Resolved conflict in view/it/hstrings.php
This commit is contained in:
commit
45a854762b
2
.gitignore
vendored
2
.gitignore
vendored
@ -27,6 +27,8 @@ custom/
|
||||
apps/
|
||||
# default startpage
|
||||
home.html
|
||||
# page header plugin
|
||||
pageheader.html
|
||||
# Ignore site TOS
|
||||
doc/SiteTOS.md
|
||||
# themes except for redbasic
|
||||
|
164
.homeinstall/README.md
Normal file
164
.homeinstall/README.md
Normal file
@ -0,0 +1,164 @@
|
||||
# Hubzilla at Home next to your Router
|
||||
|
||||
Run hubzilla-setup.sh for an unattended installation of hubzilla.
|
||||
|
||||
The script is known to work with Debian 8.3 stable (Jessie)
|
||||
|
||||
+ Home-PC (Debian-8.3.0-amd64)
|
||||
+ DigitalOcean droplet (Debian 8.3 x64 / 512 MB Memory / 20 GB Disk / NYC3)
|
||||
|
||||
# Step-by-Step Overwiew
|
||||
|
||||
## Preconditions
|
||||
|
||||
Hardware
|
||||
|
||||
+ Internet connection and router at home
|
||||
+ Mini-pc connected to your router
|
||||
+ USB drive for backups
|
||||
|
||||
Software
|
||||
|
||||
+ Fresh installation of Debian on your mini-pc
|
||||
+ Router with open ports 80 and 443 for your Debian
|
||||
|
||||
## The basic steps (quick overview)
|
||||
|
||||
+ Register your own domain (for example at selfHOST) or a free subdomain (for example at freeDNS)
|
||||
+ Log on to your new debian (server)
|
||||
- apt-get install git
|
||||
- mkdir -p /var/www/html
|
||||
- cd /var/www/html
|
||||
- git clone https://github.com/redmatrix/hubzilla.git .
|
||||
- cp .homeinstall/hubzilla-config.txt.template .homeinstall/hubzilla-config.txt
|
||||
- nano .homeinstall/hubzilla-config.txt
|
||||
- Enter your values there: db pass, domain, values for dyn DNS
|
||||
- hubzilla-setup.sh as root
|
||||
- ... wait, wait, wait until the script is finised
|
||||
- reboot
|
||||
+ Open your domain with a browser and step throught the initial configuration of hubzilla.
|
||||
|
||||
# Step-by-Step in Detail
|
||||
|
||||
## Preparations Hardware
|
||||
|
||||
### Mini-PC
|
||||
|
||||
### Recommended: USB Drive for Backups
|
||||
|
||||
The installation will create a daily backup.
|
||||
|
||||
If the backup process does not find an external device than the backup goes to
|
||||
the internal disk.
|
||||
|
||||
The USB drive must be compatible with an encrpyted filesystem LUKS + ext4.
|
||||
|
||||
## Preparations Software
|
||||
|
||||
### Install Debian Linux on the Mini-PC
|
||||
|
||||
Download the stable Debian at https://www.debian.org/
|
||||
|
||||
Create bootable USB drive with Debian on it. You could use the programm
|
||||
unetbootin, https://en.wikipedia.org/wiki/UNetbootin
|
||||
|
||||
Switch of your mini pc, plug in your USB drive and start the mini pc from the
|
||||
stick. Install Debian. Follow the instructions of the installation.
|
||||
|
||||
### Configure your Router
|
||||
|
||||
Open the ports 80 and 443 on your router for your Debian
|
||||
|
||||
## Preparations Dynamic IP Address
|
||||
|
||||
Your Hubzilla must be reachable by a domain that you can type in your browser
|
||||
|
||||
cooldomain.org
|
||||
|
||||
You can use subdomains as well
|
||||
|
||||
my.cooldomain.org
|
||||
|
||||
There are two way to get a domain
|
||||
|
||||
- buy a domain (recommended) or
|
||||
- register a free subdomain
|
||||
|
||||
### Method 1: Get yourself an own Domain (recommended)
|
||||
|
||||
...for example at selfHOST.de
|
||||
|
||||
### Method 2 Register a (free) Subdomain
|
||||
|
||||
Register a free subdomain for example at
|
||||
|
||||
- freeDNS
|
||||
- selfHOST
|
||||
|
||||
WATCH THIS: A free subdomain is not the prefered way to get a domain name. Why?
|
||||
|
||||
Let's encrpyt issues a limited number of certificates each
|
||||
day. Possibly other users of this domain will try to issue a certificate
|
||||
at the same day as you do. So make sure you choose a domain with as less subdomains as
|
||||
possible.
|
||||
|
||||
## Install Hubzilla on your Debian
|
||||
|
||||
Login to your debian
|
||||
(Provided your username is "you" and the name of the mini pc is "debian". You
|
||||
could take the IP address instead of "debian")
|
||||
|
||||
ssh -X you@debian
|
||||
|
||||
Change to root user
|
||||
|
||||
su -l
|
||||
|
||||
Install git
|
||||
|
||||
apt-get install git
|
||||
|
||||
Make the directory for apache and change diretory to it
|
||||
|
||||
mkdir /var/www
|
||||
cd /var/www/
|
||||
|
||||
Clone hubzilla from git ("git pull" will update it later)
|
||||
|
||||
git clone https://github.com/redmatrix/hubzilla html
|
||||
|
||||
Change to the install script
|
||||
|
||||
cd html/.homeinstall/
|
||||
|
||||
Copy the template file
|
||||
|
||||
cp hubzilla-config.txt.template hubzilla-config.txt
|
||||
|
||||
Change the file "hubzilla-config.txt". Read the instructions there and enter your values.
|
||||
|
||||
nano hubzilla-config.txt
|
||||
|
||||
Run the script
|
||||
|
||||
./hubzilla-setup.sh
|
||||
|
||||
Wait... The script should not finish with an error message.
|
||||
|
||||
In a webbrowser open your domain.
|
||||
Expected: A test page of hubzilla is shown. All checks there shoulg be
|
||||
successfull. Go on...
|
||||
Expected: A page for the Hubzilla server configuration shows up.
|
||||
|
||||
Leave db server name "127.0.0.1" and port "0" untouched.
|
||||
|
||||
Enter
|
||||
|
||||
- DB user name = hubzilla
|
||||
- DB pass word = This is the password you entered in "hubzilla-config.txt"
|
||||
- DB name = hubzilla
|
||||
|
||||
Leave db type "MySQL" untouched.
|
||||
|
||||
Follow the instructions in the next pages.
|
||||
|
177
.homeinstall/hubzilla-config.txt.template
Normal file
177
.homeinstall/hubzilla-config.txt.template
Normal file
@ -0,0 +1,177 @@
|
||||
###############################################
|
||||
### MANDATORY - database password #############
|
||||
#
|
||||
# Please give your database password
|
||||
# Example: db_pass=pass_word_with_no_blanks_in_it
|
||||
# Example: db_pass="this password has blanks in it"
|
||||
db_pass=
|
||||
|
||||
###############################################
|
||||
### MANDATORY - let's encrypt #################
|
||||
#
|
||||
# Hubilla requires encrypted communication via secure HTTP (HTTPS).
|
||||
# This script automates installation of an SSL certificate from
|
||||
# Let's Encrypt (https://letsencrypt.org)
|
||||
#
|
||||
# Please give the domain name of your hub
|
||||
#
|
||||
# Example: my.cooldomain.org
|
||||
# Example: cooldomain.org
|
||||
#
|
||||
# Email is optional
|
||||
#
|
||||
#
|
||||
le_domain=
|
||||
le_email=
|
||||
|
||||
###############################################
|
||||
### OPTIONAL - selfHOST - dynamic IP address ##
|
||||
#
|
||||
# 1. Register a domain at selfhost.de
|
||||
# - choose offer "DOMAIN dynamisch" 1,50€/mon at 08.01.2016
|
||||
# 2. Get your configuration for dynamic IP update
|
||||
# - Log in at selfhost.de
|
||||
# - go to "DynDNS Accounte"
|
||||
# - klick "Details" of your (freshly) registered domain
|
||||
# - You will find the configuration there
|
||||
# - Benutzername (user name) > use this for "selfhost_user="
|
||||
# - Passwort (pass word) > use this for "selfhost_pass="
|
||||
#
|
||||
#
|
||||
selfhost_user=
|
||||
selfhost_pass=
|
||||
|
||||
###############################################
|
||||
### OPTIONAL - FreeDNS - dynamic IP address ###
|
||||
#
|
||||
# Please give the alpha-numeric-key of freedns
|
||||
#
|
||||
# Get a free subdomain from freedns and use it for your dynamic ip address
|
||||
# Documentation under http://www.techjawab.com/2013/06/setup-dynamic-dns-dyndns-for-free-on.html
|
||||
#
|
||||
# - Register for a Free domain at http://freedns.afraid.org/signup/
|
||||
# - WATCH THIS: Make sure you choose a domain with as less subdomains as
|
||||
# possible. Why? Let's encrpyt issues a limited count of certificates each
|
||||
# day. Possible other users of this domain will try to issue a certificate
|
||||
# at the same day.
|
||||
# - Logon to FreeDNS (where you just registered)
|
||||
# - Goto http://freedns.afraid.org/dynamic/
|
||||
# - Right click on "Direct Link" and copy the URL and paste it somewhere.
|
||||
# - You should notice a large and unique alpha-numeric key in the URL
|
||||
#
|
||||
# http://freedns.afraid.org/dynamic/update.php?alpha-numeric-key
|
||||
#
|
||||
# Provided your url from freedns is
|
||||
#
|
||||
# http://freedns.afraid.org/dynamic/update.php?U1Z6aGt2R0NzMFNPNWRjbWxxZGpsd093OjE1Mzg5NDE5
|
||||
#
|
||||
# Then you have to provide
|
||||
#
|
||||
# freedns_key=U1Z6aGt2R0NzMFNPNWRjbWxxZGpsd093OjE1Mzg5NDE5
|
||||
#
|
||||
#
|
||||
#freedns_key=
|
||||
|
||||
|
||||
###############################################
|
||||
### OPTIONAL - Backup to external device ######
|
||||
#
|
||||
# The script can use an external device for the daily backup.
|
||||
# The file system of the device (USB stick for example) must be compatible
|
||||
# with encrypted LUKS + ext4
|
||||
#
|
||||
# You should test to mount the device befor you run the script
|
||||
# (hubzilla-setup.sh).
|
||||
# How to find your (pluged-in) devices?
|
||||
#
|
||||
# fdisk -l
|
||||
#
|
||||
# Provided your device was listed as is /dev/sdb1. You could check with:
|
||||
#
|
||||
# blkid | grep /dev/sdb1
|
||||
#
|
||||
# Try to decrypt
|
||||
# (You might install cryptsetup befor using apt-get install.
|
||||
#
|
||||
# apt-get install cryptsetup
|
||||
# cryptsetup luksOpen /dev/sdb1 cryptobackup
|
||||
#
|
||||
# Try to mount
|
||||
# You might create the directory /media/hubzilla_backup it it does not exist
|
||||
# using mkdir.
|
||||
#
|
||||
# mkdir /media/hubzilla_backup
|
||||
# mount /dev/mapper/cryptobackup /media/hubzilla_backup
|
||||
#
|
||||
# Unmounting device goes like this
|
||||
#
|
||||
# umount /media/hubzilla_backup
|
||||
# cryptsetup luksClose cryptobackup
|
||||
#
|
||||
# To check if still mounted
|
||||
#
|
||||
# lsof /media/hubzilla_backup
|
||||
#
|
||||
# If you leave the following parameters
|
||||
# - "backup_device_name" and
|
||||
# - "backup_device_pass"
|
||||
# empty the script will create daily backups on the internal disk (which could
|
||||
# save you as well).
|
||||
#
|
||||
# Example: backup_device_name=/dev/sdc1
|
||||
#
|
||||
backup_device_name=
|
||||
backup_device_pass=
|
||||
|
||||
|
||||
###############################################
|
||||
### OPTIONAL - Owncloud - deprecated ##########
|
||||
#
|
||||
# To install owncloud: owncloud=y
|
||||
# Leave empty if you don't want to install owncloud
|
||||
#
|
||||
#owncloud=
|
||||
|
||||
|
||||
|
||||
###############################################
|
||||
### OPTIONAL - do not mess with things below ##
|
||||
# (...if you are not certain)
|
||||
#
|
||||
# Usually you are done here
|
||||
# Everything below is OPTIONAL
|
||||
#
|
||||
###############################################
|
||||
#
|
||||
# Database for hubzilla
|
||||
hubzilla_db_name=hubzilla
|
||||
hubzilla_db_user=hubzilla
|
||||
hubzilla_db_pass=$db_pass
|
||||
#
|
||||
#
|
||||
# Password for package mysql-server
|
||||
# Example: mysqlpass=aberhallo
|
||||
# Example: mysqlpass="aber hallo has blanks in it"
|
||||
#
|
||||
mysqlpass=$db_pass
|
||||
|
||||
# Password for package phpmyadmin
|
||||
# Example: phpmyadminpass=aberhallo
|
||||
# Example: phpmyadminpass="aber hallo has blanks in it"
|
||||
phpmyadminpass=$db_pass
|
||||
|
||||
# TODO Prepare hubzilla for programmers
|
||||
# - install eclipse and plugins
|
||||
# - install xdebug to debug the php with eclipse
|
||||
# - weaken permissions on /var/www/html
|
||||
# - manual steps after this script
|
||||
# * in eclipse: install plugins for php git hub
|
||||
# * in eclipse: configure firefox (chrome,...) as browser to run with the php debuger
|
||||
# * in eclipse: switch php debugger from zend to xdebug
|
||||
# * in eclipse: add local hubzilla github repository
|
||||
#
|
||||
# Which user will use eclipse?
|
||||
# Leave this empty if you do not want to prepare hubzilla for debugging
|
||||
#
|
||||
#developer_name=
|
||||
|
949
.homeinstall/hubzilla-setup.sh
Executable file
949
.homeinstall/hubzilla-setup.sh
Executable file
@ -0,0 +1,949 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# How to use
|
||||
# ----------
|
||||
#
|
||||
# This file automates the installation of hubzilla under Debian Linux
|
||||
#
|
||||
# 1) Copy the file "hubzilla-config.txt.template" to "hubzilla-config.txt"
|
||||
# Follow the instuctions there
|
||||
#
|
||||
# 2) Switch to user "root" by typing "su -"
|
||||
#
|
||||
# 3) Run with "./hubzilla-setup.sh"
|
||||
# If this fails check if you can execute the script.
|
||||
# - To make it executable type "chmod +x hubzilla-setup.sh"
|
||||
# - or run "bash hubzilla-setup.sh"
|
||||
#
|
||||
#
|
||||
# What does this script do basically?
|
||||
# -----------------------------------
|
||||
#
|
||||
# This file automates the installation of hubzilla under Debian Linux
|
||||
# - install
|
||||
# * apache webserer,
|
||||
# * php,
|
||||
# * mysql - the database for hubzilla,
|
||||
# * phpmyadmin,
|
||||
# * git to download and update hubzilla itself
|
||||
# - download hubzilla core and addons
|
||||
# - configure cron
|
||||
# * "poller.php" for regular background prozesses of hubzilla
|
||||
# * to_do "apt-get update" and "apt-get dist-upgrade" to keep linux
|
||||
# up-to-date
|
||||
# * to_do backup hubzillas database and files (rsnapshot)
|
||||
# - configure dynamic ip with cron
|
||||
# - to_do letsencrypt
|
||||
# - to_do redirection to https
|
||||
#
|
||||
#
|
||||
# Discussion
|
||||
# ----------
|
||||
#
|
||||
# Security - password is the same for mysql-server, phpmyadmin and hubzilla db
|
||||
# - The script runs into installation errors for phpmyadmin if it uses
|
||||
# different passwords. For the sake of simplicity one singel password.
|
||||
#
|
||||
# Security - suhosin for PHP
|
||||
# - The script does not install suhosin.
|
||||
# - Is the security package suhosin usefull or not usefull?
|
||||
#
|
||||
# Hubzilla - email verification
|
||||
# - The script switches off email verification off in all htconfig.tpl.
|
||||
# Example: /var/www/html/view/en/htconfig.tpl
|
||||
# - Is this a silly idea or not?
|
||||
#
|
||||
#
|
||||
# Remove Hubzilla (for a fresh start using the script)
|
||||
# ----------------------------------------------------
|
||||
#
|
||||
# You could use /var/www/hubzilla-remove.sh
|
||||
# that is created by hubzilla-setup.sh.
|
||||
#
|
||||
# The script will remove (almost everything) what was installed by the script.
|
||||
# After the removal you could run the script again to have a fresh install
|
||||
# of all applications including hubzilla and its database.
|
||||
#
|
||||
# How to restore from backup
|
||||
# --------------------------
|
||||
#
|
||||
# Daily backup
|
||||
# - - - - - -
|
||||
#
|
||||
# The installation
|
||||
# - writes a script /var/www/hubzilla-daily.sh
|
||||
# - creates a daily cron that runs the hubzilla-daily.sh
|
||||
#
|
||||
# hubzilla-daily.sh makes a (daily) backup of all relevant files
|
||||
# - /var/lib/mysql/ > hubzilla database
|
||||
# - /var/www/html/ > hubzilla from github
|
||||
# - /var/www/letsencrypt/ > certificates
|
||||
#
|
||||
# hubzilla-daily.sh writes the backup
|
||||
# - either to an external disk compatible to LUKS+ext4 (see hubzilla-config.txt)
|
||||
# - or to /var/cache/rsnapshot in case the external disk is not plugged in
|
||||
#
|
||||
# Restore backup
|
||||
# - - - - - - -
|
||||
#
|
||||
# This was not tested yet.
|
||||
# Bacically you can copy the files from the backup to the server.
|
||||
#
|
||||
# Credits
|
||||
# -------
|
||||
#
|
||||
# The script is based on Thomas Willinghams script "debian-setup.sh"
|
||||
# which he used to install the red#matrix.
|
||||
#
|
||||
# The script uses another script from https://github.com/lukas2511/letsencrypt.sh
|
||||
#
|
||||
# The documentation for bash is here
|
||||
# https://www.gnu.org/software/bash/manual/bash.html
|
||||
#
|
||||
function check_sanity {
|
||||
# Do some sanity checking.
|
||||
print_info "Sanity check..."
|
||||
if [ $(/usr/bin/id -u) != "0" ]
|
||||
then
|
||||
die 'Must be run by root user'
|
||||
fi
|
||||
|
||||
if [ -f /etc/lsb-release ]
|
||||
then
|
||||
die "Distribution is not supported"
|
||||
fi
|
||||
if [ ! -f /etc/debian_version ]
|
||||
then
|
||||
die "Ubuntu is not supported"
|
||||
fi
|
||||
}
|
||||
|
||||
function check_config {
|
||||
print_info "config check..."
|
||||
# Check for required parameters
|
||||
if [ -z "$db_pass" ]
|
||||
then
|
||||
die "db_pass not set in $configfile"
|
||||
fi
|
||||
if [ -z "$le_domain" ]
|
||||
then
|
||||
die "le_domain not set in $configfile"
|
||||
fi
|
||||
# backup is important and should be checked
|
||||
if [ -n "$backup_device_name" ]
|
||||
then
|
||||
device_mounted=0
|
||||
if fdisk -l | grep -i "$backup_device_name.*linux"
|
||||
then
|
||||
print_info "ok - filesystem of external device is linux"
|
||||
if [ -n "$backup_device_pass" ]
|
||||
then
|
||||
echo "$backup_device_pass" | cryptsetup luksOpen $backup_device_name cryptobackup
|
||||
if [ ! -d /media/hubzilla_backup ]
|
||||
then
|
||||
mkdir /media/hubzilla_backup
|
||||
fi
|
||||
if mount /dev/mapper/cryptobackup /media/hubzilla_backup
|
||||
then
|
||||
device_mounted=1
|
||||
print_info "ok - could encrypt and mount external backup device"
|
||||
umount /media/hubzilla_backup
|
||||
else
|
||||
print_warn "backup to external device will fail because encryption failed"
|
||||
fi
|
||||
cryptsetup luksClose cryptobackup
|
||||
else
|
||||
if mount $backup_device_name /media/hubzilla_backup
|
||||
then
|
||||
device_mounted=1
|
||||
print_info "ok - could mount external backup device"
|
||||
umount /media/hubzilla_backup
|
||||
else
|
||||
print_warn "backup to external device will fail because mount failed"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
print_warn "backup to external device will fail because filesystem is either not linux or 'backup_device_name' is not correct in $configfile"
|
||||
fi
|
||||
if [ $device_mounted == 0 ]
|
||||
then
|
||||
die "backup device not ready"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function die {
|
||||
echo "ERROR: $1" > /dev/null 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
function update_upgrade {
|
||||
print_info "updated and upgrade..."
|
||||
# Run through the apt-get update/upgrade first. This should be done before
|
||||
# we try to install any package
|
||||
apt-get -q -y update && apt-get -q -y dist-upgrade
|
||||
print_info "updated and upgraded linux"
|
||||
}
|
||||
|
||||
function check_install {
|
||||
if [ -z "`which "$1" 2>/dev/null`" ]
|
||||
then
|
||||
# export DEBIAN_FRONTEND=noninteractive ... answers from the package
|
||||
# configuration database
|
||||
# - q ... without progress information
|
||||
# - y ... answer interactive questions with "yes"
|
||||
# DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -q -y install $2
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -q -y install $2
|
||||
print_info "installed $2 installed for $1"
|
||||
else
|
||||
print_warn "$2 already installed"
|
||||
fi
|
||||
}
|
||||
|
||||
function nocheck_install {
|
||||
# export DEBIAN_FRONTEND=noninteractive ... answers from the package configuration database
|
||||
# - q ... without progress information
|
||||
# - y ... answer interactive questions with "yes"
|
||||
# DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends -q -y install $2
|
||||
# DEBIAN_FRONTEND=noninteractive apt-get --install-suggests -q -y install $1
|
||||
DEBIAN_FRONTEND=noninteractive apt-get -q -y install $1
|
||||
print_info "installed $1"
|
||||
}
|
||||
|
||||
|
||||
function print_info {
|
||||
echo -n -e '\e[1;34m'
|
||||
echo -n $1
|
||||
echo -e '\e[0m'
|
||||
}
|
||||
|
||||
function print_warn {
|
||||
echo -n -e '\e[1;31m'
|
||||
echo -n $1
|
||||
echo -e '\e[0m'
|
||||
}
|
||||
|
||||
function stop_hubzilla {
|
||||
if [ -d /etc/apache2 ]
|
||||
then
|
||||
print_info "stopping apache webserver..."
|
||||
service apache2 stop
|
||||
fi
|
||||
if [ -f /etc/init.d/mysql ]
|
||||
then
|
||||
print_info "stopping mysql db..."
|
||||
/etc/init.d/mysql stop
|
||||
fi
|
||||
}
|
||||
|
||||
function install_apache {
|
||||
print_info "installing apache..."
|
||||
nocheck_install "apache2 apache2-utils"
|
||||
}
|
||||
|
||||
function install_curl {
|
||||
print_info "installing curl..."
|
||||
nocheck_install "curl"
|
||||
}
|
||||
|
||||
function install_sendmail {
|
||||
print_info "installing sendmail..."
|
||||
nocheck_install "sendmail sendmail-bin"
|
||||
}
|
||||
|
||||
function install_php {
|
||||
# openssl and mbstring are included in libapache2-mod-php5
|
||||
# to_to: php5-suhosin
|
||||
print_info "installing php..."
|
||||
nocheck_install "libapache2-mod-php5 php5 php-pear php5-xcache php5-curl php5-mcrypt php5-gd"
|
||||
php5enmod mcrypt
|
||||
}
|
||||
|
||||
function install_mysql {
|
||||
# http://www.microhowto.info/howto/perform_an_unattended_installation_of_a_debian_package.html
|
||||
#
|
||||
# To determine the required package name, key and type you can perform
|
||||
# a trial installation then search the configuration database.
|
||||
#
|
||||
# debconf-get-selections | grep mysql-server
|
||||
#
|
||||
# The command debconf-get-selections is provided by the package
|
||||
# debconf-utils, which you may need to install.
|
||||
#
|
||||
# apt-get install debconf-utils
|
||||
#
|
||||
# If you want to supply an answer to a configuration question but do not
|
||||
# want to be prompted for it then this can be arranged by preseeding the
|
||||
# DebConf database with the required information.
|
||||
#
|
||||
# echo mysql-server-5.5 mysql-server/root_password password xyzzy | debconf-set-selections
|
||||
# echo mysql-server-5.5 mysql-server/root_password_again password xyzzy | debconf-set-selections
|
||||
#
|
||||
print_info "installing mysql..."
|
||||
if [ -z "$mysqlpass" ]
|
||||
then
|
||||
die "mysqlpass not set in $configfile"
|
||||
fi
|
||||
echo mysql-server-5.5 mysql-server/root_password password $mysqlpass | debconf-set-selections
|
||||
echo mysql-server-5.5 mysql-server/root_password_again password $mysqlpass | debconf-set-selections
|
||||
nocheck_install "php5-mysql mysql-server mysql-client"
|
||||
php5enmod mcrypt
|
||||
}
|
||||
|
||||
function install_phpmyadmin {
|
||||
print_info "installing phpmyadmin..."
|
||||
if [ -z "$phpmyadminpass" ]
|
||||
then
|
||||
die "phpmyadminpass not set in $configfile"
|
||||
fi
|
||||
echo phpmyadmin phpmyadmin/setup-password password $phpmyadminpass | debconf-set-selections
|
||||
echo phpmyadmin phpmyadmin/mysql/app-pass password $phpmyadminpass | debconf-set-selections
|
||||
echo phpmyadmin phpmyadmin/app-password-confirm password $phpmyadminpass | debconf-set-selections
|
||||
echo phpmyadmin phpmyadmin/mysql/admin-pass password $phpmyadminpass | debconf-set-selections
|
||||
echo phpmyadmin phpmyadmin/password-confirm password $phpmyadminpass | debconf-set-selections
|
||||
echo phpmyadmin phpmyadmin/reconfigure-webserver multiselect apache2 | debconf-set-selections
|
||||
nocheck_install "phpmyadmin"
|
||||
|
||||
# It seems to be not neccessary to check rewrite.load because it comes
|
||||
# with the installation. To be sure you could check this manually by:
|
||||
#
|
||||
# nano /etc/apache2/mods-available/rewrite.load
|
||||
#
|
||||
# You should find the content:
|
||||
#
|
||||
# LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
|
||||
|
||||
a2enmod rewrite
|
||||
if [ ! -f /etc/apache2/apache2.conf ]
|
||||
then
|
||||
die "could not find file /etc/apache2/apache2.conf"
|
||||
fi
|
||||
sed -i \
|
||||
"s/AllowOverride None/AllowOverride all/" \
|
||||
/etc/apache2/apache2.conf
|
||||
if [ -z "`grep 'Include /etc/phpmyadmin/apache.conf' /etc/apache2/apache2.conf`" ]
|
||||
then
|
||||
echo "Include /etc/phpmyadmin/apache.conf" >> /etc/apache2/apache2.conf
|
||||
fi
|
||||
service apache2 restart
|
||||
}
|
||||
|
||||
function create_hubzilla_db {
|
||||
print_info "creating hubzilla database..."
|
||||
if [ -z "$hubzilla_db_name" ]
|
||||
then
|
||||
die "hubzilla_db_name not set in $configfile"
|
||||
fi
|
||||
if [ -z "$hubzilla_db_user" ]
|
||||
then
|
||||
die "hubzilla_db_user not set in $configfile"
|
||||
fi
|
||||
if [ -z "$hubzilla_db_pass" ]
|
||||
then
|
||||
die "hubzilla_db_pass not set in $configfile"
|
||||
fi
|
||||
Q1="CREATE DATABASE IF NOT EXISTS $hubzilla_db_name;"
|
||||
Q2="GRANT USAGE ON *.* TO $hubzilla_db_user@localhost IDENTIFIED BY '$hubzilla_db_pass';"
|
||||
Q3="GRANT ALL PRIVILEGES ON $hubzilla_db_name.* to $hubzilla_db_user@localhost identified by '$hubzilla_db_pass';"
|
||||
Q4="FLUSH PRIVILEGES;"
|
||||
SQL="${Q1}${Q2}${Q3}${Q4}"
|
||||
mysql -uroot -p$phpmyadminpass -e "$SQL"
|
||||
}
|
||||
|
||||
function run_freedns {
|
||||
print_info "run freedns (dynamic IP)..."
|
||||
if [ -z "$freedns_key" ]
|
||||
then
|
||||
print_info "freedns was not started because 'freedns_key' is empty in $configfile"
|
||||
else
|
||||
if [ -n "$selfhost_user" ]
|
||||
then
|
||||
die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)"
|
||||
fi
|
||||
wget --no-check-certificate -O - https://freedns.afraid.org/dynamic/update.php?$freedns_key
|
||||
fi
|
||||
}
|
||||
|
||||
function install_run_selfhost {
|
||||
print_info "install and start selfhost (dynamic IP)..."
|
||||
if [ -z "$selfhost_user" ]
|
||||
then
|
||||
print_info "selfHOST was not started because 'selfhost_user' is empty in $configfile"
|
||||
else
|
||||
if [ -n "$freedns_key" ]
|
||||
then
|
||||
die "You can not use freeDNS AND selfHOST for dynamic IP updates ('freedns_key' AND 'selfhost_user' set in $configfile)"
|
||||
fi
|
||||
if [ -z "$selfhost_pass" ]
|
||||
then
|
||||
die "selfHOST was not started because 'selfhost_pass' is empty in $configfile"
|
||||
fi
|
||||
if [ ! -d $selfhostdir ]
|
||||
then
|
||||
mkdir $selfhostdir
|
||||
fi
|
||||
# the old way
|
||||
# https://carol.selfhost.de/update?username=123456&password=supersafe
|
||||
#
|
||||
# the prefered way
|
||||
wget --output-document=$selfhostdir/$selfhostscript http://jonaspasche.de/selfhost-updater
|
||||
echo "router" > $selfhostdir/device
|
||||
echo "$selfhost_user" > $selfhostdir/user
|
||||
echo "$selfhost_pass" > $selfhostdir/pass
|
||||
bash $selfhostdir/$selfhostscript update
|
||||
fi
|
||||
}
|
||||
|
||||
function ping_domain {
|
||||
print_info "ping domain $domain..."
|
||||
# Is the domain resolved? Try to ping 6 times à 10 seconds
|
||||
COUNTER=0
|
||||
for i in {1..6}
|
||||
do
|
||||
print_info "loop $i for ping -c 1 $domain ..."
|
||||
if ping -c 4 -W 1 $le_domain
|
||||
then
|
||||
print_info "$le_domain resolved"
|
||||
break
|
||||
else
|
||||
if [ $i -gt 5 ]
|
||||
then
|
||||
die "Failed to: ping -c 1 $domain not resolved"
|
||||
fi
|
||||
fi
|
||||
sleep 10
|
||||
done
|
||||
sleep 5
|
||||
}
|
||||
|
||||
function configure_cron_freedns {
|
||||
print_info "configure cron for freedns..."
|
||||
if [ -z "$freedns_key" ]
|
||||
then
|
||||
print_info "freedns is not configured because freedns_key is empty in $configfile"
|
||||
else
|
||||
# Use cron for dynamich ip update
|
||||
# - at reboot
|
||||
# - every 30 minutes
|
||||
if [ -z "`grep 'freedns.afraid.org' /etc/crontab`" ]
|
||||
then
|
||||
echo "@reboot root https://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab
|
||||
echo "*/30 * * * * root wget --no-check-certificate -O - https://freedns.afraid.org/dynamic/update.php?$freedns_key > /dev/null 2>&1" >> /etc/crontab
|
||||
else
|
||||
print_info "cron for freedns was configured already"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function configure_cron_selfhost {
|
||||
print_info "configure cron for selfhost..."
|
||||
if [ -z "$selfhost_user" ]
|
||||
then
|
||||
print_info "freedns is not configured because freedns_key is empty in $configfile"
|
||||
else
|
||||
# Use cron for dynamich ip update
|
||||
# - at reboot
|
||||
# - every 30 minutes
|
||||
if [ -z "`grep 'selfhost-updater.sh' /etc/crontab`" ]
|
||||
then
|
||||
echo "@reboot root bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab
|
||||
echo "*/5 * * * * root /bin/bash /etc/selfhost/selfhost-updater.sh update > /dev/null 2>&1" >> /etc/crontab
|
||||
else
|
||||
print_info "cron for selfhost was configured already"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function install_git {
|
||||
print_info "installing git..."
|
||||
nocheck_install "git"
|
||||
}
|
||||
|
||||
function install_letsencrypt {
|
||||
print_info "installing let's encrypt ..."
|
||||
# check if user gave domain
|
||||
if [ -z "$le_domain" ]
|
||||
then
|
||||
die "Failed to install let's encrypt: 'le_domain' is empty in $configfile"
|
||||
fi
|
||||
# configure apache
|
||||
apache_le_conf=/etc/apache2/sites-available/le-default.conf
|
||||
if [ -f $apache_le_conf ]
|
||||
then
|
||||
print_info "$apache_le_conf exist already"
|
||||
else
|
||||
cat > $apache_le_conf <<END
|
||||
# letsencrypt default Apache configuration
|
||||
Alias /.well-known/acme-challenge /var/www/letsencrypt
|
||||
|
||||
<Directory /var/www/letsencrypt>
|
||||
Options FollowSymLinks
|
||||
Allow from all
|
||||
</Directory>
|
||||
END
|
||||
a2ensite le-default.conf
|
||||
service apache2 restart
|
||||
fi
|
||||
# download the shell script
|
||||
if [ -d $le_dir ]
|
||||
then
|
||||
print_info "letsenrypt exists already (nothing downloaded > no certificate created and registered)"
|
||||
return 0
|
||||
fi
|
||||
git clone https://github.com/lukas2511/letsencrypt.sh $le_dir
|
||||
cd $le_dir
|
||||
# create config file for letsencrypt.sh
|
||||
echo "WELLKNOWN=$le_dir" > $le_dir/config.sh
|
||||
if [ -n "$le_email" ]
|
||||
then
|
||||
echo "CONTACT_EMAIL=$le_email" >> $le_dir/config.sh
|
||||
fi
|
||||
# create domain file for letsencrypt.sh
|
||||
# WATCH THIS:
|
||||
# - It did not work wit "sub.domain.org www.sub.domain.org".
|
||||
# - So just use "sub.domain.org" only!
|
||||
echo "$le_domain" > $le_dir/domains.txt
|
||||
# test apache config for letsencrpyt
|
||||
url_http=http://$le_domain/.well-known/acme-challenge/domains.txt
|
||||
wget_output=$(wget -nv --spider --max-redirect 0 $url_http)
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
die "Failed to load $url_http"
|
||||
fi
|
||||
# run letsencrypt.sh
|
||||
#
|
||||
./letsencrypt.sh --cron
|
||||
}
|
||||
|
||||
function configure_apache_for_https {
|
||||
print_info "configuring apache to use httpS ..."
|
||||
# letsencrypt.sh
|
||||
#
|
||||
# "${BASEDIR}/certs/${domain}/privkey.pem"
|
||||
# "${BASEDIR}/certs/${domain}/cert.pem"
|
||||
# "${BASEDIR}/certs/${domain}/fullchain.pem"
|
||||
#
|
||||
SSLCertificateFile=${le_dir}/certs/${le_domain}/cert.pem
|
||||
SSLCertificateKeyFile=${le_dir}/certs/${le_domain}/privkey.pem
|
||||
SSLCertificateChainFile=${le_dir}/certs/${le_domain}/fullchain.pem
|
||||
if [ ! -f $SSLCertificateFile ]
|
||||
then
|
||||
print_warn "Failed to configure apache for httpS: Missing certificate file $SSLCertificateFile"
|
||||
return 0
|
||||
fi
|
||||
# make sure that the ssl mode is enabled
|
||||
print_info "...configuring apache to use httpS - a2enmod ssl ..."
|
||||
a2enmod ssl
|
||||
# modify apach' ssl conf file
|
||||
if grep -i "ServerName" $sslconf
|
||||
then
|
||||
print_info "seems that apache was already configered to use httpS with $sslconf"
|
||||
else
|
||||
sed -i "s/ServerAdmin.*$/ServerAdmin webmaster@localhost\\n ServerName ${le_domain}/" $sslconf
|
||||
fi
|
||||
sed -i s#/etc/ssl/certs/ssl-cert-snakeoil.pem#$SSLCertificateFile# $sslconf
|
||||
sed -i s#/etc/ssl/private/ssl-cert-snakeoil.key#$SSLCertificateKeyFile# $sslconf
|
||||
sed -i s#/etc/apache2/ssl.crt/server-ca.crt#$SSLCertificateChainFile# $sslconf
|
||||
sed -i s/#SSLCertificateChainFile/SSLCertificateChainFile/ $sslconf
|
||||
# apply changes
|
||||
a2ensite default-ssl.conf
|
||||
service apache2 restart
|
||||
}
|
||||
|
||||
function check_https {
|
||||
print_info "checking httpS > testing ..."
|
||||
url_https=https://$le_domain
|
||||
wget_output=$(wget -nv --spider --max-redirect 0 $url_https)
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
print_warn "check not ok"
|
||||
else
|
||||
print_info "check ok"
|
||||
fi
|
||||
}
|
||||
|
||||
function install_hubzilla {
|
||||
print_info "installing hubzilla..."
|
||||
# rm -R /var/www/html/ # for "stand alone" usage
|
||||
cd /var/www/
|
||||
# git clone https://github.com/redmatrix/hubzilla html # for "stand alone" usage
|
||||
cd html/
|
||||
git clone https://github.com/redmatrix/hubzilla-addons addon
|
||||
mkdir -p "store/[data]/smarty3"
|
||||
chmod -R 777 store
|
||||
touch .htconfig.php
|
||||
chmod ou+w .htconfig.php
|
||||
install_hubzilla_plugins
|
||||
cd /var/www/
|
||||
chown -R www-data:www-data html
|
||||
chown root:www-data /var/www/html/
|
||||
chown root:www-data /var/www/html/.htaccess
|
||||
chmod 0644 /var/www/html/.htaccess
|
||||
# try to switch off email registration
|
||||
sed -i "s/verify_email.*1/verify_email'] = 0/" /var/www/html/view/*/ht*
|
||||
if [ -n "`grep -r 'verify_email.*1' /var/www/html/view/`" ]
|
||||
then
|
||||
print_warn "Hubzillas registration prozess might have email verification switched on."
|
||||
fi
|
||||
print_info "installed hubzilla"
|
||||
}
|
||||
|
||||
function install_hubzilla_plugins {
|
||||
print_info "installing hubzilla plugins..."
|
||||
cd /var/www/html
|
||||
plugin_install=.homeinstall/plugin_install.txt
|
||||
theme_install=.homeinstall/theme_install.txt
|
||||
# overwrite script to update the plugin and themes
|
||||
rm -f $plugins_update
|
||||
echo "cd /var/www/html" >> $plugins_update
|
||||
###################
|
||||
# write plugin file
|
||||
if [ ! -f "$plugin_install" ]
|
||||
then
|
||||
echo "# To install a plugin" >> $plugin_install
|
||||
echo "# 1. add the plugin in a new line and run" >> $plugin_install
|
||||
echo "# 2. run" >> $plugin_install
|
||||
echo "# cd /var/www/html/.homeinstall" >> $plugin_install
|
||||
echo "# ./hubzilla-setup.sh" >> $plugin_install
|
||||
echo "https://gitlab.com/zot/ownmapp.git ownMapp" >> $plugin_install
|
||||
echo "https://gitlab.com/zot/hubzilla-chess.git chess" >> $plugin_install
|
||||
fi
|
||||
# install plugins
|
||||
while read -r line; do
|
||||
[[ "$line" =~ ^#.*$ ]] && continue
|
||||
p_url=$(echo $line | awk -F' ' '{print $1}')
|
||||
p_name=$(echo $line | awk -F' ' '{print $2}')
|
||||
# basic check of format
|
||||
if [ ${#p_url} -ge 1 ] && [ ${#p_name} -ge 1 ]
|
||||
then
|
||||
# install addon
|
||||
util/add_addon_repo $line
|
||||
util/update_addon_repo $p_name # not sure if this line is neccessary
|
||||
echo "util/update_addon_repo $p_name" >> $plugins_update
|
||||
else
|
||||
print_info "skipping installation of a plugin from file $plugin_install - something wrong with format in line: $line"
|
||||
fi
|
||||
done < "$plugin_install"
|
||||
###################
|
||||
# write theme file
|
||||
if [ ! -f "$theme_install" ]
|
||||
then
|
||||
echo "# To install a theme" >> $theme_install
|
||||
echo "# 1. add the theme in a new line and run" >> $theme_install
|
||||
echo "# 2. run" >> $theme_install
|
||||
echo "# cd /var/www/html/.homeinstall" >> $theme_install
|
||||
echo "# ./hubzilla-setup.sh" >> $theme_install
|
||||
echo "https://github.com/DeadSuperHero/hubzilla-themes.git DeadSuperHeroThemes" >> $theme_install
|
||||
|
||||
fi
|
||||
# install plugins
|
||||
while read -r line; do
|
||||
[[ "$line" =~ ^#.*$ ]] && continue
|
||||
p_url=$(echo $line | awk -F' ' '{print $1}')
|
||||
p_name=$(echo $line | awk -F' ' '{print $2}')
|
||||
# basic check of format
|
||||
if [ ${#p_url} -ge 1 ] && [ ${#p_name} -ge 1 ]
|
||||
then
|
||||
# install addon
|
||||
util/add_theme_repo $line
|
||||
util/update_theme_repo $p_name # not sure if this line is neccessary
|
||||
echo "util/update_theme_repo $p_name" >> $plugins_update
|
||||
else
|
||||
print_info "skipping installation of a theme from file $theme_install - something wrong with format in line: $line"
|
||||
fi
|
||||
done < "$theme_install"
|
||||
print_info "installed hubzilla plugins and themes"
|
||||
}
|
||||
|
||||
function rewrite_to_https {
|
||||
print_info "configuring apache to redirect http to httpS ..."
|
||||
htaccessfile=/var/www/html/.htaccess
|
||||
if grep -i "https" $htaccessfile
|
||||
then
|
||||
print_info "...configuring apache to redirect http to httpS was already done in $htaccessfile"
|
||||
else
|
||||
sed -i "s#QSA]#QSA]\\n RewriteCond %{SERVER_PORT} !^443$\\n RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]#" $htaccessfile
|
||||
fi
|
||||
service apache2 restart
|
||||
}
|
||||
|
||||
|
||||
function install_owncloud {
|
||||
if [ -z "$owncloud" ]
|
||||
then
|
||||
print_info "Do not install owncloud"
|
||||
return 0
|
||||
fi
|
||||
if [ -f /etc/apt/sources.list.d/owncloud.list ]
|
||||
then
|
||||
print_info "owncloud is already installed and is left untouched"
|
||||
return 0
|
||||
fi
|
||||
print_info "installing owncloud..."
|
||||
# add the repository key to apt
|
||||
wget -nv https://download.owncloud.org/download/repositories/stable/Debian_8.0/Release.key -O Release.key
|
||||
apt-key add - < Release.key
|
||||
# add the repository and install from there
|
||||
sh -c "echo 'deb http://download.owncloud.org/download/repositories/stable/Debian_8.0/ /' >> /etc/apt/sources.list.d/owncloud.list"
|
||||
apt-get update
|
||||
nocheck_install "owncloud"
|
||||
chown -R www-data:www-data /var/www/owncloud/
|
||||
# set strong permissions
|
||||
ocpath='/var/www/owncloud'
|
||||
htuser='www-data'
|
||||
htgroup='www-data'
|
||||
rootuser='root' # On QNAP this is admin
|
||||
find ${ocpath}/ -type f -print0 | xargs -0 chmod 0640
|
||||
find ${ocpath}/ -type d -print0 | xargs -0 chmod 0750
|
||||
chown -R ${rootuser}:${htgroup} ${ocpath}/
|
||||
chown -R ${htuser}:${htgroup} ${ocpath}/apps/
|
||||
chown -R ${htuser}:${htgroup} ${ocpath}/config/
|
||||
chown -R ${htuser}:${htgroup} ${ocpath}/data/
|
||||
chown -R ${htuser}:${htgroup} ${ocpath}/themes/
|
||||
chown ${rootuser}:${htgroup} ${ocpath}/.htaccess
|
||||
chown ${rootuser}:${htgroup} ${ocpath}/data/.htaccess
|
||||
chmod 0644 ${ocpath}/.htaccess
|
||||
chmod 0644 ${ocpath}/data/.htaccess
|
||||
}
|
||||
|
||||
# This will allways overwrite both config files
|
||||
# - internal disk
|
||||
# - external disk (LUKS + ext4)
|
||||
# of rsnapshot for hubzilla
|
||||
function install_rsnapshot {
|
||||
print_info "installing rsnapshot..."
|
||||
nocheck_install "rsnapshot"
|
||||
# internal disk
|
||||
cp -f /etc/rsnapshot.conf $snapshotconfig
|
||||
sed -i "/hourly/s/retain/#retain/" $snapshotconfig
|
||||
sed -i "/monthly/s/#retain/retain/" $snapshotconfig
|
||||
sed -i "s/^cmd_cp/#cmd_cp/" $snapshotconfig
|
||||
sed -i "s/^backup/#backup/" $snapshotconfig
|
||||
if [ -z "`grep 'letsencrypt' $snapshotconfig`" ]
|
||||
then
|
||||
echo "backup /var/lib/mysql/ localhost/" >> $snapshotconfig
|
||||
echo "backup /var/www/html/ localhost/" >> $snapshotconfig
|
||||
echo "backup /var/www/letsencrypt/ localhost/" >> $snapshotconfig
|
||||
fi
|
||||
# external disk
|
||||
if [ -n "$backup_device_name" ] && [ -n "$backup_device_pass" ]
|
||||
then
|
||||
cp -f /etc/rsnapshot.conf $snapshotconfig_external_device
|
||||
sed -i "s#snapshot_root.*#snapshot_root $backup_mount_point#" $snapshotconfig_external_device
|
||||
sed -i "/hourly/s/retain/#retain/" $snapshotconfig_external_device
|
||||
sed -i "/monthly/s/#retain/retain/" $snapshotconfig_external_device
|
||||
sed -i "s/^cmd_cp/#cmd_cp/" $snapshotconfig_external_device
|
||||
sed -i "s/^backup/#backup/" $snapshotconfig_external_device
|
||||
if [ -z "`grep 'letsencrypt' $snapshotconfig_external_device`" ]
|
||||
then
|
||||
echo "backup /var/lib/mysql/ localhost/" >> $snapshotconfig_external_device
|
||||
echo "backup /var/www/html/ localhost/" >> $snapshotconfig_external_device
|
||||
echo "backup /var/www/letsencrypt/ localhost/" >> $snapshotconfig_external_device
|
||||
fi
|
||||
else
|
||||
print_info "No backup configuration (rsnapshot) for external device configured. Reason: backup_device_name and/or backup_device_pass not given in $configfile"
|
||||
fi
|
||||
}
|
||||
|
||||
function install_cryptosetup {
|
||||
print_info "installing cryptsetup..."
|
||||
nocheck_install "cryptsetup"
|
||||
}
|
||||
|
||||
function configure_cron_daily {
|
||||
print_info "configuring cron..."
|
||||
# every 10 min for poller.php
|
||||
if [ -z "`grep 'poller.php' /etc/crontab`" ]
|
||||
then
|
||||
echo "*/10 * * * * www-data cd /var/www/html; php include/poller.php >> /dev/null 2>&1" >> /etc/crontab
|
||||
fi
|
||||
# Run external script daily at 05:30
|
||||
# - stop apache and mysql-server
|
||||
# - backup hubzilla
|
||||
# - update hubzilla core and addon
|
||||
# - update and upgrade linux
|
||||
# - reboot
|
||||
echo "#!/bin/sh" > /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "echo \" \"" >> /var/www/$hubzilladaily
|
||||
echo "echo \"+++ \$(date) +++\"" >> /var/www/$hubzilladaily
|
||||
echo "echo \" \"" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - renew certificat if 30 days old...\"" >> /var/www/$hubzilladaily
|
||||
echo "bash /var/www/letsencrypt/letsencrypt.sh --cron" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "# stop hubzilla" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - stoping apaache and mysql...\"" >> /var/www/$hubzilladaily
|
||||
echo "service apache2 stop" >> /var/www/$hubzilladaily
|
||||
echo "/etc/init.d/mysql stop # to avoid inconsistancies" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "# backup" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - try to mount external device for backup...\"" >> /var/www/$hubzilladaily
|
||||
echo "backup_device_name=$backup_device_name" >> /var/www/$hubzilladaily
|
||||
echo "backup_device_pass=$backup_device_pass" >> /var/www/$hubzilladaily
|
||||
echo "backup_mount_point=$backup_mount_point" >> /var/www/$hubzilladaily
|
||||
echo "device_mounted=0" >> /var/www/$hubzilladaily
|
||||
echo "if [ -n \"$backup_device_name\" ]" >> /var/www/$hubzilladaily
|
||||
echo "then" >> /var/www/$hubzilladaily
|
||||
echo " if blkid | grep $backup_device_name" >> /var/www/$hubzilladaily
|
||||
echo " then" >> /var/www/$hubzilladaily
|
||||
if [ -n "$backup_device_pass" ]
|
||||
then
|
||||
echo " echo \"decrypting backup device...\"" >> /var/www/$hubzilladaily
|
||||
echo " echo "\"$backup_device_pass\"" | cryptsetup luksOpen $backup_device_name cryptobackup" >> /var/www/$hubzilladaily
|
||||
fi
|
||||
echo " if [ ! -d $backup_mount_point ]" >> /var/www/$hubzilladaily
|
||||
echo " then" >> /var/www/$hubzilladaily
|
||||
echo " mkdir $backup_mount_point" >> /var/www/$hubzilladaily
|
||||
echo " fi" >> /var/www/$hubzilladaily
|
||||
echo " echo \"mounting backup device...\"" >> /var/www/$hubzilladaily
|
||||
if [ -n "$backup_device_pass" ]
|
||||
then
|
||||
echo " if mount /dev/mapper/cryptobackup $backup_mount_point" >> /var/www/$hubzilladaily
|
||||
else
|
||||
echo " if mount $backup_device_name $backup_mount_point" >> /var/www/$hubzilladaily
|
||||
fi
|
||||
echo " then" >> /var/www/$hubzilladaily
|
||||
echo " device_mounted=1" >> /var/www/$hubzilladaily
|
||||
echo " echo \"device $backup_device_name is now mounted. Starting backup...\"" >> /var/www/$hubzilladaily
|
||||
echo " rsnapshot -c $snapshotconfig_external_device daily" >> /var/www/$hubzilladaily
|
||||
echo " rsnapshot -c $snapshotconfig_external_device weekly" >> /var/www/$hubzilladaily
|
||||
echo " rsnapshot -c $snapshotconfig_external_device monthly" >> /var/www/$hubzilladaily
|
||||
echo " echo \"\$(date) - disk sizes...\"" >> /var/www/$hubzilladaily
|
||||
echo " df -h" >> /var/www/$hubzilladaily
|
||||
echo " echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily
|
||||
echo " du -h $backup_mount_point | grep mysql/hubzilla" >> /var/www/$hubzilladaily
|
||||
echo " echo \"unmounting backup device...\"" >> /var/www/$hubzilladaily
|
||||
echo " umount $backup_mount_point" >> /var/www/$hubzilladaily
|
||||
echo " else" >> /var/www/$hubzilladaily
|
||||
echo " echo \"failed to mount device $backup_device_name\"" >> /var/www/$hubzilladaily
|
||||
echo " fi" >> /var/www/$hubzilladaily
|
||||
if [ -n "$backup_device_pass" ]
|
||||
then
|
||||
echo " echo \"closing decrypted backup device...\"" >> /var/www/$hubzilladaily
|
||||
echo " cryptsetup luksClose cryptobackup" >> /var/www/$hubzilladaily
|
||||
fi
|
||||
echo " fi" >> /var/www/$hubzilladaily
|
||||
echo "fi" >> /var/www/$hubzilladaily
|
||||
echo "if [ \$device_mounted == 0 ]" >> /var/www/$hubzilladaily
|
||||
echo "then" >> /var/www/$hubzilladaily
|
||||
echo " echo \"device could not be mounted $backup_device_name. Using internal disk for backup...\"" >> /var/www/$hubzilladaily
|
||||
echo " rsnapshot -c $snapshotconfig daily" >> /var/www/$hubzilladaily
|
||||
echo " rsnapshot -c $snapshotconfig weekly" >> /var/www/$hubzilladaily
|
||||
echo " rsnapshot -c $snapshotconfig monthly" >> /var/www/$hubzilladaily
|
||||
echo "fi" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - db size...\"" >> /var/www/$hubzilladaily
|
||||
echo "du -h /var/cache/rsnapshot/ | grep mysql/hubzilla" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "# update" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - updating letsencrypt.sh...\"" >> /var/www/$hubzilladaily
|
||||
echo "git -C /var/www/letsencrypt/ pull" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - updating hubhilla core...\"" >> /var/www/$hubzilladaily
|
||||
echo "git -C /var/www/html/ pull" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - updating hubhilla addons...\"" >> /var/www/$hubzilladaily
|
||||
echo "git -C /var/www/html/addon/ pull" >> /var/www/$hubzilladaily
|
||||
echo "bash /var/www/html/$plugins_update" >> /var/www/$hubzilladaily
|
||||
echo "chown -R www-data:www-data /var/www/html/ # make all accessable for the webserver" >> /var/www/$hubzilladaily
|
||||
echo "chown root:www-data /var/www/html/.htaccess" >> /var/www/$hubzilladaily
|
||||
echo "chmod 0644 /var/www/html/.htaccess # www-data can read but not write it" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - updating linux...\"" >> /var/www/$hubzilladaily
|
||||
echo "apt-get -q -y update && apt-get -q -y dist-upgrade # update linux and upgrade" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - Backup hubzilla and update linux finished. Rebooting...\"" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "reboot" >> /var/www/$hubzilladaily
|
||||
|
||||
if [ -z "`grep 'hubzilla-daily.sh' /etc/crontab`" ]
|
||||
then
|
||||
echo "30 05 * * * root /bin/bash /var/www/$hubzilladaily >> /var/www/html/hubzilla-daily.log 2>&1" >> /etc/crontab
|
||||
echo "0 0 1 * * root rm /var/www/html/hubzilla-daily.log" >> /etc/crontab
|
||||
fi
|
||||
|
||||
# This is active after either "reboot" or "/etc/init.d/cron reload"
|
||||
print_info "configured cron for updates/upgrades"
|
||||
}
|
||||
|
||||
function write_uninstall_script {
|
||||
print_info "writing uninstall script..."
|
||||
|
||||
cat > /var/www/hubzilla-remove.sh <<END
|
||||
#!/bin/sh
|
||||
#
|
||||
# This script removes Hubzilla.
|
||||
# You might do this for a fresh start using the script.
|
||||
# The script will remove (almost everything) what was installed by the script,
|
||||
# all applications including hubzilla and its database.
|
||||
#
|
||||
# Backup the certificates of letsencrypt (you never know)
|
||||
cp -a /var/www/letsencrypt/ ~/backup_le_certificats
|
||||
#
|
||||
# Removal
|
||||
apt-get remove apache2 apache2-utils libapache2-mod-php5 php5 php-pear php5-xcache php5-curl php5-mcrypt php5-gd php5-mysql mysql-server mysql-client phpmyadmin
|
||||
apt-get purge apache2 apache2-utils libapache2-mod-php5 php5 php-pear php5-xcache php5-curl php5-mcrypt php5-gd php5-mysql mysql-server mysql-client phpmyadmin
|
||||
apt-get autoremove
|
||||
apt-get clean
|
||||
rm /etc/rsnapshot_hubzilla.conf
|
||||
rm /etc/rsnapshot_hubzilla_external_device.conf
|
||||
rm -R /etc/apache2/
|
||||
rm -R /var/lib/mysql/
|
||||
rm -R /var/www
|
||||
rm -R /etc/selfhost/
|
||||
# uncomment the next line if you want to remove the backups
|
||||
# rm -R /var/cache/rsnapshot
|
||||
nano /etc/crontab # remove entries there manually
|
||||
END
|
||||
chmod -x /var/www/hubzilla-remove.sh
|
||||
}
|
||||
|
||||
########################################################################
|
||||
# START OF PROGRAM
|
||||
########################################################################
|
||||
export PATH=/bin:/usr/bin:/sbin:/usr/sbin
|
||||
|
||||
check_sanity
|
||||
|
||||
# Read config file edited by user
|
||||
configfile=hubzilla-config.txt
|
||||
source $configfile
|
||||
|
||||
selfhostdir=/etc/selfhost
|
||||
selfhostscript=selfhost-updater.sh
|
||||
hubzilladaily=hubzilla-daily.sh
|
||||
plugins_update=.homeinstall/plugins_update.sh
|
||||
snapshotconfig=/etc/rsnapshot_hubzilla.conf
|
||||
snapshotconfig_external_device=/etc/rsnapshot_hubzilla_external_device.conf
|
||||
backup_mount_point=/media/hubzilla_backup
|
||||
le_dir=/var/www/letsencrypt
|
||||
sslconf=/etc/apache2/sites-available/default-ssl.conf
|
||||
|
||||
#set -x # activate debugging from here
|
||||
|
||||
check_config
|
||||
stop_hubzilla
|
||||
update_upgrade
|
||||
install_curl
|
||||
install_sendmail
|
||||
install_apache
|
||||
install_php
|
||||
install_mysql
|
||||
install_phpmyadmin
|
||||
create_hubzilla_db
|
||||
run_freedns
|
||||
install_run_selfhost
|
||||
ping_domain
|
||||
configure_cron_freedns
|
||||
configure_cron_selfhost
|
||||
install_git
|
||||
install_letsencrypt
|
||||
configure_apache_for_https
|
||||
check_https
|
||||
install_hubzilla
|
||||
rewrite_to_https
|
||||
# install_owncloud # deprecated
|
||||
install_rsnapshot
|
||||
configure_cron_daily
|
||||
install_cryptosetup
|
||||
write_uninstall_script
|
||||
|
||||
#set +x # stop debugging from here
|
||||
|
@ -24,6 +24,9 @@ AddType audio/ogg .oga
|
||||
# Also place auth information into REMOTE_USER for sites running
|
||||
# in CGI mode.
|
||||
|
||||
RewriteCond %{REQUEST_URI} ^/\.well\-known/.*
|
||||
RewriteRule ^(.*)$ index.php?q=$1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^(.*)$ index.php?q=$1 [E=REMOTE_USER:%{HTTP:Authorization},L,QSA]
|
||||
|
@ -179,8 +179,11 @@ echo "chmod done, permissions set to 777 on poller script."
|
||||
|
||||
# Hubzilla configuration - changes to default settings
|
||||
# to make Hubzilla on OpenShift a more pleasant experience
|
||||
echo "Changing default configuration to conserve space"
|
||||
echo "Changing default configuration to conserve space and autocreate a social private channel upon account registration"
|
||||
cd ${OPENSHIFT_REPO_DIR}
|
||||
util/config system auto_channel_create
|
||||
util/config system default_permissions_role social_private
|
||||
util/config system workflow_channel_next channel
|
||||
util/config system expire_delivery_reports 3
|
||||
util/config system feed_contacts 0
|
||||
util/config system diaspora_enabled 0
|
||||
@ -197,9 +200,19 @@ util/add_addon_repo https://github.com/redmatrix/hubzilla-addons.git HubzillaAdd
|
||||
# Hubzilla themes
|
||||
echo "Try to add or update Hubzilla themes"
|
||||
cd ${OPENSHIFT_REPO_DIR}
|
||||
util/add_theme_repo https://github.com/DeadSuperHero/redmatrix-themes.git DeadSuperHeroThemes
|
||||
util/add_theme_repo https://github.com/DeadSuperHero/hubzilla-themes.git DeadSuperHeroThemes
|
||||
|
||||
# Hubzilla ownMapp
|
||||
echo "Try to add or update Hubzilla ownMapp"
|
||||
cd ${OPENSHIFT_REPO_DIR}
|
||||
util/add_addon_repo https://gitlab.com/zot/ownmapp.git ownMapp
|
||||
|
||||
# Hubzilla Chess
|
||||
echo "Try to add or update Hubzilla chess "
|
||||
cd ${OPENSHIFT_REPO_DIR}
|
||||
util/add_addon_repo https://gitlab.com/zot/hubzilla-chess.git Chess
|
||||
|
||||
# Hubzilla Hubsites
|
||||
echo "Try to add or update Hubzilla Hubsites"
|
||||
cd ${OPENSHIFT_REPO_DIR}
|
||||
util/add_addon_repo https://gitlab.com/zot/hubsites.git Hubsites
|
||||
|
168
CHANGELOG
Normal file
168
CHANGELOG
Normal file
@ -0,0 +1,168 @@
|
||||
Hubzilla 1.4
|
||||
[This list may appear brief, but encompasses a huge amount of re-writing and re-factoring
|
||||
of the internal code structure to gain long-term performance and stability and provide a standard
|
||||
interface to alternate protocol federation plugins which were made possible by the UNO configuration.
|
||||
UNO is a configuration of hubzilla introduced in 1.3 with reduced complexity and which provides
|
||||
improved protocol federation potential to other networks by virtue of removing nomadic identity
|
||||
(which is not possible to model or work around using other network protocols).]
|
||||
|
||||
Implement channel move operation for UNO configuration
|
||||
Remove bookmark references in UNO (which has no bookmarks by default)
|
||||
UI cleanup profiles/chat/manage
|
||||
Refactor webfinger probes and salmon backend for GNU-social federation
|
||||
SECURITY: DAV authentication exploit
|
||||
Context help added
|
||||
More help pages
|
||||
Provide 'posts only' feed
|
||||
Refactor App to remove globals
|
||||
Refactor Session to remove globals
|
||||
provide a fullscreen mode for selected modules and functions
|
||||
Regression: some addon routes broken
|
||||
fix "remember me"
|
||||
Autocomplete tool extended to bbcode/comanche
|
||||
Clone sync of file/photo updates
|
||||
system rename (e.g. http to https or DNS name change) missing some connection photos
|
||||
calendar module not blocked to public whhen block_public enabled
|
||||
Use timeago.js in reshare content so that timestamps will be correct on federated reshares
|
||||
Rework detection of JavaScript to avoid reload penalty under normal operation
|
||||
Changed primary directory server to a hubzilla server
|
||||
Plugins:
|
||||
Diaspora - switch to alternate XML parser to avoid storing compound objects
|
||||
GNU-Social - Huge amounts of work, federation somewhat working now, several issues remain
|
||||
Friendica - Initial federation work (not yet published)
|
||||
|
||||
Hubzilla 1.3
|
||||
Admin Security configuration page created which consolidates several previously hidden settings:
|
||||
Communication white/black lists
|
||||
Channel white/black lists
|
||||
OEmbed white/black lists
|
||||
Admin Profile Fields page created which manages the availability and order of standard profile fields and allows new fields to be created/managed
|
||||
"Poke" module reworked - page UI updated and "poke basic" setting introduced which limits the available poke "verbs".
|
||||
"Mood" module UI reworked
|
||||
"profile_photo" module UI reworked
|
||||
"cover_photo" module UI reworked
|
||||
"new_channel" module UI reworked
|
||||
"register" module UI reworked
|
||||
"pubsites" module UI reworked
|
||||
item-meta ("iconfig") created which implements arbitrary storage for item metadata for plugins
|
||||
abook-meta ("abconfig") created which implements arbitrary storage for connection metadata for plugins
|
||||
"Strict transport security header" made optional as it conflicts with some existing Apache/nginx configurations
|
||||
"Hubzilla UNO" (Hubzilla with radically simplified and locked site settings) implemented as an install configuration.
|
||||
.well-known directory conflict worked out to support LetsEncrypt cert ownership checks without disrupting webfinger and other internal uses of .well-known
|
||||
Lots of work on 'zcards' which are self-contained HTML representations of a channel including cover photos, profile photos, and some text information
|
||||
Long standing bug uncovered which failed to properly restrict the lower time limit for public feed requests
|
||||
A number of fixes to "readmore" to fix page jumping
|
||||
Bugfix: persons other than the channel owner who have permission to upload photos to a channel could not do so if the js_upload plugin/addon was enabled
|
||||
Siteinfo incorrectly identifying secondary directory servers
|
||||
Allow admin to set and lock features when UNO is configured
|
||||
Atom feeds: alter how events are formatted to be compatible with GNU-social
|
||||
Allow guest/visitor access to view personal calendar
|
||||
Moved several more classes to "composer format" and provided an autoloader.
|
||||
Bugfix: require existing password to change password
|
||||
Bugfix: allow relative_date() to be translated to Polish which has more than two plural forms.
|
||||
Plugin API: add "requires" keyword to module header to indicate dependent addons
|
||||
ActivityStreams improvements and cleanup: photo and file activities
|
||||
UI cleanup for editing profile when multiple profiles enabled
|
||||
Removed the "markdown" feature as there are numerous issues and no maintainer.
|
||||
Provide "footer" bbcode to ease theming of post footer content
|
||||
Bugfix: install issues caused by composer code refactor and typo in postgres load file
|
||||
Plugins:
|
||||
keepout - "block public on steroids"
|
||||
pubsubhubbub - provides PuSH support to Atom feeds, required for GNU-social federation
|
||||
GNUsocial protocol - under development
|
||||
Diaspora protocol - some work to ease migration to the new signing format
|
||||
Diaspost - disabled; numerous issues and no maintainer
|
||||
smileybutton - theme work and fixed compatibility with other jot-tools plugins
|
||||
|
||||
|
||||
Hubzilla 1.2
|
||||
Provide extra HTTP security headers (several of them).
|
||||
Allow a site to disable delivery reports if disk space is limited
|
||||
Regression: Wrong theme when viewing single post as non-member
|
||||
Some Diaspora profile photos use relative URLs - force absolute
|
||||
Add locked features to siteinfo report to aid remote debugging
|
||||
Provide version compatibility checking to plugins (minversion, maxversion, and minphpversion)
|
||||
Account config storage
|
||||
Provide optional integrated registration and channel create form
|
||||
cli utility for managing addons
|
||||
issue with sharing photo "items"
|
||||
cover photo manager: upload, crop, and store
|
||||
cover photo widget created
|
||||
rework the connections list page and provide a few management features there
|
||||
fixed issue with Comanche layout definitions loaded by plugins
|
||||
provide ability to separate delivery functions from item_store() and item_store_update() - some forum messages were being redelivered when cloned.
|
||||
call build_sync_packet() on pdledit changes
|
||||
Abstract the project name and version so these can be customised or removed
|
||||
Allow hiding the ratings links on a per-site basis
|
||||
db_type not present in international setup templates - was unable to choose postgres.
|
||||
item_photo_menu logically divided into a) actions on the post, b) actions related to the author
|
||||
bug: default channel not reset to 0 when last channel removed
|
||||
create widget containing only the contact block
|
||||
regression: public forums granted send stream permissions to connections
|
||||
workaround Firefox's refusal to honour disabling autocomplete of passwords
|
||||
regression: photo's uploaded to a channel by a guest (with file write permissions) not saved correctly.
|
||||
provide mechanisms for custom .well-known handlers (needed for LetsEncrypt ownership verification)
|
||||
proc_run modified to use exec() instead of proc_open() - causing issues on some PHP installations
|
||||
remote delegation failure under a specific set of circumstances which we were finally able to duplicate
|
||||
Delegation section of Channel Manager was missing names and contained useless notification icons.
|
||||
Change "expire" channel setting to show system limit if there is one.
|
||||
Regression: provide a one-click ignore of pending connection
|
||||
Config to control directory keyword generation on client and server.
|
||||
"Collections" renamed to "Privacy Groups", documentation improved
|
||||
widget_item - allow use of page title instead of message id
|
||||
Add site black/white list checking to all .well-known services
|
||||
reduce incidents of screen jumping when "showmore" is activated
|
||||
add oembed provider for photos
|
||||
|
||||
Addons:
|
||||
|
||||
CSS theming of pageheader plugin
|
||||
xmpp addon ported from Friendica
|
||||
Diaspora private mail issues after the third reply
|
||||
Occasional issue with Diaspora connection requests
|
||||
Add notification email to Diaspora PMs
|
||||
Allow anonymising platform and version for statistics
|
||||
msgfooter addon created
|
||||
removed embedly plugin
|
||||
sync clones after superblock addition
|
||||
"keepout" plugin created
|
||||
|
||||
|
||||
Hubzilla 1.1
|
||||
|
||||
Rewrote and simplified the Queue manager and delivery system
|
||||
Rewrote and simplified the outer layers of the Zot protocol
|
||||
Use a standard version numbering scheme in addition to the snapshot tags
|
||||
Provide a channel blacklist for blocking channels with abusive or illegal content at the hub level
|
||||
Make the black/white lists pluggable
|
||||
Update template library
|
||||
Support for letsencrypt certs in various places
|
||||
Cleanup of login and register pages
|
||||
Better error responses for permission denied on channel file repositories
|
||||
Disabled the public stream by default for new installs (can be enabled if desired)
|
||||
Cleanup of API authentication and rework the old OAuth1 stuff
|
||||
Add API "status with media" support compatible with Twitter and conflicting method for GNU-social
|
||||
Rework photo ActivityStreams objects to align better with ActivityStreams producers/consumers
|
||||
Several minor API fixes to work better with AndStatus client
|
||||
Invitation only site - experimental support added, needs more work
|
||||
Fix delivery loop condition due to corrupted data which resulted in recursive upstream delivery
|
||||
Provide more support for external (git) widget collections.
|
||||
Extend the Queue API to 3rd-party network addons which have experienced downtime recently.
|
||||
Regression: Inherited permissions were not explicitly set
|
||||
Regression: "Xyz posted on your wall" notification sent when creating webpages at another channel
|
||||
Regression: Custom permissions not pre-populated on channel creation with named role.
|
||||
Provide "Public" string when a post can be made public, instead of "visible to default audience"
|
||||
Allow hub admin to specify a default role type for the first channel created, reducing complexity
|
||||
Ability for a hub admin to set feature defaults and lock them, reducing complexity
|
||||
Change default expiration of delivery reports to 10 days to accomodate sites with reduced resources
|
||||
Addons/Plugins:
|
||||
Pageheader addon ported from Friendica
|
||||
Hubwall (allow admin to send email to all accounts on this hub) created
|
||||
GNU-social - queueing added
|
||||
Diaspora - fixes for various failures to update profile photos, updates to queue API
|
||||
Cross Domain Authenticated Chess (Andrew Manning's repository)
|
||||
|
||||
And... the normal "lots of bugs fixed, translations updated, and documentation improved"
|
||||
|
||||
|
||||
|
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2010-2015 Hubzilla
|
||||
Copyright (c) 2010-2016 Hubzilla
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
25
README.md
25
README.md
@ -3,24 +3,26 @@
|
||||
Hubzilla - Community Server
|
||||
===========================
|
||||
|
||||
Help us redefine the web - using integrated and united community websites.
|
||||
--------------------------------------------------------------------------
|
||||
Connected and linked web communities.
|
||||
-------------------------------------
|
||||
|
||||
[](https://travis-ci.org/redmatrix/hubzilla)
|
||||
<p align="center" markdown="1">
|
||||
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
|
||||
</p>
|
||||
|
||||
**What are Hubs?**
|
||||
**What are Hubz?**
|
||||
|
||||
Hubs are independent general-purpose websites that not only connect with their associated members and viewers, but also connect together to exchange personal communications and other information with each other.
|
||||
Hubz are independent general-purpose websites that not only connect with their associated members and viewers, but also connect together to exchange personal communications and other information with each other.
|
||||
This allows hub members on any hub to securely and privately share anything; with anybody, on any hub - anywhere; or share stuff publicly with anybody on the internet if desired.
|
||||
|
||||
**Hubzilla** is the server software which makes this possible. It is a sophisticated and unique combination of an open source content management system and a decentralised identity, communications, and permissions framework and protocol suite, built using common webserver technology (PHP/MySQL/Apache, although Mariadb or Postgres and Nginx could also be used - we're pretty easy). The end result is a level of systems integration, privacy control, and communications features that you wouldn't think are possible in either a content management system or a decentralised communications network. It also brings a new level of cooperation and privacy to the web and introduces the concept of personally owned "single sign-on" to web services across the entire internet.
|
||||
**Hubzilla** is the server software which makes this possible. It is a sophisticated and unique combination of an open source content management system and a decentralised identity, communications, and permissions framework and protocol suite, built using common webserver technology (PHP/MySQL/Apache and popular variants). The end result is a level of systems integration, privacy control, and communications features that you wouldn't think are possible in either a content management system or a decentralised communications network. It also brings a new level of cooperation and privacy to the web and introduces the concept of personally owned "single sign-on" to web services across the entire internet.
|
||||
|
||||
Hubzilla hubs are
|
||||
Hubzilla hubz are
|
||||
|
||||
* decentralised
|
||||
* inherently social
|
||||
* optionally inter-networked with other hubs
|
||||
* privacy-enabled (privacy exclusions work across the entire internet to any registered identity on any compatible hubs)
|
||||
* optionally inter-networked with other hubz
|
||||
* privacy-enabled (privacy exclusions work across the entire internet to any registered identity on any compatible hubz)
|
||||
|
||||
Possible website applications include
|
||||
|
||||
@ -38,3 +40,8 @@ Possible website applications include
|
||||
* dating websites
|
||||
* pretty much anything you can do on a traditional blog or community website, but that you could do better if you could easily connect it with other websites or privately share things across website boundaries.
|
||||
|
||||
<p align="center" markdown="1">
|
||||
<em><a href="https://github.com/redmatrix/hubzilla/blob/master/install/INSTALL.txt">Installing Hubzilla</a></em>
|
||||
</p>
|
||||
|
||||
[](https://travis-ci.org/redmatrix/hubzilla)
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Access;
|
||||
|
||||
|
||||
class AccessList {
|
||||
|
||||
@ -88,61 +90,3 @@ class AccessList {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Used to wrap ACL elements in angle brackets for storage.
|
||||
*
|
||||
* @param[in,out] array &$item
|
||||
*/
|
||||
function sanitise_acl(&$item) {
|
||||
if (strlen($item))
|
||||
$item = '<' . notags(trim($item)) . '>';
|
||||
else
|
||||
unset($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert an ACL array to a storable string.
|
||||
*
|
||||
* @param array $p
|
||||
* @return array
|
||||
*/
|
||||
function perms2str($p) {
|
||||
$ret = '';
|
||||
|
||||
if (is_array($p))
|
||||
$tmp = $p;
|
||||
else
|
||||
$tmp = explode(',', $p);
|
||||
|
||||
if (is_array($tmp)) {
|
||||
array_walk($tmp, 'sanitise_acl');
|
||||
$ret = implode('', $tmp);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Turn user/group ACLs stored as angle bracketed text into arrays.
|
||||
*
|
||||
* turn string array of angle-bracketed elements into string array
|
||||
* e.g. "<123xyz><246qyo><sxo33e>" => array(123xyz,246qyo,sxo33e);
|
||||
*
|
||||
* @param string $s
|
||||
* @return array
|
||||
*/
|
||||
function expand_acl($s) {
|
||||
$ret = array();
|
||||
|
||||
if(strlen($s)) {
|
||||
$t = str_replace('<','',$s);
|
||||
$a = explode('>',$t);
|
||||
foreach($a as $aa) {
|
||||
if($aa)
|
||||
$ret[] = $aa;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
63
Zotlabs/Project/System.php
Normal file
63
Zotlabs/Project/System.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Project;
|
||||
|
||||
class System {
|
||||
|
||||
function get_platform_name() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['platform_name'])
|
||||
return \App::$config['system']['platform_name'];
|
||||
return PLATFORM_NAME;
|
||||
}
|
||||
|
||||
function get_site_name() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['sitename'])
|
||||
return \App::$config['system']['sitename'];
|
||||
return '';
|
||||
}
|
||||
|
||||
function get_project_version() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['hide_version'])
|
||||
return '';
|
||||
return RED_VERSION;
|
||||
}
|
||||
|
||||
function get_update_version() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['hide_version'])
|
||||
return '';
|
||||
return DB_UPDATE_VERSION;
|
||||
}
|
||||
|
||||
|
||||
function get_notify_icon() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['email_notify_icon_url'])
|
||||
return \App::$config['system']['email_notify_icon_url'];
|
||||
return z_root() . '/images/hz-white-32.png';
|
||||
}
|
||||
|
||||
function get_site_icon() {
|
||||
if(is_array(\App::$config) && is_array(\App::$config['system']) && \App::$config['system']['site_icon_url'])
|
||||
return \App::$config['system']['site_icon_url'];
|
||||
return z_root() . '/images/hz-32.png';
|
||||
}
|
||||
|
||||
|
||||
function get_server_role() {
|
||||
if(UNO)
|
||||
return 'basic';
|
||||
return 'advanced';
|
||||
}
|
||||
|
||||
// return the standardised version. Since we can't easily compare
|
||||
// before the STD_VERSION definition was applied, we have to treat
|
||||
// all prior release versions the same. You can dig through them
|
||||
// with other means (such as RED_VERSION) if necessary.
|
||||
|
||||
function get_std_version() {
|
||||
if(defined('STD_VERSION'))
|
||||
return STD_VERSION;
|
||||
return '0.0.0';
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace RedMatrix\RedDAV;
|
||||
namespace Zotlabs\Storage;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
||||
/**
|
||||
* @brief Authentication backend class for RedDAV.
|
||||
* @brief Authentication backend class for DAV.
|
||||
*
|
||||
* This class also contains some data which is not necessary for authentication
|
||||
* like timezone settings.
|
||||
@ -15,7 +15,7 @@ use Sabre\DAV;
|
||||
* @link http://github.com/friendica/red
|
||||
* @license http://opensource.org/licenses/mit-license.php The MIT License (MIT)
|
||||
*/
|
||||
class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
class BasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
|
||||
/**
|
||||
* @brief This variable holds the currently logged-in channel_address.
|
||||
@ -45,18 +45,18 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
public $observer = '';
|
||||
/**
|
||||
*
|
||||
* @see RedBrowser::set_writeable()
|
||||
* @see Browser::set_writeable()
|
||||
* @var \Sabre\DAV\Browser\Plugin
|
||||
*/
|
||||
public $browser;
|
||||
/**
|
||||
* channel_id of the current visited path. Set in RedDirectory::getDir().
|
||||
* channel_id of the current visited path. Set in Directory::getDir().
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $owner_id = 0;
|
||||
/**
|
||||
* channel_name of the current visited path. Set in RedDirectory::getDir().
|
||||
* channel_name of the current visited path. Set in Directory::getDir().
|
||||
*
|
||||
* Used for creating the path in cloud/
|
||||
*
|
||||
@ -110,7 +110,7 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
if ($x) {
|
||||
// @fixme this foreach should not be needed?
|
||||
foreach ($x as $record) {
|
||||
if (($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED)
|
||||
if ((($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED))
|
||||
&& (hash('whirlpool', $record['account_salt'] . $password) === $record['account_password'])) {
|
||||
logger('password verified for ' . $username);
|
||||
return $this->setAuthenticated($r[0]);
|
||||
@ -197,7 +197,7 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints out all RedBasicAuth variables to logger().
|
||||
* @brief Prints out all BasicAuth variables to logger().
|
||||
*
|
||||
* @return void
|
||||
*/
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace RedMatrix\RedDAV;
|
||||
namespace Zotlabs\Storage;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
||||
@ -15,7 +15,7 @@ use Sabre\DAV;
|
||||
* @link http://github.com/friendica/red
|
||||
* @license http://opensource.org/licenses/mit-license.php The MIT License (MIT)
|
||||
*/
|
||||
class RedBrowser extends DAV\Browser\Plugin {
|
||||
class Browser extends DAV\Browser\Plugin {
|
||||
|
||||
/**
|
||||
* @see set_writeable()
|
||||
@ -243,7 +243,7 @@ class RedBrowser extends DAV\Browser\Plugin {
|
||||
));
|
||||
|
||||
$a = get_app();
|
||||
$a->page['content'] = $html;
|
||||
\App::$page['content'] = $html;
|
||||
load_pdl($a);
|
||||
|
||||
$theme_info_file = "view/theme/" . current_theme() . "/php/theme.php";
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace RedMatrix\RedDAV;
|
||||
namespace Zotlabs\Storage;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
||||
@ -16,7 +16,7 @@ use Sabre\DAV;
|
||||
* @link http://github.com/friendica/red
|
||||
* @license http://opensource.org/licenses/mit-license.php The MIT License (MIT)
|
||||
*/
|
||||
class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
|
||||
/**
|
||||
* @brief The path inside /cloud
|
||||
@ -53,7 +53,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
logger('directory ' . $ext_path, LOGGER_DATA);
|
||||
$this->ext_path = $ext_path;
|
||||
// remove "/cloud" from the beginning of the path
|
||||
$modulename = get_app()->module;
|
||||
$modulename = \App::$module;
|
||||
$this->red_path = ((strpos($ext_path, '/' . $modulename) === 0) ? substr($ext_path, strlen($modulename) + 1) : $ext_path);
|
||||
if (! $this->red_path) {
|
||||
$this->red_path = '/';
|
||||
@ -114,9 +114,9 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
$modulename = get_app()->module;
|
||||
$modulename = \App::$module;
|
||||
if ($this->red_path === '/' && $name === $modulename) {
|
||||
return new RedDirectory('/' . $modulename, $this->auth);
|
||||
return new Directory('/' . $modulename, $this->auth);
|
||||
}
|
||||
|
||||
$x = RedFileData($this->ext_path . '/' . $name, $this->auth);
|
||||
@ -168,6 +168,14 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
intval($this->auth->owner_id)
|
||||
);
|
||||
|
||||
|
||||
$ch = channelx_by_n($this->auth->owner_id);
|
||||
if($ch) {
|
||||
$sync = attach_export_data($ch,$this->folder_hash);
|
||||
if($sync)
|
||||
build_sync_packet($ch['channel_id'],array('file' => array($sync)));
|
||||
}
|
||||
|
||||
$this->red_path = $new_path;
|
||||
}
|
||||
|
||||
@ -332,9 +340,15 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
|
||||
require_once('include/photos.php');
|
||||
$args = array( 'resource_id' => $hash, 'album' => $album, 'os_path' => $f, 'filename' => $name, 'getimagesize' => $x, 'directory' => $direct);
|
||||
$p = photo_upload($c[0],get_app()->get_observer(),$args);
|
||||
$p = photo_upload($c[0],\App::get_observer(),$args);
|
||||
}
|
||||
|
||||
$sync = attach_export_data($c[0],$hash);
|
||||
|
||||
if($sync)
|
||||
build_sync_packet($c[0]['channel_id'],array('file' => array($sync)));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -356,7 +370,14 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
|
||||
if ($r) {
|
||||
$result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash));
|
||||
if (! $result['success']) {
|
||||
|
||||
if($result['success']) {
|
||||
$sync = attach_export_data($r[0],$ret['data']['hash']);
|
||||
if($sync) {
|
||||
build_sync_packet($r[0]['channel_id'],array('file' => array($sync)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger('error ' . print_r($result, true), LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
@ -380,6 +401,15 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
}
|
||||
|
||||
attach_delete($this->auth->owner_id, $this->folder_hash);
|
||||
|
||||
$ch = channelx_by_n($this->auth->owner_id);
|
||||
if($ch) {
|
||||
$sync = attach_export_data($ch,$this->folder_hash,true);
|
||||
if($sync)
|
||||
build_sync_packet($ch['channel_id'],array('file' => array($sync)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -393,7 +423,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
public function childExists($name) {
|
||||
// On /cloud we show a list of available channels.
|
||||
// @todo what happens if no channels are available?
|
||||
$modulename = get_app()->module;
|
||||
$modulename = \App::$module;
|
||||
if ($this->red_path === '/' && $name === $modulename) {
|
||||
//logger('We are at ' $modulename . ' show a channel list', LOGGER_DEBUG);
|
||||
return true;
|
||||
@ -417,7 +447,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
|
||||
logger('GetDir: ' . $this->ext_path, LOGGER_DEBUG);
|
||||
$this->auth->log();
|
||||
$modulename = get_app()->module;
|
||||
$modulename = \App::$module;
|
||||
|
||||
$file = $this->ext_path;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace RedMatrix\RedDAV;
|
||||
namespace Zotlabs\Storage;
|
||||
|
||||
use Sabre\DAV;
|
||||
|
||||
@ -15,7 +15,7 @@ use Sabre\DAV;
|
||||
* @link http://github.com/friendica/red
|
||||
* @license http://opensource.org/licenses/mit-license.php The MIT License (MIT)
|
||||
*/
|
||||
class RedFile extends DAV\Node implements DAV\IFile {
|
||||
class File extends DAV\Node implements DAV\IFile {
|
||||
|
||||
/**
|
||||
* The file from attach table.
|
||||
@ -84,6 +84,20 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
dbesc($this->data['hash']),
|
||||
intval($this->data['id'])
|
||||
);
|
||||
|
||||
if($this->data->is_photo) {
|
||||
$r = q("update photo set filename = '%s' where resource_id = '%s' and uid = %d",
|
||||
dbesc($newName),
|
||||
dbesc($this->data['hash']),
|
||||
intval($this->auth->owner_id)
|
||||
);
|
||||
}
|
||||
$ch = channelx_by_n($this->auth->owner_id);
|
||||
if($ch) {
|
||||
$sync = attach_export_data($ch,$this->data['hash']);
|
||||
if($sync)
|
||||
build_sync_packet($ch['channel_id'],array('file' => array($sync)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,7 +187,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
if($is_photo) {
|
||||
require_once('include/photos.php');
|
||||
$args = array( 'resource_id' => $this->data['hash'], 'album' => $album, 'os_path' => $f, 'filename' => $r[0]['filename'], 'getimagesize' => $gis, 'directory' => $direct );
|
||||
$p = photo_upload($c[0],get_app()->get_observer(),$args);
|
||||
$p = photo_upload($c[0],\App::get_observer(),$args);
|
||||
}
|
||||
|
||||
// update the folder's lastmodified timestamp
|
||||
@ -205,6 +219,12 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$sync = attach_export_data($c[0],$this->data['hash']);
|
||||
|
||||
if($sync)
|
||||
build_sync_packet($c[0]['channel_id'],array('file' => array($sync)));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -318,5 +338,12 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
}
|
||||
|
||||
attach_delete($this->auth->owner_id, $this->data['hash']);
|
||||
|
||||
$ch = channelx_by_n($this->auth->owner_id);
|
||||
if($ch) {
|
||||
$sync = attach_export_data($ch,$this->data['hash'],true);
|
||||
if($sync)
|
||||
build_sync_packet($ch['channel_id'],array('file' => array($sync)));
|
||||
}
|
||||
}
|
||||
}
|
36
Zotlabs/Web/CheckJS.php
Normal file
36
Zotlabs/Web/CheckJS.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Web;
|
||||
|
||||
|
||||
class CheckJS {
|
||||
|
||||
private static $jsdisabled = 0;
|
||||
|
||||
function __construct($test = 0) {
|
||||
if(intval($_REQUEST['jsdisabled']))
|
||||
$this->jsdisabled = 1;
|
||||
if(intval($_COOKIE['jsdisabled']))
|
||||
$this->jsdisabled = 1;
|
||||
|
||||
if(! $this->jsdisabled) {
|
||||
$page = urlencode(\App::$query_string);
|
||||
|
||||
if($test) {
|
||||
\App::$page['htmlhead'] .= "\r\n" . '<meta http-equiv="refresh" content="0; url=' . z_root() . '/nojs?f=&redir=' . $page . '">' . "\r\n";
|
||||
}
|
||||
else {
|
||||
\App::$page['htmlhead'] .= "\r\n" . '<noscript><meta http-equiv="refresh" content="0; url=' . z_root() . '/nojs?f=&redir=' . $page . '"></noscript>' . "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function disabled() {
|
||||
return self::$jsdisabled;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
66
Zotlabs/Web/HttpMeta.php
Normal file
66
Zotlabs/Web/HttpMeta.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Web;
|
||||
|
||||
|
||||
class HttpMeta {
|
||||
|
||||
private $vars = null;
|
||||
private $og = null;
|
||||
|
||||
function __construct() {
|
||||
|
||||
$this->vars = array();
|
||||
$this->og = array();
|
||||
|
||||
}
|
||||
|
||||
function set($property,$value) {
|
||||
if(strpos($property,'og:') === 0)
|
||||
$this->og[$property] = $value;
|
||||
else
|
||||
$this->vars[$property] = $value;
|
||||
}
|
||||
|
||||
function check_required() {
|
||||
if(
|
||||
($this->og)
|
||||
&& array_key_exists('og:title',$this->og)
|
||||
&& array_key_exists('og:type', $this->og)
|
||||
&& array_key_exists('og:image',$this->og)
|
||||
&& array_key_exists('og:url', $this->og)
|
||||
)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_field($field) {
|
||||
if(strpos($field,'og:') === 0)
|
||||
$arr = $this->og;
|
||||
else
|
||||
$arr = $this->vars;
|
||||
|
||||
if($arr && array_key_exists($field,$arr) && $arr[$field])
|
||||
return $arr[$field];
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function get() {
|
||||
$o = '';
|
||||
if($this->vars) {
|
||||
foreach($this->vars as $k => $v) {
|
||||
$o .= '<meta property="' . $k . '" content="' . urlencode($v) . '" />' . "\r\n" ;
|
||||
}
|
||||
}
|
||||
if($this->check_required()) {
|
||||
foreach($this->og as $k => $v) {
|
||||
$o .= '<meta property="' . $k . '" content="' . urlencode($v) . '" />' . "\r\n" ;
|
||||
}
|
||||
}
|
||||
if($o)
|
||||
return "\r\n" . $o;
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
203
Zotlabs/Web/Router.php
Normal file
203
Zotlabs/Web/Router.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Web;
|
||||
|
||||
|
||||
class Router {
|
||||
|
||||
function __construct(&$a) {
|
||||
|
||||
/**
|
||||
*
|
||||
* We have already parsed the server path into App::$argc and App::$argv
|
||||
*
|
||||
* App::$argv[0] is our module name. We will load the file mod/{App::$argv[0]}.php
|
||||
* and use it for handling our URL request.
|
||||
* The module file contains a few functions that we call in various circumstances
|
||||
* and in the following order:
|
||||
*
|
||||
* "module"_init
|
||||
* "module"_post (only called if there are $_POST variables)
|
||||
* "module"_content - the string return of this function contains our page body
|
||||
*
|
||||
* Modules which emit other serialisations besides HTML (XML,JSON, etc.) should do
|
||||
* so within the module init and/or post functions and then invoke killme() to terminate
|
||||
* further processing.
|
||||
*/
|
||||
|
||||
$module = \App::$module;
|
||||
|
||||
if(strlen($module)) {
|
||||
|
||||
/**
|
||||
*
|
||||
* We will always have a module name.
|
||||
* First see if we have a plugin which is masquerading as a module.
|
||||
*
|
||||
*/
|
||||
|
||||
if(is_array(\App::$plugins) && in_array($module,\App::$plugins) && file_exists("addon/{$module}/{$module}.php")) {
|
||||
include_once("addon/{$module}/{$module}.php");
|
||||
if(function_exists($module . '_module'))
|
||||
\App::$module_loaded = true;
|
||||
}
|
||||
|
||||
if((strpos($module,'admin') === 0) && (! is_site_admin())) {
|
||||
\App::$module_loaded = false;
|
||||
notice( t('Permission denied.') . EOL);
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
/**
|
||||
* If the site has a custom module to over-ride the standard module, use it.
|
||||
* Otherwise, look for the standard program module in the 'mod' directory
|
||||
*/
|
||||
|
||||
if(! (\App::$module_loaded)) {
|
||||
if(file_exists("mod/site/{$module}.php")) {
|
||||
include_once("mod/site/{$module}.php");
|
||||
\App::$module_loaded = true;
|
||||
}
|
||||
elseif(file_exists("mod/{$module}.php")) {
|
||||
include_once("mod/{$module}.php");
|
||||
\App::$module_loaded = true;
|
||||
}
|
||||
else logger("mod/{$module}.php not found.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This provides a place for plugins to register module handlers which don't otherwise exist on the system.
|
||||
* If the plugin sets 'installed' to true we won't throw a 404 error for the specified module even if
|
||||
* there is no specific module file or matching plugin name.
|
||||
* The plugin should catch at least one of the module hooks for this URL.
|
||||
*/
|
||||
|
||||
$x = array('module' => $module, 'installed' => false);
|
||||
call_hooks('module_loaded', $x);
|
||||
if($x['installed'])
|
||||
\App::$module_loaded = true;
|
||||
|
||||
/**
|
||||
* The URL provided does not resolve to a valid module.
|
||||
*
|
||||
* On Dreamhost sites, quite often things go wrong for no apparent reason and they send us to '/internal_error.html'.
|
||||
* We don't like doing this, but as it occasionally accounts for 10-20% or more of all site traffic -
|
||||
* we are going to trap this and redirect back to the requested page. As long as you don't have a critical error on your page
|
||||
* this will often succeed and eventually do the right thing.
|
||||
*
|
||||
* Otherwise we are going to emit a 404 not found.
|
||||
*/
|
||||
|
||||
if(! (\App::$module_loaded)) {
|
||||
|
||||
// Stupid browser tried to pre-fetch our Javascript img template. Don't log the event or return anything - just quietly exit.
|
||||
if((x($_SERVER, 'QUERY_STRING')) && preg_match('/{[0-9]}/', $_SERVER['QUERY_STRING']) !== 0) {
|
||||
killme();
|
||||
}
|
||||
|
||||
if((x($_SERVER, 'QUERY_STRING')) && ($_SERVER['QUERY_STRING'] === 'q=internal_error.html') && \App::$config['system']['dreamhost_error_hack']) {
|
||||
logger('index.php: dreamhost_error_hack invoked. Original URI =' . $_SERVER['REQUEST_URI']);
|
||||
goaway(z_root() . $_SERVER['REQUEST_URI']);
|
||||
}
|
||||
|
||||
logger('index.php: page not found: ' . $_SERVER['REQUEST_URI'] . ' ADDRESS: ' . $_SERVER['REMOTE_ADDR'] . ' QUERY: ' . $_SERVER['QUERY_STRING'], LOGGER_DEBUG);
|
||||
header($_SERVER['SERVER_PROTOCOL'] . ' 404 ' . t('Not Found'));
|
||||
$tpl = get_markup_template('404.tpl');
|
||||
\App::$page['content'] = replace_macros($tpl, array(
|
||||
'$message' => t('Page not found.')
|
||||
));
|
||||
|
||||
// pretend this is a module so it will initialise the theme
|
||||
\App::$module = '404';
|
||||
\App::$module_loaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function Dispatch(&$a) {
|
||||
|
||||
/**
|
||||
* Call module functions
|
||||
*/
|
||||
|
||||
if(\App::$module_loaded) {
|
||||
\App::$page['page_title'] = \App::$module;
|
||||
$placeholder = '';
|
||||
|
||||
/**
|
||||
* No theme has been specified when calling the module_init functions
|
||||
* For this reason, please restrict the use of templates to those which
|
||||
* do not provide any presentation details - as themes will not be able
|
||||
* to over-ride them.
|
||||
*/
|
||||
|
||||
if(function_exists(\App::$module . '_init')) {
|
||||
$arr = array('init' => true, 'replace' => false);
|
||||
call_hooks(\App::$module . '_mod_init', $arr);
|
||||
if(! $arr['replace']) {
|
||||
$func = \App::$module . '_init';
|
||||
$func($a);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do all theme initialiasion here before calling any additional module functions.
|
||||
* The module_init function may have changed the theme.
|
||||
* Additionally any page with a Comanche template may alter the theme.
|
||||
* So we'll check for those now.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* In case a page has overloaded a module, see if we already have a layout defined
|
||||
* otherwise, if a PDL file exists for this module, use it
|
||||
* The member may have also created a customised PDL that's stored in the config
|
||||
*/
|
||||
|
||||
load_pdl($a);
|
||||
|
||||
/**
|
||||
* load current theme info
|
||||
*/
|
||||
|
||||
$theme_info_file = 'view/theme/' . current_theme() . '/php/theme.php';
|
||||
if (file_exists($theme_info_file)){
|
||||
require_once($theme_info_file);
|
||||
}
|
||||
|
||||
if(function_exists(str_replace('-', '_', current_theme()) . '_init')) {
|
||||
$func = str_replace('-', '_', current_theme()) . '_init';
|
||||
$func($a);
|
||||
}
|
||||
elseif (x(\App::$theme_info, 'extends') && file_exists('view/theme/' . \App::$theme_info['extends'] . '/php/theme.php')) {
|
||||
require_once('view/theme/' . \App::$theme_info['extends'] . '/php/theme.php');
|
||||
if(function_exists(str_replace('-', '_', \App::$theme_info['extends']) . '_init')) {
|
||||
$func = str_replace('-', '_', \App::$theme_info['extends']) . '_init';
|
||||
$func($a);
|
||||
}
|
||||
}
|
||||
|
||||
if(($_SERVER['REQUEST_METHOD'] === 'POST') && (! \App::$error)
|
||||
&& (function_exists(\App::$module . '_post'))
|
||||
&& (! x($_POST, 'auth-params'))) {
|
||||
call_hooks(\App::$module . '_mod_post', $_POST);
|
||||
$func = \App::$module . '_post';
|
||||
$func($a);
|
||||
}
|
||||
|
||||
if((! \App::$error) && (function_exists(\App::$module . '_content'))) {
|
||||
$arr = array('content' => \App::$page['content'], 'replace' => false);
|
||||
call_hooks(\App::$module . '_mod_content', $arr);
|
||||
\App::$page['content'] = $arr['content'];
|
||||
if(! $arr['replace']) {
|
||||
$func = \App::$module . '_content';
|
||||
$arr = array('content' => $func($a));
|
||||
}
|
||||
call_hooks(\App::$module . '_mod_aftercontent', $arr);
|
||||
\App::$page['content'] .= $arr['content'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
160
Zotlabs/Web/Session.php
Normal file
160
Zotlabs/Web/Session.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Web;
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This file includes session related functions.
|
||||
*
|
||||
* Session management functions. These provide database storage of PHP
|
||||
* session info.
|
||||
*/
|
||||
|
||||
|
||||
class Session {
|
||||
|
||||
private static $handler = null;
|
||||
private static $session_started = false;
|
||||
|
||||
function init() {
|
||||
|
||||
$gc_probability = 50;
|
||||
|
||||
ini_set('session.gc_probability', $gc_probability);
|
||||
ini_set('session.use_only_cookies', 1);
|
||||
ini_set('session.cookie_httponly', 1);
|
||||
|
||||
/*
|
||||
* Set our session storage functions.
|
||||
*/
|
||||
|
||||
$handler = new \Zotlabs\Web\SessionHandler();
|
||||
self::$handler = $handler;
|
||||
|
||||
$x = session_set_save_handler($handler,true);
|
||||
if(! $x)
|
||||
logger('Session save handler initialisation failed.',LOGGER_NORMAL,LOG_ERR);
|
||||
|
||||
// Force cookies to be secure (https only) if this site is SSL enabled.
|
||||
// Must be done before session_start().
|
||||
|
||||
$arr = session_get_cookie_params();
|
||||
session_set_cookie_params(
|
||||
((isset($arr['lifetime'])) ? $arr['lifetime'] : 0),
|
||||
((isset($arr['path'])) ? $arr['path'] : '/'),
|
||||
((isset($arr['domain'])) ? $arr['domain'] : App::get_hostname()),
|
||||
((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') ? true : false),
|
||||
((isset($arr['httponly'])) ? $arr['httponly'] : true)
|
||||
);
|
||||
}
|
||||
|
||||
function start() {
|
||||
session_start();
|
||||
self::$session_started = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets the current session.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function nuke() {
|
||||
self::new_cookie(0); // 0 means delete on browser exit
|
||||
if($_SESSION && count($_SESSION)) {
|
||||
foreach($_SESSION as $k => $v) {
|
||||
unset($_SESSION[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function new_cookie($xtime) {
|
||||
|
||||
$newxtime = (($xtime> 0) ? (time() + $xtime) : 0);
|
||||
|
||||
$old_sid = session_id();
|
||||
|
||||
if(self::$handler && self::$session_started) {
|
||||
session_regenerate_id(true);
|
||||
|
||||
// force SessionHandler record creation with the new session_id
|
||||
// which occurs as a side effect of read()
|
||||
|
||||
self::$handler->read(session_id());
|
||||
}
|
||||
else
|
||||
logger('no session handler');
|
||||
|
||||
if (x($_COOKIE, 'jsdisabled')) {
|
||||
setcookie('jsdisabled', $_COOKIE['jsdisabled'], $newxtime);
|
||||
}
|
||||
setcookie(session_name(),session_id(),$newxtime);
|
||||
|
||||
$arr = array('expire' => $xtime);
|
||||
call_hooks('new_cookie', $arr);
|
||||
|
||||
}
|
||||
|
||||
function extend_cookie() {
|
||||
|
||||
// if there's a long-term cookie, extend it
|
||||
|
||||
$xtime = (($_SESSION['remember_me']) ? (60 * 60 * 24 * 365) : 0 );
|
||||
|
||||
if($xtime)
|
||||
setcookie(session_name(),session_id(),(time() + $xtime));
|
||||
$arr = array('expire' => $xtime);
|
||||
call_hooks('extend_cookie', $arr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function return_check() {
|
||||
|
||||
// check a returning visitor against IP changes.
|
||||
// If the change results in being blocked from re-entry with the current cookie
|
||||
// nuke the session and logout.
|
||||
// Returning at all indicates the session is still valid.
|
||||
|
||||
// first check if we're enforcing that sessions can't change IP address
|
||||
// @todo what to do with IPv6 addresses
|
||||
|
||||
if($_SESSION['addr'] && $_SESSION['addr'] != $_SERVER['REMOTE_ADDR']) {
|
||||
logger('SECURITY: Session IP address changed: ' . $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
|
||||
|
||||
$partial1 = substr($_SESSION['addr'], 0, strrpos($_SESSION['addr'], '.'));
|
||||
$partial2 = substr($_SERVER['REMOTE_ADDR'], 0, strrpos($_SERVER['REMOTE_ADDR'], '.'));
|
||||
|
||||
$paranoia = intval(get_pconfig($_SESSION['uid'], 'system', 'paranoia'));
|
||||
|
||||
if(! $paranoia)
|
||||
$paranoia = intval(get_config('system', 'paranoia'));
|
||||
|
||||
switch($paranoia) {
|
||||
case 0:
|
||||
// no IP checking
|
||||
break;
|
||||
case 2:
|
||||
// check 2 octets
|
||||
$partial1 = substr($partial1, 0, strrpos($partial1, '.'));
|
||||
$partial2 = substr($partial2, 0, strrpos($partial2, '.'));
|
||||
if($partial1 == $partial2)
|
||||
break;
|
||||
case 1:
|
||||
// check 3 octets
|
||||
if($partial1 == $partial2)
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
// check any difference at all
|
||||
logger('Session address changed. Paranoid setting in effect, blocking session. '
|
||||
. $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
|
||||
self::nuke();
|
||||
goaway(z_root());
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
88
Zotlabs/Web/SessionHandler.php
Normal file
88
Zotlabs/Web/SessionHandler.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Web;
|
||||
|
||||
|
||||
class SessionHandler implements \SessionHandlerInterface {
|
||||
|
||||
|
||||
function open ($s, $n) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// IMPORTANT: if we read the session and it doesn't exist, create an empty record.
|
||||
// We rely on this due to differing PHP implementation of session_regenerate_id()
|
||||
// some which call read explicitly and some that do not. So we call it explicitly
|
||||
// just after sid regeneration to force a record to exist.
|
||||
|
||||
function read ($id) {
|
||||
|
||||
if($id) {
|
||||
$r = q("SELECT `data` FROM `session` WHERE `sid`= '%s'", dbesc($id));
|
||||
|
||||
if($r) {
|
||||
return $r[0]['data'];
|
||||
}
|
||||
else {
|
||||
q("INSERT INTO `session` (sid, expire) values ('%s', '%s')",
|
||||
dbesc($id),
|
||||
dbesc(time() + 300)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
function write ($id, $data) {
|
||||
|
||||
if(! $id || ! $data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unless we authenticate somehow, only keep a session for 5 minutes
|
||||
// The viewer can extend this by performing any web action using the
|
||||
// original cookie, but this allows us to cleanup the hundreds or
|
||||
// thousands of empty sessions left around from web crawlers which are
|
||||
// assigned cookies on each page that they never use.
|
||||
|
||||
$expire = time() + 300;
|
||||
|
||||
if($_SESSION) {
|
||||
if(array_key_exists('remember_me',$_SESSION) && intval($_SESSION['remember_me']))
|
||||
$expire = time() + (60 * 60 * 24 * 365);
|
||||
elseif(local_channel())
|
||||
$expire = time() + (60 * 60 * 24 * 3);
|
||||
elseif(remote_channel())
|
||||
$expire = time() + (60 * 60 * 24 * 1);
|
||||
}
|
||||
|
||||
q("UPDATE `session`
|
||||
SET `data` = '%s', `expire` = '%s' WHERE `sid` = '%s'",
|
||||
dbesc($data),
|
||||
dbesc($expire),
|
||||
dbesc($id)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function close() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function destroy ($id) {
|
||||
q("DELETE FROM `session` WHERE `sid` = '%s'", dbesc($id));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function gc($expire) {
|
||||
q("DELETE FROM session WHERE expire < %d", dbesc(time()));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -132,7 +132,7 @@ class Auth {
|
||||
// tell them to logout if they're logged in locally as anything but the target remote account
|
||||
// in which case just shut up because they don't need to be doing this at all.
|
||||
|
||||
if (get_app()->channel['channel_hash'] == $hubloc['xchan_hash']) {
|
||||
if (\App::$channel['channel_hash'] == $hubloc['xchan_hash']) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@ -242,9 +242,9 @@ class Auth {
|
||||
|
||||
$arr = array('xchan' => $hubloc, 'url' => $this->desturl, 'session' => $_SESSION);
|
||||
call_hooks('magic_auth_success',$arr);
|
||||
get_app()->set_observer($hubloc);
|
||||
\App::set_observer($hubloc);
|
||||
require_once('include/security.php');
|
||||
get_app()->set_groups(init_groups_visitor($_SESSION['visitor_id']));
|
||||
\App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
|
||||
info(sprintf( t('Welcome %s. Remote authentication successful.'),$hubloc['xchan_name']));
|
||||
logger('mod_zot: auth success from ' . $hubloc['xchan_addr']);
|
||||
$this->success = true;
|
||||
@ -341,5 +341,5 @@ class Auth {
|
||||
* Service_class can be used by cooperating sites to provide different access rights based on account rights and subscription plans. It is
|
||||
* a string whose contents are not defined by protocol. Example: "basic" or "gold".
|
||||
*
|
||||
* @param[in,out] App &$a
|
||||
* @param[in,out] \App &$a
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Zot;
|
||||
|
||||
class DReport {
|
||||
|
@ -41,9 +41,10 @@ class Receiver {
|
||||
if(! $this->messagetype)
|
||||
$this->error = true;
|
||||
|
||||
$this->sender = ((array_key_exists('sender',$this->data)) ? $this->data['sender'] : null);
|
||||
$this->recipients = ((array_key_exists('recipients',$this->data)) ? $this->data['recipients'] : null);
|
||||
|
||||
if($this->data) {
|
||||
$this->sender = ((array_key_exists('sender',$this->data)) ? $this->data['sender'] : null);
|
||||
$this->recipients = ((array_key_exists('recipients',$this->data)) ? $this->data['recipients'] : null);
|
||||
}
|
||||
|
||||
if($this->sender)
|
||||
$this->ValidateSender();
|
||||
|
42
Zotlabs/Zot/Verify.php
Normal file
42
Zotlabs/Zot/Verify.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Zot;
|
||||
|
||||
|
||||
class Verify {
|
||||
|
||||
function create($type,$channel_id,$token,$meta) {
|
||||
return q("insert into verify ( type, channel, token, meta, created ) values ( '%s', %d, '%s', '%s', '%s' )",
|
||||
dbesc($type),
|
||||
intval($channel_id),
|
||||
dbesc($token),
|
||||
dbesc($meta),
|
||||
dbesc(datetime_convert())
|
||||
);
|
||||
}
|
||||
|
||||
function match($type,$channel_id,$token,$meta) {
|
||||
$r = q("select id from verify where type = '%s' and channel = %d and token = '%s' and meta = '%s' limit 1",
|
||||
dbesc($type),
|
||||
intval($channel_id),
|
||||
dbesc($token),
|
||||
dbesc($meta)
|
||||
);
|
||||
if($r) {
|
||||
q("delete from verify where id = %d",
|
||||
intval($r[0]['id'])
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function purge($type,$interval) {
|
||||
q("delete from verify where type = '%s' and created < %s - INTERVAL %s",
|
||||
dbesc($type),
|
||||
db_utcnow(),
|
||||
db_quoteinterval($interval)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -2,9 +2,6 @@
|
||||
|
||||
namespace Zotlabs\Zot;
|
||||
|
||||
require_once('Zotlabs/Zot/IHandler.php');
|
||||
|
||||
|
||||
class ZotHandler implements IHandler {
|
||||
|
||||
function Ping() {
|
||||
|
@ -18,7 +18,7 @@ view/php/default.php
|
||||
<html>
|
||||
<head>
|
||||
<title><?php if(x($page,'title')) echo $page['title'] ?></title>
|
||||
<script>var baseurl="<?php echo $a->get_baseurl() ?>";</script>
|
||||
<script>var baseurl="<?php echo z_root() ?>";</script>
|
||||
<?php if(x($page,'htmlhead')) echo $page['htmlhead'] ?>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -38,7 +38,7 @@ Inside it, put the following information - edit as needed
|
||||
|
||||
function mytheme_init(&$a) {
|
||||
|
||||
$a->theme_info['extends'] = 'redbasic';
|
||||
App::$theme_info['extends'] = 'redbasic';
|
||||
|
||||
|
||||
}
|
||||
@ -63,7 +63,6 @@ In it, put the following:
|
||||
|
||||
That's it. This tells the software to read the PCSS information for the redbasic theme first, and then read our CSS file which will just consist of changes we want to make from our parent theme (redbasic).
|
||||
|
||||
|
||||
Now create the actual CSS file for your theme. Put it in view/theme/mytheme/css/style.css (where we just told the software to look for it). For our example, we'll just change the body background color so you can see that it works. You can use any CSS you'd like.
|
||||
|
||||
|
||||
@ -74,4 +73,29 @@ Now create the actual CSS file for your theme. Put it in view/theme/mytheme/css
|
||||
|
||||
You've just successfully created a derived theme. This needs to be enabled in the admin "themes" panel, and then anybody on the site can use it by selecting it in Settings->Display Settings as their default theme.
|
||||
|
||||
**Lesson 2**
|
||||
|
||||
If you want to use the redbasic schemas for your derived theme, you have to do a bit more.
|
||||
|
||||
Do everything as above, but don't create view/theme/mytheme/php/style.php, but copy instead view/theme/redbasic/php/style.php to view/theme/mytheme/php/style.php. Modify that file and remove (or comment out) these two lines:
|
||||
|
||||
if(local_channel() && App::$channel && App::$channel['channel_theme'] != 'redbasic')
|
||||
set_pconfig(local_channel(), 'redbasic', 'schema', '---');
|
||||
|
||||
Also add this line at the bottom:
|
||||
|
||||
echo @file_get_contents('view/theme/mytheme/css/style.css');
|
||||
|
||||
To show the schema selector you have to copy view/theme/redbasic/tpl/theme_settings.tpl to view/theme/mytheme/tpl/theme_settings.tpl. Modify that file and replace the lines:
|
||||
|
||||
{{if $theme == redbasic}}
|
||||
{{include file="field_select.tpl" field=$schema}}
|
||||
{{/if}}
|
||||
|
||||
with:
|
||||
|
||||
{{include file="field_select.tpl" field=$schema}}
|
||||
|
||||
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
||||
|
@ -57,9 +57,9 @@ Private messages are encrypted during transport and storage. In this day and age
|
||||
|
||||
This provides the ability to select posts by date ranges
|
||||
|
||||
**Collections Filter**
|
||||
**Privacy Group Filter**
|
||||
|
||||
Enable widget to display stream posts only from selected collections. This also toggles the outbound permissions while you are viewing a collection. This is analogous to Google "circles" or Disapora "aspects".
|
||||
Enable widget to display stream posts only from selected groups of connection. This also toggles the outbound permissions while you are viewing a privacy group. This is analogous to Google "circles" or Disapora "aspects".
|
||||
|
||||
**Saved Searches**
|
||||
|
||||
|
@ -12,7 +12,7 @@ There are certain scenarios where you might want your own directory-server that
|
||||
|
||||
* On the hub that will be the Directory Server, open the .htconfig.php file and set:
|
||||
|
||||
`$a->config['system']['directory_mode'] = DIRECTORY_MODE_PRIMARY;`
|
||||
`App::$config['system']['directory_mode'] = DIRECTORY_MODE_PRIMARY;`
|
||||
|
||||
|
||||
By default it should already be set as **DIRECTORY_MODE_NORMAL**, so just edit that line to say **DIRECTORY_MODE_PRIMARY**
|
||||
|
@ -48,10 +48,9 @@ Content (especially status posts) that you share with other networks or that you
|
||||
|
||||
Comments to posts that were created by others and posts which are designated as forum posts belong to you as the creator/author, but the distribution of these posts is not under your direct control. These posts/comments MAY be re-distributed to others, and MAY be visible to anybody on the internet. In the case of comments, the creator of the "first message" in the thread to which you are replying controls the distribution of all comments and replies to that message.
|
||||
|
||||
|
||||
**Private Information**
|
||||
|
||||
$Projectname developers will ensure that any content you provide which is designated as PRIVATE will be protected against eavesdropping - to the best of their ability. Private content is generally hidden or obscured even from hub administrators. It is also stripped from email notifications. It is difficult but NOT impossible for this content to be seen by a hub administrator. End to end encryption is provided as an optional feature and this CANNOT be seen, even by a determined administrator.
|
||||
$Projectname developers will ensure that any content you provide which is designated as PRIVATE will be protected against eavesdropping - to the best of their ability. Private channel content CAN be seen in the database of every involved hub administrator, but private messages are obscured in the database. The latter means that it is very difficult, but NOT impossible for this content to be seen by a hub administrator. Private channel content and private messages are also stripped from email notifications. End to end encryption is provided as an optional feature and this CANNOT be seen, even by a determined administrator.
|
||||
|
||||
##Identity Privacy
|
||||
|
||||
|
@ -11,9 +11,9 @@ When you start to mention somebody, it will create an auto-complete box to selec
|
||||
|
||||
**Private Mentions**
|
||||
|
||||
If you wish to restrict a post to a single person or a number of people, you can do this by selecting channels or collections from the privacy tool. You can also just tag them with a privacy tag. A privacy tag is a name preceded by the two characters @! - and in addition to tagging these channels, will also change the privacy permissions of the post to include them (and perhaps restrict the post from "everybody" if this was the default). You can have more than one privacy tag, for instance @!bob and @!linda will send the post only to Bob and Linda (in addition to any recipients you selected with the privacy selector - if any).
|
||||
If you wish to restrict a post to a single person or a number of people, you can do this by selecting channels or privacy groups from the privacy tool. You can also just tag them with a privacy tag. A privacy tag is a name preceded by the two characters @! - and in addition to tagging these channels, will also change the privacy permissions of the post to include them (and perhaps restrict the post from "everybody" if this was the default). You can have more than one privacy tag, for instance @!bob and @!linda will send the post only to Bob and Linda (in addition to any recipients you selected with the privacy selector - if any).
|
||||
|
||||
You may also tag public collections. When you create or edit a collection, there is a checkbox to allow the group members to be seen by others. If this box is checked for a collection and you tag (for instance) @!Friends - the post will be restricted to the Friends collection. Check that the collection is public before doing this - as there is no way to take back a post except to delete it. The collection name will appear in the post and will alert members of that collection that they are members of it.
|
||||
You may also tag privacy groups which are "public". When you create or edit a privacy group, there is a checkbox to allow the group members to be seen by others. If this box is checked for a group and you tag (for instance) @!Friends - the post will be restricted to the Friends group. Check that the group is public before doing this - as there is no way to take back a post except to delete it. The group name will appear in the post and will alert members of that group that they are members of it.
|
||||
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@ Some/many of these widgets have restrictions which may restrict the type of page
|
||||
* args: count - number of items to return (default 24)
|
||||
<br /> <br />
|
||||
|
||||
* collections - collection selector for the current logged in channel
|
||||
* collections - privacy group selector for the current logged in channel
|
||||
|
||||
* args: mode - one of "conversation", "group", "abook" depending on module
|
||||
<br /> <br />
|
||||
@ -74,8 +74,11 @@ Some/many of these widgets have restrictions which may restrict the type of page
|
||||
|
||||
* suggestedchats - "interesting" chatrooms chosen for the current observer
|
||||
|
||||
* item - displays a single webpage item by mid
|
||||
* args: mid - message_id of webpage to display (must be webpage, not a conversation item)
|
||||
* item - displays a single webpage item by mid or page title
|
||||
* args:
|
||||
* channel_id - channel that owns the content, defualt is the profile_uid
|
||||
* mid - message_id of webpage to display (must be webpage, not a conversation item)
|
||||
* title - URL page title of webpage (must provide one of either title or mid)
|
||||
<br /> <br />
|
||||
|
||||
* photo - display a single photo
|
||||
@ -85,6 +88,13 @@ Some/many of these widgets have restrictions which may restrict the type of page
|
||||
* style - CSS style string
|
||||
<br /> <br />
|
||||
|
||||
* cover_photo - display the cover photo for the selected channel
|
||||
* args:
|
||||
* channel_id - channel to use, default is the profile_uid
|
||||
* style - CSS style string (default is dynamically resized to width of region)
|
||||
<br /> <br />
|
||||
|
||||
|
||||
* photo_rand - display a random photo from one of your photo albums. Photo permissions are honoured
|
||||
* args:
|
||||
* album - album name (very strongly recommended if you have lots of photos)
|
||||
|
@ -1,19 +1,22 @@
|
||||
[h3]Plugins/Addons[/h3]
|
||||
[list=1]
|
||||
[*] abcjsplugin - Create musical scores in your posts
|
||||
[*] adultphotoflag - prevents nsfw photos from being displayed in public albums
|
||||
[*] bbmath - use complex math expressions in your posts
|
||||
[*] bookmarker - replace #^ with bookmark link in posts
|
||||
[*] buglink - provide a bug reporting icon in the lower-left corner of every page
|
||||
[*] calc - a scientific calculator
|
||||
[*] chess - cross domain identity aware interactive chess games
|
||||
[*] chords - generate fingering charts and alternatives for every known guitar chord
|
||||
[*] custom_home - set a custom page as the hub start page
|
||||
[*] diaspora - crosspost to a Diaspora account (different from the built-in Diaspora emulator)
|
||||
[*] dfedfix - fixes some federation issues with Diaspora releases around aug-sep 2015
|
||||
[*] diaspora - Diaspora protocol emulator
|
||||
[*] diaspost - crosspost to a Diaspora account (different from the Diaspora protocol emulator)
|
||||
[*] dirstats - show some interesting statistics generated by the driectory server
|
||||
[*] donate - provides a project donation page
|
||||
[*] dwpost - crosspost to Dreamwidth
|
||||
[*] embedly - use the embedly (formerly ooehmbed) service to embed media from many providers
|
||||
[*] extcron - use an external cron service to run your hub's scheduled tasks
|
||||
[*] flattr - provides a "Flattr Us" button
|
||||
[*] flattrwidget - provides a "Flattr Us" button
|
||||
[*] flip - create upside down text
|
||||
[*] fortunate - displays random quote (fortune cookie). Requires setting up a fortune server.
|
||||
[*] frphotos - import photo albums from Friendica
|
||||
@ -26,12 +29,16 @@
|
||||
[*] libertree - crosspost to Libertree
|
||||
[*] likebanner - create a "like us on red#matrix" banner image
|
||||
[*] ljpost - crosspost to LiveJournal
|
||||
[*] logrot - logfile rotation utility
|
||||
[*] mahjongg - Chinese puzzle game
|
||||
[*] mailhost - when using multiple channel clones, select one to receive email notifications
|
||||
[*] mayan_places - set location field to a random city in the Mayan world
|
||||
[*] morechoice - additional gender/sexual-preference choices for profiles (not safe for work)
|
||||
[*] moremoods - Additional mood options
|
||||
[*] morepokes - additional poke options (not safe for work)
|
||||
[*] msgfooter - provide legal or other text on each outgoing post
|
||||
[*] noembed - use noembed.com as an addition to Hubzilla's native oembed functionality (currently broken)
|
||||
[*] nofed - prevent "federation" of channel posts, maintains all interaction on your site
|
||||
[*] nsabait - add random terrorism related hashtags to your posts
|
||||
[*] nsfw - Highly recommended plugin to collpase posts with inappropriate content
|
||||
[*] openclipatar - choose a profile photo from hundreds of royalty free images
|
||||
@ -42,21 +49,29 @@
|
||||
[*] qrator - generate QR code images
|
||||
[*] rainbowtag - display your tag and category clouds in colours
|
||||
[*] randpost - post/reply bot based on and requires fortunate
|
||||
[*] redfiles - import file storage from redmatrix
|
||||
[*] redphotos - import photo albums from redmatrix
|
||||
[*] redred - Crosspost to another Red Matrix or Hubzilla channel
|
||||
[*] rtof - Crosspost to Friendica
|
||||
[*] sendzid - add 'zid' auth parmaters to all outbound links, not just in-network links
|
||||
[*] skeleton - sample addon/plugin to demonstrate plugin development
|
||||
[*] smiley_pack - extend the built-in smilie (emoticon) support
|
||||
[*] smileybutton - provides a smiley selector on the post window
|
||||
[*] startpage - set a personal preferred page to redirect after logging in.
|
||||
[*] statistics_json - Diaspora statistics generator
|
||||
[*] statusnet - GNU-social and StatusNet crosspost [zrl=[baseurl]/help/addons_gnusocial]Posting To Gnu Social[/zrl]
|
||||
[*] superblock - Highly recommended - completely block an offensive channel from your stream
|
||||
[*] testdrive - Turns your hub into a test drive site with accounts that expire after a trail period.
|
||||
[*] tictac - 3D tic-tac-toe
|
||||
[*] torch - flashlight app
|
||||
[*] tour - feature tour for new members
|
||||
[*] twitter - crosspost to Twitter
|
||||
[*] upload_limits - discover what server setting (there are a few) may be causing large photo uploads to fail
|
||||
[*] visage - show visitors to your channel
|
||||
[*] wholikesme - provides a page to display what connections have 'liked' your posts the most
|
||||
[*] webRTC - use an external server (mayfirst.org) to negotiate webRTC hookups
|
||||
[*] wppost - crosspost to WordPress (or other wordpress XMLRPC service)
|
||||
[*] xmpp - XMPP chat based on converse.js
|
||||
[/list]
|
||||
|
||||
[h3]Addon Repositories[/h3]
|
||||
|
78
doc/ca/Privacy.md
Normal file
78
doc/ca/Privacy.md
Normal file
@ -0,0 +1,78 @@
|
||||
Política de Privacitat
|
||||
======================
|
||||
|
||||
|
||||
##Sumari##
|
||||
|
||||
|
||||
Q: Qui pot veure el meu contingut?
|
||||
|
||||
A: Per defecte TOTHOM A INTERNET, EXCEPTE que ho hagis restringit. $Projectname permet te triar el nivell de privacitat que desitgis. El contingut restringit no serà visible als "espies de la xarxa " ni als anunciants. Estarà protegit contra l'espionatge per estranys - de la millor manera que sabem. Administradors de nodes amb habilitats i paciència suficients poden ser capaços d'espiar a algunes comunicacions privades però han de invertir molt esforç per fer-ho. Hi maneres de Privacitat en $Projectname que són fins i tot resistents a escoltes il·legals pels administradors de nodes hàbils i decidits.
|
||||
|
||||
Q: Pot el meu contingut ser censurat?
|
||||
|
||||
A: $Projectname (la xarxa de nodes) NO POT censurat el teu contingut. Els administradors de servidor i del node estan subjectes a les lleis locals i poden suprimir contingut censurable des del seu lloc/node. Qualsevol POT convertir-se en un administrador de node, inclòs tu; i per tant publicar contingut que d'altra manera podria ser censurat. Encara i això estaràs subjecte a les teves lleis locals. Es la teva decisió.
|
||||
|
||||
|
||||
##Definicions
|
||||
|
||||
**$Projectname**
|
||||
|
||||
Coneguda d'un altre forma com "la xarxa", Hubzilla és una col·lecció d'equips individuals/servidors (àlies nodes) que connecten entre si per formar una xarxa cooperativa més gran.
|
||||
|
||||
**node (hub)**
|
||||
|
||||
Un equip individual o un servidor connectat a $Projectname. Aquests són proporcionats per un **administrador del node** i poden ser públics o privats, de pagament o gratuïts.
|
||||
|
||||
**administrador del node**
|
||||
|
||||
L'operador del sistema d'un node individual.
|
||||
|
||||
##Polítiques
|
||||
|
||||
**Informació Pública**
|
||||
|
||||
Qualsevol informació o cualsevol cosa publicada per tu a $Projectname POT ser pública o visible a qualsevol a Internet. En la mesura que sigui possible, $Projectname te permet protegir el contingut i restringir qui pot veure-ho.
|
||||
|
||||
La teva foto de perfil, el nom del teu canal, i la ubicació (URL o adreça de xarxa) del seu canal són visibles per a qualsevol persona a Internet i els controls de privacitat no afectaràn la visualització d'aquests elements.
|
||||
|
||||
POTS proporcionar, a més, un altra informació de perfil. Qualsevol informació que proporcionis en el teu perfil públic **per defecte** POT ser transmesa a altres centres en $Projectname i, a més, és possible que aparegui en el directori del canal. POTS restringir la visualització d'aquesta informació de perfil. Es POT restringir (permets que visualitzin), només als membres del teu nucli, o només les connexions (amics), o altres conjunts limitats de espectadors com desitgis. Si vols que el teu perfil estigui restringit, has d'establir la configuració de privacitat adequada, o simplement NO PROPORCIONIS informació addicional.
|
||||
|
||||
**Contingut**
|
||||
|
||||
El contingut que proporciones (missatges d'estat, fotos, arxius, etc.) et pertany a tu. Per defecte a $Projectname és publica contingut de forma oberta i visible per qualsevol en internet (PÚBLIC). POTS controlar això a la seva configuració del canal i restringir els permisos per defecte o pot restringir la visibilitat de qualsevol article únic publicat per separat (PRIVAT). Els desenvolupadors $Projectname s'han d'assegurat que el contingut restringit és visible NOMÉs per als que estan a la llista d'autoritzats - han emprat el millor d'ells per això.
|
||||
|
||||
El contingut (especialment les entrades d'estat) que es comparteixen amb altres xarxes o que has fet visible a qualsevol a Internet (PÚBLIC) no poden ser retirats (esborrats) fàcilment un cop que ha estat publicats. Pot haver estat compartit amb altres xarxes i posat a disposició a través de feeds RSS/Atom. També pot haver estat sindicat en altres llocs $Projectname. Pot aparèixer en les xarxes d'espionatge i recerques a Internet. Si no desitges aquest comportament per defecte, si et plau, ajusta la configuració del canal i restringeix qui pot veure el teu contingut.
|
||||
|
||||
**Comentaris i entrades a Forums**
|
||||
|
||||
Els comentaris als llocs que es van crear per altres i entrades que es designen com missatges al fòrum pertanyen tant a tu com al creador/autor, però la distribució d'aquests llocs no està sota el teu control directe. Aquestes entrades/comentaris es poden tornar a distribuir als altres, i pot ser visible per qualsevol en internet. En el cas dels comentaris, el creador del "primer missatge" al fil al qual està responent controla la distribució de tots els comentaris i respostes a aquest missatge.
|
||||
|
||||
|
||||
**Informació Privada**
|
||||
|
||||
Els desenvolupadors de $Projectname aseguraràn que cualsevol contingut que creis designat com PRIVAT estarà protegit contra estaràn protegits contra les escoltes - han emprat el millor d'ells per això. El contingut privat generalment s'amaga o enfosqueix fins i tot als administradors de nodes. També s'eliminen les notificacions per correu electrònic. És difícil, però no impossible que aquest contingut sigui vist per un administrador de node. El xifrat extrem a extrem es facilita com una característica opcional i fa el contingut, NO VISIBLE, fins i tot per un administrador determinat a veure'l.
|
||||
|
||||
##Privacitat de la Identitat
|
||||
|
||||
La Privacitat per la teva identitat és un altre aspecte. En tenir una identitat descentralitzada a $Projectname, la seva privacitat s'estén més enllà del seu node d'inici. Si vols tenir el control complet de la teva privacitat i seguretat has d'executar el teu propi centre en un servidor dedicat. Per a moltes persones, això és complicat i pot esgotar les seves habilitats tècniques. Així que anem a enumerar algunes precaucions que pots fer per assegurar la teva privacitat tant com sigui possible.
|
||||
|
||||
Una identitat descentralitzat té molts avantatges i te dóna un munt de característiques interessants, però has de ser conscient del fet que la teva identitat és coneguda per altres centres de la xarxa $Projectname. Un d'aquests avantatges és que altres canals poden servir contingut personalitzat i permetrà veure el contingut privat (com fotos privades que altres volen compartir amb vostè). Per això els canals necessiten saber qui ets. Però entenem que de vegades aquests altres canals en saben més de tu del que pugui desitjar. Per exemple, el plug-in Visage pot dir-li al propietari d'un canal l'última vegada que vas visitar el seu perfil. Pots renunciar fàcilment a aquest baix nivell de seguiment, que creiem inofensiu.
|
||||
|
||||
* Pots activar [No Em Segueixis (anglès:Do Not Track (DNT))](http://donottrack.us/) al teu navegador web. Respectem aquesta nova política de privacitat proposada. Tots en navegadors moderns soporten DNT. Trobaràs als ajustos de privacitat del teu navegador web o sino pots consultar el manual del navegador. Això no afectarà la funcionalitat de $Projectname. Aquest ajust, segurament, es suficient per la majoria de la gent.
|
||||
|
||||
* Pots [deshabilitar publicacions](ajustos) del teu canal al nostre canal de directoris. Si vols que la gent trobi el teu canal, has de facilitar la teva direcció del canal a ell(a). Pensem que això es un bon indicador que, en aquest cas, vols es un extra de privacitat i automaticament s'activarà "No Em Segueixis" (DNT).
|
||||
|
||||
* Pots tenir un node blocat. Això significa que tots els canals i contingut en aquest node no es públic i invisible al món exterior. Això és quelcom que només ho pot fer l'administrador del teu node. També es respecta això i automàticament s'activa DNT si és sel·leccionat.
|
||||
|
||||
###Censura
|
||||
|
||||
$Projectname és una xarxa global que inclou a totes les religions i cultures. Això no implica que tots els membres de la xarxa pensin de la mateixa manera que tu pel que fa en temes polèmics, i algunes persones poden sentir una forta oposició al contingut que publiquis. En general, si desitjes publicar alguna cosa que saps que no és universalment acceptable, el millor enfocament consisteix a restringir l'audiència utilitzant els controls de privacitat a un petit cercle d'amics.
|
||||
|
||||
$Projectname com un proveïdor de la xarxa no pot censurar el contingut. No obstant això, els administradors de node poden censurar qualsevol contingut que apareix en el seu centre per complir amb les lleis locals o fins i tot el seu judici personal. La seva decisió serà inapel·lable. Si té problemes amb qualsevol administrador de node, pots moure el teu compte i publicacions a un altre lloc que estigui més d'acord amb les teves expectatives. Si us plau comprova (periòdicament) les [Condicions d'ús](help/TermsOfService) del teu centre per aprendre sobre les normes o directrius. Si el teu contingut consisteix en un material que és il·legal o que pugui causar problemes, es recomana ENCARIDAMENT a allotjar tu mateix (convertir-te en un administrador de node). Podràs trobar que el teu contingut està bloquejat en alguns centres, però $Projectname, com a xarxa, no pot bloquejar una vegada publicat.
|
||||
|
||||
$Projectname RECOMANA que els administradors de nodes ofereixin un període de gràcia de 1-2 dies entre advertir al titular d'un compte, que hi ha contingut que ha de ser eliminat, i l'eliminació física o desactivació del compte. Això li donarà al propietari del contingut l'oportunitat d'exportar els seus canal de meta-dades i importar-lo a un altre lloc. En rares ocasions el contingut pot ser de tal naturalesa que es justifiqui l'eliminació immediata del compte. Aquesta és una decisió del node, no és una decisió de $Projectname.
|
||||
|
||||
Si normalment i regularment publiques contingut per a adults o de caràcter ofensiu, es recomana ENCARIDAMENT que marquis el compte com "NSFW" (No segur per al treball). Això evitarà que es mostri la teva foto de perfil al directori, excepte per als espectadors que han optat per desactivar el "mode segur". Si la teva foto de perfil es considera per a adults o ofensiu pels administradors de directori, l'administrador del directori POT marcar la teva foto de perfil com NSFW. Actualment no hi ha un sistema oficial per revertir aquesta decisió. Així DEURIES marcar tu mateix, el teu compte, com a NSFW si és probable que no sigui apropiat per a audiències generals.
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
8
doc/ca/TermsOfService.md
Normal file
8
doc/ca/TermsOfService.md
Normal file
@ -0,0 +1,8 @@
|
||||
Termes del Servei
|
||||
================
|
||||
Aquest node Hubzilla encara no te Termes del Servei. Estic buscant un model adient.....
|
||||
En resum empreu el servei respectant els altres i no cometeu il·legalitats. Aquest node no s'identifica amb les opinions dels usuaris ni es responsablilitza de les mateixes.
|
||||
|
||||
|
||||
#include doc/SiteTOS.md;
|
||||
|
27
doc/ca/about.bb
Normal file
27
doc/ca/about.bb
Normal file
@ -0,0 +1,27 @@
|
||||
[b]Que és[/b]
|
||||
|
||||
$Projectname és una xarxa de comunicacions descentralitzades, que permet comunicacions lliures de censura, amb privacitat, i per tant lliure de les urpes opressores de gegants contemporanis de comunicació corporativa. Aquests gegants funcionen principalment com xarxes d''espionatge per a cobrar a clients de totes les classes i tipus, a més de monopolitzar i centralitzar Internet; una característica que no formava part dels objectius originals i revolucionàries que van produir la World Wide Web.
|
||||
|
||||
$Projectname és gratuït i de codi obert. Està dissenyat per a creixèr des de una raspberry pi de 35€, fins el màxim de la gama de servidors AMD i servidors empresarials de múltiples nuclis que funcionen amb Intel Xeon. Pot ser utilitzat per a suportar la comunicació entre uns pocs individus, o l'escalar a molts milers i més.
|
||||
|
||||
$Projectname pretén ser àgil i capaç de treballar amb múltiples recursos informàtics. És fàcil d'utilitzar pels usuaris habituals d''ordinadors, així com per administradors de sistemes i desenvolupadors.
|
||||
|
||||
|
||||
La forma d'utilitzar depèn de com voleu utilitzar-lo.
|
||||
|
||||
Està escrit en el llenguatge de scripting PHP, pel que és trivial instal·lar-lo en qualsevol plataforma d'allotjament en ús avui en dia. Això inclou l'auto-allotjament a casa, en els proveïdors d'allotjament, com ara [url=http://mediatemple.com/]Media Temple[/url] i [url=http://www.dreamhost.com/]Dreamhost[/url], o en servidors virtuals i dedicats, oferts per gràcia de [url=https://www.linode.com]Linode[/url], [url=http://greenqloud.com]GreenQloud[/url] o [url=https://aws.amazon.com]Amazon AWS[/url].
|
||||
|
||||
|
||||
En altres paraules, $Projectname es pot executar en qualsevol plataforma informàtica que vingui amb un servidor web, una base de dades compatible amb MySQL i el llenguatge de scripting PHP.
|
||||
|
||||
|
||||
|
||||
De pas, $Projectname ofereix una sèrie de atractius únics:
|
||||
|
||||
[b]Identificació amb un sol clic d'usuari:[/b] vol dir que pot accedir a llocs en $Projectname simplement fent clic als enllaços a llocs remots. L''autenticació passa automàgicament en segon plà. Oblida't de recordar múltiples noms d'usuari amb múltiples contrasenyes en accedir a diferents llocs en línia.
|
||||
|
||||
[b]La clonació:[/b] de les identitats en línia. La seva presència en línia ja no ha d'estar lligat a un sol servidor, nom de domini o adreça IP. Pot clonar i importar la seva identitat (o canal com en diem) a un altre servidor (o, en un concentrasor com son coneguts els servidors a $Projectname). Ara, si el seu concentrador/servidor cau, no et preocupis, els teus contactes, missatges [i]*[/i], i els missatges de [i]*[/i] automàgicament segueixen estant disponibles i accessibles al seu canal clonat. [i](*: només es perden els missatges i els missatges a partir del moment en que va clonar el seu canal)[/i]
|
||||
|
||||
[b]Privacitat:[/b] les identitats a $Projectname (Zot identificadors) es poden eliminar, salvar/descarregar i clonar. L'usuari té el control total de les seves dades. Si vostè decideix esborrar tot el seu contingut i esborrar la seva ID Zot, tot el que has de fer és fer clic a un enllaç i s'eliminen immediatament d concentrador/servidor. No hi ha preguntes, sense problemes.
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
19
doc/ca/accounts_profiles_channels_basics.bb
Normal file
19
doc/ca/accounts_profiles_channels_basics.bb
Normal file
@ -0,0 +1,19 @@
|
||||
[size=large][b]Comptes, Perfils i Canals[/b][/size]
|
||||
|
||||
Una vegada t'has registrat amb un [i]compte[/i] al servei, també has de crear un [i]perfil[/i] i un [i]canal[/i].
|
||||
|
||||
[b]Compte[/b]
|
||||
Tens i]un[/i] compte. Això consisteix en una adreça de correu electrònic i una contrasenya. Amb el teu compte pots accedit al teu perfil i al teu canal.
|
||||
[i]Pensa en el teu compte com una via per autenticar-te al teu lloc $Projectname. Et permet fer coses com, crear perfils i canals amb els que podràs amb altres persones.[/i]
|
||||
|
||||
[b]Perfil[/b]
|
||||
Segurament t'has registrat a altres serveis a internet, com fòrums, o comunicacions en línia. Per a tots ells proveeixes alguna informació de tu, data de naixement, país, edat, i que es el que d'agrada. [observer=1]If you like you can see your profile here: [baseurl]/profile/[observer.webname] and edit it by clicking on the pencil icon next to your avatar image. [/observer]
|
||||
Unlike other services $Projectname offers you the advantage of creating [i]many more profiles[/i]. That way you are able to distinguish between profiles targeted specially at everyone (your public profile), your work mates, your family and your partner.
|
||||
[i]Think of your profile as the basic information about yourself you tell other people.[/i]
|
||||
|
||||
[b]Channel[/b]
|
||||
During the registration you created your first [i]channel[/i]. Yes, besides several profiles you are able to have several channels. This might be a bit confusing in the beginning, but let's clear things up. You already have created one channel. You can use this one for the public, to communicate with people about every day life. But perhaps you are an avid book reader and many people are bored by that. So you open a [i]second channel[/i] just for the book lovers, where you all can talk about books as much as you like. Obviously this is a new stream of posts, with a new profile (... or new profile[i]s[/i] ...) and completely different contacts. Some connections might exist in both channels, but there will be some that are exclusive to only one of both. You yourself just switch between both of them just like you would in real life switch when talking to people you meet on the street or people you meet specially to talk about books. You can even connect to yourself, or better: to your other channel. :)
|
||||
[i]Think of a channel as different spaces dedicated to different topics where you meet with different people.[/i]
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
||||
|
15
doc/ca/admins.bb
Normal file
15
doc/ca/admins.bb
Normal file
@ -0,0 +1,15 @@
|
||||
[h2]Documentació per a Administradors de Concentradors (dits Hubs en anglès)[/h2]
|
||||
|
||||
[h3]Administradors[/h3]
|
||||
|
||||
[zrl=[baseurl]/help/install]Instal·lació[/zrl]
|
||||
[zrl=[baseurl]/help/red2pi]Instal·lant $Projectname en una Raspberry Pi[/zrl]
|
||||
[zrl=[baseurl]/help/Hubzilla_on_OpenShift]$Projectname en OpenShift[/zrl]
|
||||
[zrl=[baseurl]/help/troubleshooting]Consells per solucionar problemes[/zrl]
|
||||
[zrl=[baseurl]/help/hidden_configs]Afinant Configuracions ocultes de $Projectname[/zrl]
|
||||
[zrl=[baseurl]/help/faq_admins]FAQ Per als Administradors[/zrl]
|
||||
[zrl=[baseurl]/help/service_classes]Classes de Serveis[/zrl]
|
||||
[zrl=[baseurl]/help/directories]Treballant amb i configuració de directoris[/zrl]
|
||||
[zrl=[baseurl]/help/theme_management]Gestió de Temes[/zrl]
|
||||
|
||||
|
32
doc/ca/channels.bb
Normal file
32
doc/ca/channels.bb
Normal file
@ -0,0 +1,32 @@
|
||||
[b]Canals[/b]
|
||||
|
||||
|
||||
|
||||
Els canals són simplement col·leccions de continguts emmagatzemats en un sol lloc. Un canal pot representar qualsevol cosa. Podria representi, un lloc web, un fòrum, àlbums de fotos, qualsevol cosa. Per a la majoria de la gent, el seu primer canal serà "Ell" mateix.
|
||||
|
||||
Les característiques més importants d'un canal que "em" representa són:
|
||||
|
||||
Comunicacions segures i privades "lliures d'spam"
|
||||
|
||||
Identitat i "un sol inici de sessió " a través de tota la xarxa
|
||||
|
||||
Controls de privacitat i permisos que s'estenen a tota la xarxa
|
||||
|
||||
Serveis de directori (com una guia telefònica)
|
||||
|
||||
En resum, una cadena que et representa a tú mateix és "jo, a l'Internet ".
|
||||
|
||||
Hauràs de crear el teu primer canal com a part del procés de registre. També pots crear canals additonal des del menú "Selecciona canal ".
|
||||
|
||||
Se li demanarà que proporcioni un nom de canal, i un curt sobrenom. Per a un canal que et representa a tu mateix, és una bona idea utilitzar el teu nom real per assegurar-se que els teus amics puguin trobar-te, i connectar al teu canal. El sobrenom curt s'utilitzarà per generar un nom "intermediari". Això és una mica com un nom d'usuari, i es veurà com una adreça de correu electrònic, prenent forma sobrenom@domini. Has de pensar una mica en que desitges utilitzar aquí. Imagina a algú demanant la teu nom intermediari i haver de dir-los que és "Crema-miss_issipi.123". "cremamississipi" seria una opció molt millor.
|
||||
|
||||
Una vegada que hagis creat el teu canal, se't portarà a la pàgina de configuració, que permet definir el teu canal, i establir els teus permisos predeterminats.
|
||||
|
||||
Un cop fet això, el canal està llest per utilitzar. En [observer=1][observer.url][/observer][observer=0]example.com/channel/username[/observer] trobaràs el teu canal de "flux". Aquí és on apareixerà la teva activitat recent, en ordre cronològic invers. Si publica a la casella "compartir", apareixerà l'entrada a la part superior del teu flux. També trobaràs enllaços a totes les altres àrees de comunicació per aquest canal. El fitxa "en quant a " conté el teu "perfil", la pàgina de fotos conté àlbums de fotos, i la pàgina d'esdeveniments conté esdeveniments compartits per tu i els teus contactes.
|
||||
|
||||
La pàgina "Xarxa" conté tots els missatges recents de tota la xarxa $Projectname, de nou amb sentit cronològic invers. Els missatges exactes que apareixen aquí depenen en gran mesura dels teus permisos. En la teva forma més permissiva, rebràs missatges de desconeguts. A l'altre extrem de l'escala, podràs veure els missatges de només els seus amics - o si ets realment antisocial, només els teus propis missatges.
|
||||
|
||||
Com s'ha esmentat al principi, són possibles molts altres tipus de canal, però, el procediment de creació és el mateix. La diferència entre els canals es troba principalment en els permisos assignats. Per exemple, una cadena per a l'intercanvi de documents amb els seus col.legues a la feina, és millor si canvieu valors més permissius per "Em pot escriure en el meu" públic "magatzem d'arxius ", que un compte personal. Per obtenir més informació, consulteu la secció de permisos.
|
||||
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
34
doc/ca/develop.bb
Normal file
34
doc/ca/develop.bb
Normal file
@ -0,0 +1,34 @@
|
||||
[h2]Documentació per Desenvolupadors[/h2]
|
||||
|
||||
[h3]Documentació Tècnica[/h3]
|
||||
[zrl=[baseurl]/help/Zot---A-High-Level-Overview]Una vista en profunditat a Zot[/zrl]
|
||||
[zrl=[baseurl]/help/zot]Una introducció a Zot[/zrl]
|
||||
[zrl=[baseurl]/help/zot_structures]Estuctures a Zot[/zrl]
|
||||
[zrl=[baseurl]/help/comanche]Descripcions de Pàgina a Comanche[/zrl]
|
||||
[zrl=[baseurl]/help/Creating-Templates]Creant Plantilles a Comanche[/zrl]
|
||||
[zrl=[baseurl]/help/Widgets]Artilugis[/zrl]
|
||||
[zrl=[baseurl]/help/plugins]Complements[/zrl]
|
||||
[zrl=[baseurl]/help/hooklist]Ganxos (detallat - en construcció)[/zrl]
|
||||
[zrl=[baseurl]/help/doco]Documentació[/zrl]
|
||||
[zrl=[baseurl]/help/DerivedTheme1]Creant Temes Derivats[/zrl]
|
||||
[zrl=[baseurl]/help/schema_development]Esquemes[/zrl]
|
||||
[zrl=[baseurl]/help/Translations]Traduccions[/zrl]
|
||||
[zrl=[baseurl]/help/developers]Desenvolupadors[/zrl]
|
||||
[zrl=[baseurl]/help/intro_for_developers]Introducció per Desenvolupadors[/zrl]
|
||||
[zrl=[baseurl]/help/database]Documentació del esquema de la base de dades[/zrl]
|
||||
[zrl=[baseurl]/help/api_functions]Funcions de la API[/zrl]
|
||||
[zrl=[baseurl]/help/api_posting]Entrades a $Projectname emprant la API[/zrl]
|
||||
[zrl=[baseurl]/help/developer_function_primer]Funcions Red 101[/zrl]
|
||||
[zrl=[baseurl]/doc/html/]Refrència del Codi (Doxygen generat - ajust de cookies)[/zrl]
|
||||
[zrl=[baseurl]/help/to_do_doco]Llista de Pendents per a la Documentació del Projecte $Projectname[/zrl]
|
||||
[zrl=[baseurl]/help/to_do_code]Llista de Pendents per a Desenvolupadors[/zrl]
|
||||
[zrl=[baseurl]/help/roadmap]Full de ruta[/zrl]
|
||||
[zrl=[baseurl]/help/git_for_non_developers]Git per a No-Desenvolupadors[/zrl]
|
||||
[zrl=[baseurl]/help/dev_beginner]Manual pas-a-pas per a desenvolupadors principiants[/zrl]
|
||||
|
||||
[h3]Preguntes Més Freqüents (FAQ) Per Desenvolupadors[/h3]
|
||||
[zrl=[baseurl]/help/faq_developers]FAQ Per Desenvoupadors[/zrl]
|
||||
|
||||
[h3]Recursos Externs[/h3]
|
||||
[url=https://zothub.com/channel/one]Development Channel[/url]
|
||||
[url=https://federated.social/channel/postgres]Postgres-specific $Projectname Admin Support Channel[/url]
|
202
doc/ca/features.bb
Normal file
202
doc/ca/features.bb
Normal file
@ -0,0 +1,202 @@
|
||||
[b][size=36]Característiques[/size][/b]
|
||||
|
||||
[b][size=24]$Projectname en Poques Paraules[/size][/b]
|
||||
|
||||
TL;DR
|
||||
|
||||
$Projectname proveeix publicacions i comunicacions socials distribuïdes amb [b]permisos descentralitzats[/b].
|
||||
|
||||
Així, que vol dir "permisos descentralitzats"? Em donen la habilitat de compàrtir quelcom al meu lloc web (fotos, mitjans, arxius, pàgines web, etc.) Aamb persones específiques en llocs completament diferents - encara que no necesàriament amb [i]tothom[/i] en aquests llocs web; i no es necessita tenir un usuari i contrasenya en aquests altres llocs web per poder fer-ho ni per poder tafanejar el que ells han compartit amb mi. Ells tenen un usuari i contrasenya al seu lloc web i "màgica autenticació" entre llocs web afiliats a la xarxa. També, al esser centralitzat, no hi ha terceres parts que puguin saltar-se els permisos i veure el que estàs fent a la xarxa.
|
||||
|
||||
$Projectname combina moltes característiques dels blocs tradicionals, les xarxes socials i els mitjans de comunicació, sistemes de gestió de continguts i emmagatzematge en el núvol personal en un marc de treball fàcil d'utilitzar. Cada node de la xarxa pot funcionar independent o enllaçar amb altres nodes per crear una súper-xarxa; deixant la privacitat sota el control de l'editor original.
|
||||
|
||||
$Projectname és una aplicació de servidor web de codi obert escrit originalment en PHP/MySQL i és fàcilment instalable per aquells amb habilitats d'administració web bàsiques. També s'estén fàcilment a través de plugins i temes i altres eines de tercers.
|
||||
|
||||
[b][size=24]Característiques de $Projectname[/size][/b]
|
||||
|
||||
|
||||
$Projectname és un tot terreny per a la publicació web i una xarxa de comunicacions amb diverses característiques úniques. Està dissenyat per a ser utilitzat per la gamma més àmplia de persones a la web, dels blocaires no tècnics, als programadors de PHP experts i administradors de sistemes experimentats.
|
||||
|
||||
A aquesta pàgina s'enumeren algunes de les característiques fonamentals de $Projectname que s'inclouen amb la versió oficial. Igual que amb la majoria del programari lliure i de codi obert, pot haver moltes altres extensions, complements, plugins, temes i configuracions que estan limitats només per les necessitats i la imaginació dels membres.
|
||||
|
||||
[b][size=24]Construït per la Privacitat i la Llibertat[/size][/b]
|
||||
|
||||
Un dels objectius de disseny de $Projectname és permetre la comunicació fàcil a la web, mentre que preserva la intimitat, si així es desitja pels membres. Per aconseguir aquest objectiu, $Projectname inclou una sèrie de característiques que permeten nivells arbitraris de privacitat:
|
||||
|
||||
[b]Control Lliscant d'Afinitat[/b]
|
||||
|
||||
En afegir connexions en $Projectname, els membres tenen l'opció d'assignar nivells de "afinitat" (el prop que la seva amistat és amb el contacte) per a la nova connexió. Per exemple, quan s'afegeix a algú que resulta ser una persona a la que segueixes el seu bloc, podries assignar al seu canal un nivell d'afinitat de "Coneguts".
|
||||
|
||||
D'altra banda, quan s'afegeix el canal d'un amic, que pot ser col·locat sota el nivell d'afinitat de "Amics".
|
||||
|
||||
En aquest punt, l'eina [i]Control Lliscant d'Afinitat[/i] de $Projectname, que en general apareix a la part superior de la teva pàgina, ajusta el contingut de la pàgina per incloure als que estan dins del rang afinitat desitjada. No es mostraran Canals fora d'aquest rang, llevat que s'ajusti el Control Lliscant per incloure'ls.
|
||||
|
||||
El Control Lliscant D'Afinitat permet filtrar instantàniament grans quantitats de contingut, agrupats per nivells de proximitat.
|
||||
|
||||
[b]Filtre de Connexions[/b]
|
||||
|
||||
Tens la capacitat de controlar amb precisió el que apareix en el teu flux emprant opcionalment el "filtre de connexió". Quan s'activa, l'editor de connexió proporciona entrades per a la selecció de criteris que ha de ser aparellat amb la finalitat d'incloure o excloure un lloc específic d'un canal específic. Una vegada que un missatge s'ha permès, tots els comentaris a aquest lloc se'ls permet, independentment de si s'ajusten als criteris de selecció. Pots seleccionar paraules que si estàn presents al bloc o assegurar-te que està inclosses en el teu flux. Les expressions regulars es poden usar per al control encara més fi, així com hashtags o fins i tot l'idioma detectat del lloc.
|
||||
|
||||
[b]Llista de Control d'Accés[/b]
|
||||
|
||||
En compartir el contingut, els membres tenen l'opció de restringir qui veu el contingut. En fer clic al cadenat sota de la casella de compartir, un pot triar els destinataris desitjats del lloc, fent clic en els seus noms.
|
||||
|
||||
Un cop enviat, el missatge serà visible únicament pel remitent i els destinataris seleccionats. En altres paraules, el missatge no apareixerà al mur públic.
|
||||
|
||||
Llistes de Control d'Accés es poden aplicar als continguts i missatges, fotos, esdeveniments, pàgines web, sales de xat i arxius.
|
||||
|
||||
[b]Inici de Sessió Únic[/b]
|
||||
|
||||
Les Llistes de Control d'Accés treballen per a tots els canals a la xarxa gràcies a la nostra tecnologia única d'inici de sessió únic. La majoria dels enllaços interns proporcionen una identitat símbolica que pot ser verificada en altres llocs $Projectname i s'utilitza per controlar l'accés als recursos privats. Entres una vegada al teu concentrador. Després d'això, l'autenticació de tots els recursos de $Projectname és "màgia".
|
||||
|
||||
|
||||
[b]WebDAV activa l'Emagatzematge d'Arxius[/b]
|
||||
|
||||
Els arxius poden ser enviats a la teva àrea d'emmagatzematge personal utilitzant les teves utilitats del sistema operatiu (arrossegar i deixar anar en la majoria dels casos). Pots protegir aquests arxius amb la Llista de Control d'Accés amb qualsevol combinació de membres de $Projectname (incloent alguns membres d'altres terceres xarxes) o fer-los públics.
|
||||
|
||||
[b]Foto Àlbums[/b]
|
||||
|
||||
Salva Fotos en Àlbums. Totes les fotografies es poden protegir mitjançant llistes de control d'accés.
|
||||
|
||||
[b]Calendari d'Esdeveniments[/b]
|
||||
|
||||
Creació i gestió d'esdeveniments i tasques, que també poden ser protegits amb llistes de control d'accés. Els esdeveniments poden ser importats/exportats a un altre programari amb el format estàndard de la indústria vCalendar/iCal i compartida en els llocs amb els altres. Esdeveniments d'aniversari s'agreguen automàticament dels teus amics i es tradueixen a la seva zona horària correcta així sabràs exactament quan es produeix l'aniversari - no importa on et trobis en el món en relació amb la persona de l'aniversari. Els esdeveniments es creen normalment amb taulells d'assistència perquè els teus amics i connexions puguin confirmar la seva assistència a l'instant.
|
||||
|
||||
[b]Sales de Xat[/b]
|
||||
|
||||
Pots crear qualsevol nombre de sales de xat personals i permetre l'accés a través de llistes de control d'accés. Aquestes solen ser més segures que XMPP, IRC, i altres transports de missatgeria instantània, encara que també permetem l'ús d'aquests altres serveis a través de connectors.
|
||||
|
||||
[b]Constructor de Pàgines Web[/b]
|
||||
|
||||
$Projectname té moltes eines de creació de "Gestió de Contingut" per a la creació de pàgines web, incloent l'edició disposició, menús, blocs, widgets, i pàgina/contingut per regions. Totes aquestes poden ser d'accés controlat perquè les pàgines resultants siguin privades per al seu públic objectiu.
|
||||
|
||||
[b]Apps/Aplicacions[/b]
|
||||
|
||||
Apps poden ser construïdes i distribuïdes pels membres. Aquestes aplicacions són diferents del tradicional "bloqueig pel proveïdor" perquè són controlats completament per l'autor - que pot proporcionar control d'accés a les pàgines d'aplicacions de destinació i la càrrega consegüent per a aquest accés. La majoria de les aplicacions en $Projectname són gratuïtes i es poden crear fàcilment per aquells que no tenen coneixements de programació.
|
||||
|
||||
[b]Disposició[/b]
|
||||
|
||||
La disposició de la pàgina es basa en un llenguatge de descripció anomenat Comanche. $Projectname en si mateix està escrit amb dissenys de Comanche i es poden canviar. Això permet un nivell de personalització que no se sol trobar en els anomenats "entorns multiusuari".
|
||||
|
||||
[b]Favorits[/b]
|
||||
|
||||
Compartir i guardar/administrar els enllaços de favorits proporcionats en les converses.
|
||||
|
||||
|
||||
[b]Xifrat de missatges privats i Dubtes sobre la confidencialitat[/b]
|
||||
|
||||
El correu privat s'emmagatzema en un format ocult. Si bé això no és a prova de bales, en general, evita l'espionatge informal per l'administrador del lloc o ISP.
|
||||
|
||||
Cada canal de $Projectname té el seu propi conjunt únic de claus RSA (de 4096 bits) públiques i privades associades, que es genera quan es crea primer els canals. Això s'utilitza per protegir els missatges privats i missatges en trànsit.
|
||||
|
||||
A més, els missatges poden ser creats utilitzant "xifrat d'extrem a extrem", que no pot ser llegit per els operadors $Projectname o ISPs o algú que no coneixi el codi d'accés.
|
||||
|
||||
Els missatges públics en general, no es xifren en trànsit o en l'emmagatzematge.
|
||||
|
||||
Els missatges privats poden ser retirats (com si no s'hagués enviat), encara que no es garanteix que el destinatari no l'ha llegit abans que l'hagis retirat.
|
||||
|
||||
Entrades i missatges poden ser creats amb una data de venciment, moment en el qual s'eliminaran/borraran en el lloc del destinatari.
|
||||
|
||||
|
||||
[b]Servei de Federació[/b]
|
||||
|
||||
A més de l'afegit (addon) "connectors d'entrades creuades" a una varietat de xarxes alternatives, no hi ha suport natiu per a la importació de continguts de RSS/Atom i usar això per crear canals especials. A més, una implementació experimental, però de treball del protocol de la Diàspora permet la comunicació amb la gent en les xarxes socials friendica i Diàspora descentralitzats. Actualment això es va marcar experimental a causa de que aquestes xarxes no tenen el mateix nivell de funcions de privacitat i encriptació i habilitats com $Projectname i poden presentar riscos per a la privacitat.
|
||||
També hi ha suport experimental per a l'autenticació OpenID que es pot utilitzar en les llistes de control d'accés. Aquest és un treball en progrés. El seu concentrador $Projectname pot ser utilitzat com un proveïdor d'OpenID per autenticar als serveis externs que utilitzen aquesta tecnologia.
|
||||
Els canals poden tenir permisos per convertir-se en "canals derivats" on dos o més canals existents es combinen per crear un nou canal d'actualitat.
|
||||
|
||||
[b]Col·leccions[/b]
|
||||
|
||||
"Col·leccions" és la nostra implementació de grups de privacitat, que és similar a Google "Cercles" i "Aspectes" de Diaspora. Això li permet filtrar el flux entrant per col·leccions o grups, i automàticament configurar la llista de control d'accés sortint a només aquells en la Col·lecció quan publiqui. Pots obviar tot això en qualsevol moment (abans d'enviar l'entrada).
|
||||
|
||||
|
||||
[b]Serveis de Directori [/b]
|
||||
|
||||
Oferim fàcil accés a un directori de membres i proporcionem eines descentralitzades capaçes de proporcionar amics "suggerits". Els directoris són llocs normals $Projectname que han optat per acceptar la funció de servidor de directori. Això requereix més recursos que la majoria dels llocs típics pel que no és el predeterminat. Els Directoris estan sincronitzats i reflecteixen el que tots ells contenen amb informació actualitzada sobre tota la xarxa (subjecte a demores normals de propagació).
|
||||
|
||||
|
||||
[b]TLS/SSL[/b]
|
||||
|
||||
Els concentradors de $Projectname que empran TLS/SSL, les comunicacions entre client i servidor son encriptades via TLS/SSL. Donades les recents revelacions en els mitjans de comunicació en relació amb, la vigilància global i l'elusió de xifrat pel NSA i GCHQ, és raonable suposar que les comunicacions HTTPS-protegides es poden veure compromeses de diverses maneres. Les comunicacions privades són en conseqüència xifrades en un nivell superior abans d'enviar-les fora del lloc.
|
||||
|
||||
[b]Ajustos del Canals[/b]
|
||||
|
||||
Quan es crea un canal, es tria un rol al que s'apliquen una sèrie d'ajustos de seguretat i privacitat preconfigurats. Aquests són elegits per les millors pràctiques per mantenir la privacitat en els nivells requerits.
|
||||
|
||||
Si escolliu un paper privacitat "personalitzat", cada canal permet permisos de gra fi que es fixaràn per a diferents aspectes de la comunicació. Per exemple, sota la capçalera "Ajusts de Seguretat i Privacitat", cada aspecte a la banda esquerra de la pàgina, té sis (6) Opcions possibles de visualització/accés, que es poden seleccionar fent clic al menú desplegable. També hi ha una sèrie d'altres opcions de privacitat que pots editar.
|
||||
|
||||
Les opcions són:
|
||||
- Ningú, excepte tu mateix.
|
||||
- Només aquells que es permeten específicament.
|
||||
- Qualsevol persona en la seva llibreta d'adreces.
|
||||
- Qualsevol en aquest lloc web.
|
||||
- Qualsevol persona en aquesta xarxa.
|
||||
- Qualsevol autenticat.
|
||||
- Qualsevol persona a Internet.
|
||||
|
||||
[b]Forums Públics i Privats[/b]
|
||||
|
||||
Els fòrums són típicament canals que poden estar obertes a la participació de múltiples autors. Actualment existeixen dos mecanismes per pujar als fòrums: 1) els missatges "de mur a mur" i 2) a través de les etiquetes de foro @menció. Els fòrums poden ser creats per qualsevol persona i s'utilitzats per a qualsevol propòsit. El directori conté una opció per buscar fòrums públics. Als Fòrums privats només es poden fer entrades pels membres i sovint només son vistos pels membres.
|
||||
|
||||
|
||||
[b]Clonat de Comptes[/b]
|
||||
|
||||
Els Comptes a $Projectname es refereixen com a [i]identitats nómades[/i], perquè la identitat d'un membre no està lligada al concentrador/servidor on es va crear originalment. Per exemple, quan es crea un compte de Facebook o Gmail, que està lligat a aquests serveis. No poden funcionar sense Facebook.com o Gmail.com.
|
||||
|
||||
Per contra, imagina que has creat una identitat a $Projectname anomenada [b]tina@Hubzillahub.com[/b]. Aquesta es pot clonar a un altre hub de $Projectname amb el mateix nom o un altre de diferent: per exemple [b]viuPerSempre@HubzillaHub.info[/b]
|
||||
|
||||
Tots dos canals estan ara sincronitzats, el que significa que tots els seus contactes i preferències es dupliquen en el teu clon. No importa si s'envia un missatge des del seu hub original o el nou centre. Els missatges/emtrades seran reflectits/des en tots dos comptes.
|
||||
|
||||
Aquesta és una característica bastant revolucionària, si tenim en compte alguns dels escenaris:
|
||||
|
||||
- Què passa si el concentrador/servidor on la identitat es basa cau sobtadament fora de línia? Sense clonació, un membre no pot comunicar fins que aquest centre torna a estar de nou en línia (sens dubte molts de vosaltres heu vist i maleït el Twitter "Fail Whale"). Amb la clonació, es pot iniciar la sessió al compte clonat, i la vida continua feliços per sempre. - L'administrador del teu concentrador/servidor ja no es pot permetre el luxe de pagar el concentrador/servidor $Projectname que ofereix gratuitament. Llavors anuncia que el centre serà tancant en dues setmanes. Això li dóna temps suficient als socis/partíceps per clonar la seva identitat/s i preservar les seves relacions de $Projectname, amics i contingut. - Què passa si la teva identitat està subjecta a la censura del govern? El teu proveïdor del concentrador/servidor pot ser obligat a eliminar el teu compte, juntament amb les identitats i dades associades. Amb la clonació, a $Projectname ofereixes [b]resistència a la censura[/b]. Pots tenir centenars de clons, si vols, amb noms totalment diferents, i existents en molts centres diferents, escampats a tot l'Internet.
|
||||
|
||||
$Projectname ofereix noves i interesants possibilitats per a la privacitat. Pots llegir més a la pàgina <<Bones Pràctiques en Comunicacions Privades>>.
|
||||
|
||||
A tenir en compte. Per a una explicació completa de la clonació d'identitat, llegir el <HOW TO CLONE MY IDENTITY>.
|
||||
|
||||
[b]Perfils Multiples[/b]
|
||||
|
||||
Es poden crear qualsevol nombre de perfils amb informació diferent i es poden fer-se visible/s a alguns de les teves connexions/amics. Un perfil "per defecte" es pot veure per qualsevol persona i pot contenir informació limitada, amb més informació disponible per grups o persones seleccionades. Això vol dir que el perfil (i el contingut del lloc) per als teus amics bevedors de cervesa pot ser diferents del que presentes als seus companys de treball, i també completament diferent del que és visible per al públic en general.
|
||||
|
||||
[b]Còpies de Seguretat del Compte[/b]
|
||||
|
||||
Hubzilla ofereix una còpia de seguretat del compte, amb un simple clic, on pots descarregar una còpia de seguretat completa del teu perfil(s).
|
||||
|
||||
Les còpies de seguretat es poden utilitzar per clonar o restaurar un perfil.
|
||||
|
||||
[b]Eliminació del Compte[/b]
|
||||
|
||||
Els comptes poden ser [b]esborrats immediatament[/b] fent clic en un enllaç. [b]Això és així[/b]. Tot el contingut associat s'elimina de la xarxa (això inclou els missatges i qualsevol altre tipus de contingut produït pel perfil suprimit). Depenent del nombre de connexions que té, el procés d'eliminació de contingut remot podria portar el seu temps, però està previst que passi tan aviat com sigui possible.
|
||||
|
||||
[b][size=20]Creació de Contingut[/size][/b]
|
||||
|
||||
[b]Escribint Entrades[/b]
|
||||
|
||||
$Projectname suporta un nombre de diferents alternatives per afegir contingut amb text enriquit. La opció per defecte es una variant personalitzada de _BBcode, ajustada per al seu ús a $Projectname. Pots activar l'ús de Markdown (un llenguatge de marques) fàcil de treballar amb ell. Un editor visual també es pot emprar. El editor visual tradicionalment emprat en $Projectname va tenir seriosos problemes i ha estat eliminat. Estem actualment buscant un substitut.
|
||||
|
||||
Quant creem "llocs Web", El contingut espot afegir en HTML, Markdown, BBcode, i/o text plà.
|
||||
|
||||
[b]Esborrat del contingut[/b]
|
||||
Qualsevol contingut creat a $Projectname roman sota el control del membre (o canal) que el va crear originalment. En qualsevol moment, un membre pot esborrar un missatge o un rang de missatges. El procés d'esborrat assegura que el contingut es eliminat, indiferentment de on es va publicar si en el canal primari (l'inicial)del concentrador/servidor o en altre qualsevol on el canal es va autenticar remotament via Zot ($Projectname communicació i protocol d'autenticació).
|
||||
|
||||
[b]Multimedia[/b]
|
||||
Igual que qualsevol altre sistema modern de blocs, xarxes socials, o d'un servei de micro-blogging, $Projectname és compatible amb la càrrega d'arxius, la incorporació dels vídeos, l'enllaç de pàgines web.
|
||||
|
||||
[b]Vista Prèvia/Edició[/b]
|
||||
Les entrades es poder pre visualitzar abans d'enviar-les i reeditar desprès de ser enviades.
|
||||
|
||||
[b]Votacions/Consens[/b]
|
||||
El missatges poden convertir-se en "consensos", són articles que ofereixen als lectors una forma de retroalimentació, es recopilen en comptadors de "d'acord", "en desacord" i "abstenir-se". Que permeten mesurar l'interès per les idees i crear enquestes informals.
|
||||
|
||||
|
||||
[b]Estenent $Projectname[/b]
|
||||
|
||||
$Projectname es pot estendre per diferents nombre de vies, a través de la personalització del lloc, la teva personalització, ajustos optatius, temes i addons/plugins.
|
||||
|
||||
[b]API[/b]
|
||||
|
||||
Una API està disponible per al seu ús per serveis de terceres part. Està basat originalment en una de les primeres API's de Twitter(de la que existeixen cents d'eines de terceres parts). S'està ampliant actualment per proporcionar accés a les instal·lacions i capacitats que són específiques de $Projectname. L'accés pot ser proporcionada per usuari/contrasenya o OAuth i es proporciona registre de clients d'aplicacions OAuth.
|
||||
|
||||
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
3
doc/ca/first-post.bb
Normal file
3
doc/ca/first-post.bb
Normal file
@ -0,0 +1,3 @@
|
||||
[size=large]La teva primera entrada[/size]
|
||||
|
||||
... pendent de ser escrita ...
|
20
doc/ca/general.bb
Normal file
20
doc/ca/general.bb
Normal file
@ -0,0 +1,20 @@
|
||||
[h2]Informació del Projecte/Lloc[/h2]
|
||||
|
||||
[zrl=[baseurl]/help/Privacy]Politica de Privacitat[/zrl]
|
||||
|
||||
[zrl=[baseurl]/help/history]Història de $Projectname[/zrl]
|
||||
|
||||
[h3]Recursos Externs[/h3]
|
||||
[zrl=[baseurl]/help/external-resource-links]Enllaços a Recursos Externs[/zrl]
|
||||
|
||||
[url=https://github.com/redmatrix/hubzilla]Lloc Web Principal[/url]
|
||||
|
||||
[url=https://github.com/redmatrix/hubzilla-addons]Complements del Lloc Web[/url]
|
||||
|
||||
[url=[baseurl]/help/credits]Credits en $Projectname[/url]
|
||||
|
||||
[h3]Sobre Aquest Node $Projectname[/h3]
|
||||
[zrl=[baseurl]/help/TermsOfService]Termes de Servei per a AQUEST Node[/zrl]
|
||||
[zrl=[baseurl]/siteinfo]Informació del Node[/zrl]
|
||||
[zrl=[baseurl]/siteinfo/json]Informació Tècnica Detallada en format JSON d'aquest Node[/zrl]
|
||||
|
12
doc/ca/main.bb
Normal file
12
doc/ca/main.bb
Normal file
@ -0,0 +1,12 @@
|
||||
[zrl=[baseurl]/help/about][b]Que és $Projectname?[/b][/zrl]
|
||||
$Projectname és una plataforma de comunicació i publicació descentralitzada que et permet mantenir el control de les teves necessitats de comunicació, gràcies a l'encriptació automàtica i control d'accés de gra fi. Éts tu, i només tu qui decideixes qui pot veure les teves coses.
|
||||
|
||||
[zrl=[baseurl]/help/features][b]Característiques de $Projectname[/b][/zrl]
|
||||
|
||||
$Projectname ja s'està executant com una xarxa distribuïda global i demostra la seva versatilitat i escalabilitat des de independent fins a grans llocs.
|
||||
Penseu en plataformes independents de comunicació de la família, de comunitats en línia distribuïdes, fòrums de suport, blocs i pàgines web. O proveïdors de continguts professionals amb canals premium comercials i accés de continguts específics. El que vulguis, $Projectname és allà per atendre la teva creativitat.
|
||||
|
||||
[zrl=[baseurl]/help/what_is_zot][b]Tens Zot? Be, Deuries.[/b][/zrl]
|
||||
Zot és el gran nou protocol de communicació inventat especialment per a $Projectname. Com a membre, ja no estàs lligat a un sol lloc o concentrador (hub) gràcies a les "identitats nòmades". Migra fàcilment a un altre servidor i manté els teus contactes intactes, o clona i executa el mateix canal en diversos servidors. Encara que un d'ells tanqui, no es perd res. A més, una vegada que estàs dins de $Projectname no hi ha necessitat d'autenticar dues vegades, fins i tot quan s'accedeix des d'un altre lloc $Projectname. Zot és el que difèrencia $Projectname de qualsevol altre projecte.
|
||||
|
||||
|
25
doc/ca/members.bb
Normal file
25
doc/ca/members.bb
Normal file
@ -0,0 +1,25 @@
|
||||
[h2]Documentació per a Membres del Concentrador[/h2]
|
||||
|
||||
[h3]Començant[/h3]
|
||||
[zrl=[baseurl]/help/registration]Registrant un Compte[/zrl]
|
||||
[zrl=[baseurl]/help/accounts_profiles_channels_basics]Tu a $Projectname: breument comptes, perfils i canals[/zrl]
|
||||
[zrl=[baseurl]/help/profiles]Perfils[/zrl]
|
||||
[zrl=[baseurl]/help/channels]Canals[/zrl]
|
||||
[zrl=[baseurl]/help/roles]Permisos per roles i tipus de Canals[/zrl]
|
||||
[zrl=[baseurl]/help/first-post]La teva primera entrada[/zrl]
|
||||
[zrl=[baseurl]/help/connecting_to_channels]Connectant Amb Altres Canals[/zrl]
|
||||
[zrl=[baseurl]/help/permissions]Permisos I Encriptació: Tu Tens El Control[/zrl]
|
||||
[zrl=[baseurl]/help/cloud]Emmagatzegament Al Núbol[/zrl]
|
||||
[zrl=[baseurl]/help/remove_account]Esborrar un Canal o un Compte[/zrl]
|
||||
|
||||
[h3]Ajuda per als Membres[/h3]
|
||||
[zrl=[baseurl]/help/tags_and_mentions]Etiquetes i Mencions[/zrl]
|
||||
[zrl=[baseurl]/help/webpages]Pàgines Web[/zrl]
|
||||
[zrl=[baseurl]/help/bbcode]Referència BBcode per a entrades i comentaris[/zrl]
|
||||
[zrl=[baseurl]/help/checking_account_quota_usage]Comprovant la Quota d'Ús del Compte[/zrl]
|
||||
[zrl=[baseurl]/help/cloud_desktop_clients]Clients d'Escriptori al Núbol[/zrl]
|
||||
[zrl=[baseurl]/help/AdvancedSearch]Cerca Avançada al Directori[/zrl]
|
||||
[zrl=[baseurl]/help/addons]Ajuda pels Addons[/zrl]
|
||||
[zrl=[baseurl]/help/diaspora_compat]Compatibilitat de Comunicacions amb Diaspora (Diaspora i Friendica)[/zrl]
|
||||
[zrl=[baseurl]/help/faq_members]FAQ Per Membres[/zrl]
|
||||
[zrl=[baseurl]/help/bugs]Errors, Assumptes, i les coses que arriben de cop a la nit...[/zrl]
|
37
doc/ca/profiles.bb
Normal file
37
doc/ca/profiles.bb
Normal file
@ -0,0 +1,37 @@
|
||||
[b]Profiles[/b]
|
||||
|
||||
$Projectname has unlimited profiles. You may use different profiles to show different "sides of yourself" to different audiences. This is different to having different channels. Different channels allow for completely different sets of information. You may have a channel for yourself, a channel for your sports team, a channel for your website, or whatever else. A profile allows for finely graded "sides" of each channel. For example, your default public profile might say "Hello, I'm Fred, and I like laughing". You may show your close friends a profile that adds "and I also enjoy dwarf tossing".
|
||||
|
||||
You always have a profile known as your "default" or "public" profile. This profile is always available to the general public and cannot be hidden (there may be rare exceptions on privately run or disconnected sites). You may, and probably should restrict the information you make available on your public profile.
|
||||
|
||||
That said, if you want other friends to be able to find you, it helps to have the following information in your public profile...
|
||||
|
||||
[ul][*]Your real name or at least a nickname everybody knows
|
||||
[*]A photo of you
|
||||
[*]Your location on the planet, at least to a country level.[/ul]
|
||||
|
||||
In addition, if you'd like to meet people that share some general interests with you, please take a moment and add some "Keywords" to your profile. Such as "music, linux, photography" or whatever. You can add as many keywords as you like.
|
||||
|
||||
To create an alternate profile, first go to [zrl=[baseurl]/settings/features]Settings > Additional Features[/zrl] and enable "Multiple Profiles" there, otherwise you won't have the ability to use more than just your default profile.
|
||||
|
||||
Then select "Edit Profiles" from the menu of your $Projectname site. You may edit an existing profile, change the profile photo, add things to a profile or create a new profile. You may also create a "clone" of an existing profile if you only wish to change a few items but don't wish to enter all the information again. To do that, click on the profile you want to clone and choose "Clone this profile" there.
|
||||
|
||||
In the list of your profiles, you can also choose the contacts who can see a specific profile. Just click on "Edit visibility" next to the profile in question (only available for the profiles that are not your default profile) and then click on user images to add them to or remove them from the group of people who can see this profile.
|
||||
|
||||
Once a profile has been selected, when the person views your profile, they will see the private profile you have assigned. If they are not authenticated, they will see your public profile.
|
||||
|
||||
There is a setting which allows you to publish your profile to a directory and ensure that it can be found by others. You can change this setting on the "Settings" page.
|
||||
|
||||
If you do not wish to be found be people unless you give them your channel address, you may leave your profile unpublished.
|
||||
|
||||
[b]Keywords and Directory Search[/b]
|
||||
|
||||
On the directory page, you may search for people with published profiles. Currently, only the name field and the keywords are searched. You may also include such keywords in your default profile - which may be used to search for common interests with other members. Keywords are used in the channel suggestion tool and although they aren't visible in the directory, they are shown if people visit your profile page.
|
||||
|
||||
On your Connnections page and in the directory there is a link to "Suggestions" or "Channel Suggestions", respectively. This will find channels who have matching and/or similar keywords. The more keywords you provide, the more relevant the search results that are returned. These are sorted by relevance.
|
||||
|
||||
See Also
|
||||
|
||||
[zrl=[baseurl]/help/AdvancedSearch]Advanced Searching[/zrl]
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
35
doc/ca/registration.bb
Normal file
35
doc/ca/registration.bb
Normal file
@ -0,0 +1,35 @@
|
||||
[size=large][b]Registre[/b][/size]
|
||||
|
||||
No tots els llocs $Projectname permeten la inscripció oberta. Si es permet el registre, veureu un enllaç de " Registre " immediatament sota de l'entrada a la pàgina principal del lloc. Seguint aquest enllaç et portarà a la pàgina de registre del lloc. En alguns llocs es pot redirigir a un altre lloc que permet registres. Com tots els llocs $Projectname estan vinculats, no importa on resideix el teu compte.
|
||||
|
||||
[b]La Teva Adreça de Correu Electrònic[/b]
|
||||
|
||||
Si us plau introdueix la teva adreça de correu electrònic vàlida. La teva adreça de correu electrònic mai es farà pública. Aquesta adreça s'utilitzarà per activar el teu compte, que (opcionalment) enviarà notificacions de correu electrònic per als missatges entrants o articles, [i]i per recuperar contrasenyes perdudes[/i].
|
||||
|
||||
[b]Contrasenya[/b]
|
||||
|
||||
Introdueix una contrasenya de la teva elecció, i repeix-la en la segona casella per assegurar-te que es va escriure correctament. Com $Projectname ofereix una identitat descentralitzada, Es pot accedir al teu compte en molts altres llocs web no només en el que t'has donat d'alta.
|
||||
|
||||
[b]Termes Del Servei[/b]
|
||||
|
||||
Clica a l'enllaç per llegir els [zrl=[baseurl]/help/TermsOfService]Termes de Servei[/zrl] del lloc. Una vegada llegits, marca la casella al formulari de registre per confirmar.
|
||||
|
||||
[b]Registre[/b]
|
||||
|
||||
Una vegada que hagis proporcionat els detalls necessaris, fes clic al botó "Registrar-se". Alguns llocs poden requerir l'aprovació de l'administrador abans de processar el registre, s'avisarà si aquest és el cas. Si us plau, mira el teu correu electrònic (incloent carpetes d'spam) per poder finalitzar la teva aprovació de registre.
|
||||
|
||||
[b]Crear un Canal[/b]
|
||||
|
||||
A continuació, se et presentarà la pantalla " Afegir un canal". Normalment, el primer canal serà un que et representa - pel que l'ús del seu propi nom (o pseudònim) com el nom del canal és una bona idea. El nom de la cadena ha de ser pensat com un títol o descripció breu del teu canal. El " triar un sobrenom curt " és similar a un "nom d'usuari ". Farem servir tot el que entra aquí per crear una adreça de canal, que altres persones utilitzaran per connectar-se amb tu, i que utilitzaràs per iniciar sessió en altres llocs. Això s'assembla a una adreça de correu electrònic, i pren la forma nickname@siteyouregisteredat.xyz
|
||||
|
||||
Quan es crea el teu canal se't portarà directament a la pàgina de configuració on pots definir permisos, habilitar les funcions, etc. Totes aquestes coses es tracten a la secció corresponent dels fitxers d'ajuda.
|
||||
|
||||
Veure Tambè
|
||||
[zrl=[baseurl]/help/accounts_profiles_channels_basics]Lo Basic sobre Identitats dins $Projectname[/zrl]
|
||||
[zrl=[baseurl]/help/accounts]Comptes[/zrl]
|
||||
[zrl=[baseurl]/help/profiles]Perfils[/zrl]
|
||||
[zrl=[baseurl]/help/permissions]Permisos[/zrl]
|
||||
[zrl=[baseurl]/help/remove_account]Eliminar Compte[/zrl]
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
||||
|
61
doc/ca/what_is_zot.bb
Normal file
61
doc/ca/what_is_zot.bb
Normal file
@ -0,0 +1,61 @@
|
||||
[b]Qué és Zot?[/b]
|
||||
|
||||
Zot és el protocol que fa funcionar $Projectname, proveeix tres Característiques esencials: Comunicacions, Identitat, i Control d'Accéss.
|
||||
|
||||
Les funcionalitats que proveeix es poden describir de la següent manera:
|
||||
|
||||
- una relació en línia es només un munt de permisos
|
||||
- internet és només un altre carpeta
|
||||
|
||||
[b][size=20]Comunicacions[/size][/b]
|
||||
|
||||
Zot és un protocol revolucionari que ofereix [i]comunicacions descentralitzades[/i] i [i]gestió d'identitat[/i] en tota la malla (o entrallat de connexions). El resultat es una plataforma que proveeix serveis web comparables amb els que ofereixen les grans companyies, però sense elles ni els seus problemes de privacitat, la seva insaciable necessitat de beneficis, ni la seva idea dels jardins-privats.
|
||||
|
||||
Comunicacions i xarxes socials són una part integral del teixit. Qualsevol canal (i qualsevol servei ofert per aquest canal) por fer ús complert de les grans caracteristiques de comunicació social a escala global. Aquestes comunicacions poden ser públiques o privades - i comunicacions privades no es limiten a encriptar totalment l'enviament, sino que també encripten l'emmagatzegament per tal d'impedir que, administradors de sistemes murris o proveidors de servei, accidental o intencionadament tafanegin o revelin dades personals.
|
||||
|
||||
Zot permet un ampli vental de serveis en segon plà per a la xarxa, des de oferir suggeriments d'amics, a serveis de directori. També pot realitzar altres coses que normalment només són possibles en un proveïdor centralitzat, com missatges "de mur a mur". Perfils particulars/múltiples es poden crear fàcilment i el contingut del web es pot adaptar a l'espectador a través del [i]Control Lliscant d'Afinitat[/i].
|
||||
|
||||
No trobaràs, de cap manera, aquestes característiques en altres serveis de comunicació descentralitzades. A més de proporcionar la descentralització de concentradors (servidors), potser la característica més innovadora i interessant de Zot és el subministrament de serveis [i]d'identitat descentralitzada[/i].
|
||||
|
||||
[b][size=20]Identitat[/size][/b]
|
||||
|
||||
La capa que permet identitat mitjançant Zot es única. Facilita [i]l'identificació única invisible[/i] al llarg de tots els llocs de la malla.
|
||||
|
||||
També ofereix [i]identitat nómada[/i], de tal forma que les teves comunicacions amb amics, familiars , i qualsevol amb el que et comuniquis no s'han de veure afectats per la pérdua (caiguda, desconnexió) temporal/permanent del teu node de comunicació primari.
|
||||
|
||||
Les parts importants de la teva identitat i les relacions es poden copiar a una memòria USB, o el teu ordinador portàtil, i poden aparèixer en qualsevol node de la xarxa en qualsevol moment - amb tots els teus amics i preferències intactes.
|
||||
|
||||
Fonamentalment, aquestes instàncies (identitats) nòmades es mantenen en sincronia per tal que qualsevol instància pugui fer-se càrrec si un altre està en perill o danyada. Això el protegeix contra no només d'una fallada del sistema, sinó també de sobrecàrregues temporals del lloc i/o la manipulació governamental o censura.
|
||||
|
||||
Identitat nòmada, inici de sessió únic, i nodes $Projectname descentralitzats, al nostre parer, introduir un alt grau de grau de [i]resiliència[/i] i [i]persistència[/i] en les comunicacions d'Internet, que són profundament necessàries en direcció contrària de les tendències mundials cap a la centralització corporativa, així com la vigilància governamental indiscriminada i la censura.
|
||||
|
||||
Com naveges per la xarxa, els canals de visualització i el seu contingut únic, que es produeix sobre la marxa, fins i tot a través de centres de servidors completament diferents. No hi ha contrasenyes per entrar. No hi ha res a escriure. No tens que posar teu nom en cada nou lloc que visites.
|
||||
|
||||
Com Zot pot fer això? En diem [i]identificació-màgica[/i], perquè $Projectname oculta els detalls de les complexitats que van a l'inici únic de sessió, les identitats nòmades, i l'experiència de navegació a la xarxa. Aquest és un dels objectius de disseny de $Projectname: per augmentar la privacitat i la llibertat a la xarxa, alhora que redueix la complexitat i el tedi interposat per la necessitat d'introduir noves contrasenyes i noms d'usuari per a cada vista diferent, que pots visitar en línia.
|
||||
|
||||
Entrar com a usuari només una vegada en el teu centre d'origen (o qualsevol centre de recolçament nòmada que hagis triat). Això permet accedir a tots els serveis autenticats en qualsevol lloc de la malla - com ara anar a comprar, blocs, fòrums, i l'accés a la informació privada. Això és igual que els serveis oferts pels grans proveïdors de les empreses amb enormes bases de dades d'usuaris; però, pots ser un membre d'aquesta comunitat, així com un servidor en aquesta xarxa emprant un RasberryPi de 35$. La teva contrasenya no s'emmagatzema en un miler de diferents llocs, o encara pitjor, només en uns pocs llocs com Google i Facebook, fora del teu control directe.
|
||||
|
||||
No pots ser silenciat. No pots ser eliminat de la xarxa, llevat que triïs per sortir, tu mateix.
|
||||
|
||||
[b][size=20]Control d'Accés[/size][/b]
|
||||
|
||||
La capa de identitat de Zot permet proporcionar permisos específics a qualsevol contingut que desitgis publicar - i aquests permisos s'estenen per $ProjectName. Això és com tenir un sol súper gran espai web format per un exèrcit de petits llocs web individuals - i on cada canal a la xarxa pot controlar completament les seves preferències de privacitat i ús compartit dels recursos web que creen.
|
||||
|
||||
Actualment, la xarxa suporta comunicacions, àlbums de fotos, esdeveniments, i arxius. Això s'ampliarà en el futur per proporcionar serveis de gestió de continguts (pàgines web) i instal·lacions d'emmagatzematge en el núvol, com biblioteques WebDAV i multimèdia. Cada objecte i la forma en què es comparteix i amb qui està completament sota el teu control.
|
||||
|
||||
Aquest tipus de control està disponible en grans proveïdors de serveis com Facebook i Google, ja que poseeixen la base de dades d'usuari. Dins de la xarxa, no hi ha necessitat d'un gran usuari de base de dades a la teva màquina - perquè la xarxa [i]és[/i] la teva base de dades d'usuari. Té essencialment infinita capacitat (limitada pel nombre total de nodes en línia a través d'Internet), i s'estén entre centenars, i potencialment milions d'ordinadors.
|
||||
|
||||
L'accés pot ser concedit o negat per a qualsevol recurs, a qualsevol canal, o qualsevol grup de canals; en qualsevol lloc dins de la malla. Altres podràn accedir al teu contingut si els permets fer-ho, i ni tan sols cal tenir un compte al node. Les teves fotos privades no es poden veure, perquè els permissos realment funcionen; no són un complement que s'ha afegit a l'últim moment. Si no ets a la llista d'espectadors permesos per a una foto en particular, tu no la veuràs.
|
||||
|
||||
[b][size=18]Recursos Addicionals i Enllaços[/size][/b]
|
||||
|
||||
Per més detalla, informació tècnica sobre Zot, clica sobre algún dels següents enllaços:
|
||||
|
||||
- [url=https://github.com/friendica/red/wiki/Zot---A-High-Level-Overview]Vista per experts (en anglès)[/url]
|
||||
|
||||
- [url=https://github.com/friendica/red/wiki/zot]Especificació pel desenvolupament de Zot (en anglès)[/url]
|
||||
|
||||
- [url=https://github.com/redmatrix/hubzilla/blob/master/include/zot.php]Referència per la implementació de Zot en PHP (en anglès)[/url]
|
||||
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
@ -10,7 +10,7 @@ On many public servers there may be limits on disk usage.
|
||||
|
||||
The quickest and easiest way to share files is through file attachments. In the row of icons below the status post editor is a tool to upload attachments. Click the tool, select a file and submit. After the file is uploaded, you will see an attachment code placed inside the text region. Do not edit this line or it may break the ability for your friends to see the attachment. You can use the post permissions dialogue box or privacy hashtags to restrict the visibility of the file - which will be set to match the permissions of the post your are sending.
|
||||
|
||||
To delete attachments or change the permissions on the stored files, visit [observer.baseurl]/filestorage/{{username}}" replacing {{username}} with the nickname you provided during channel creation.
|
||||
To delete attachments or change the permissions on the stored files, visit [observer.baseurl]/cloud/{{username}}" replacing {{username}} with the nickname you provided during channel creation.
|
||||
|
||||
[b]Web Access[/b]
|
||||
|
||||
@ -22,6 +22,6 @@ See: [zrl=[baseurl]/help/cloud_desktop_clients]Cloud Desktop Clients[/zrl]
|
||||
|
||||
[b]Permissions[/b]
|
||||
|
||||
When using WebDAV, the file is created with your channel's default file permissions and this cannot be changed from within the operating system. It also may not be as restrictive as you would like. What we've found is that the preferred method of making files private is to first create folders or directories; then visit "filestorage/{{username}}"; select the directory and change the permissions. Do this before you put anything into the directory. The directory permissions take precedence so you can then put files or other folders into that container and they will be protected from unwanted viewers by the directory permissions. It is common for folks to create a "personal" or "private" folder which is restricted to themselves. You can use this as a personal cloud to store anything from anywhere on the web or any computer and it is protected from others. You might also create folders for "family" and "friends" with permission granted to appropriate collections of channels.
|
||||
When using WebDAV, the file is created with your channel's default file permissions and this cannot be changed from within the operating system. It also may not be as restrictive as you would like. What we've found is that the preferred method of making files private is to first create folders or directories; then visit "filestorage/{{username}}"; select the directory and change the permissions. Do this before you put anything into the directory. The directory permissions take precedence so you can then put files or other folders into that container and they will be protected from unwanted viewers by the directory permissions. It is common for folks to create a "personal" or "private" folder which is restricted to themselves. You can use this as a personal cloud to store anything from anywhere on the web or any computer and it is protected from others. You might also create folders for "family" and "friends" with permission granted to appropriate privacy groups.
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
||||
|
@ -27,8 +27,8 @@ Currently there are five layout templates, unless your site provides additional
|
||||
edgesthree - three column layout with fixed side margins
|
||||
full - three column layout with fixed side margins and adds a "header" region beneath the navigation bar
|
||||
|
||||
[b]redable[/b]
|
||||
A template for reading longer texts. Three columns: aside, content and right_aside.
|
||||
[b]redable[/b] (sic)
|
||||
A template for reading longer texts full screen (so without navigation bar). Three columns: aside, content and right_aside.
|
||||
For maximum readability it is advised to only use the middle content column.
|
||||
|
||||
[b]zen[/b]
|
||||
|
3
doc/context/admin/security/help.html
Normal file
3
doc/context/admin/security/help.html
Normal file
@ -0,0 +1,3 @@
|
||||
<h3>Security Settings</h3>
|
||||
<p>This page contains various administrator settings related to security.</p>
|
||||
<p>To save any changes you make to these settings, you must press the Submit button.</p>
|
24
doc/context/channel/help.html
Normal file
24
doc/context/channel/help.html
Normal file
@ -0,0 +1,24 @@
|
||||
<script>
|
||||
var contextualHelp1 = function (target, openSidePanel) {
|
||||
$("#help-content").removeClass('help-content-open'); // Close the help panel
|
||||
$("#navbar-collapse-1").removeClass('in'); // Collapse the navbar for small screens
|
||||
if (openSidePanel) {
|
||||
$("main").addClass('region_1-on'); // Open the side panel to highlight element
|
||||
} else {
|
||||
$("main").removeClass('region_1-on');
|
||||
}
|
||||
// Animate the page scroll to the element and then pulse the element to direct attention
|
||||
$('html,body').animate({scrollTop: $(target).offset().top - $('#navbar-collapse-1').height() - 20}, 'slow');
|
||||
for (i = 0; i < 3; i++) {
|
||||
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>General</dt>
|
||||
<dd>This is the home page of a channel. It is similar to someone's profile "wall" in a social network context. Posts created by the channel are displayed according to the observer's viewing permissions.</dd>
|
||||
<dt>Create a Post</dt>
|
||||
<dd>If you have permission to create posts on the channel page, then you will see the post editor at the top.</dd>
|
||||
<dt><a href='#' onclick='contextualHelp1("#tabs-collapse-1", 0); return false;' title="Click to highlight element...">Channel Content Tabs</a></dt>
|
||||
<dd>The channel content tabs are links to other content published by the channel. The <b>About</b> tab links to the channel profile. The <b>Photos</b> tab links to the channel photo galleries. The <b>Files</b> tab links to the general shared files published by the channel.</dd>
|
||||
</dl>
|
22
doc/context/cloud/help.html
Normal file
22
doc/context/cloud/help.html
Normal file
@ -0,0 +1,22 @@
|
||||
<script>
|
||||
var contextualHelp1 = function (target, openSidePanel) {
|
||||
$("#help-content").removeClass('help-content-open'); // Close the help panel
|
||||
$("#navbar-collapse-1").removeClass('in'); // Collapse the navbar for small screens
|
||||
if (openSidePanel) {
|
||||
$("main").addClass('region_1-on'); // Open the side panel to highlight element
|
||||
} else {
|
||||
$("main").removeClass('region_1-on');
|
||||
}
|
||||
// Animate the page scroll to the element and then pulse the element to direct attention
|
||||
$('html,body').animate({scrollTop: $(target).offset().top - $('#navbar-collapse-1').height() - 20}, 'slow');
|
||||
for (i = 0; i < 3; i++) {
|
||||
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>General</dt>
|
||||
<dd>This page displays a channel's "cloud" files. The files visible to the observer depend on the individual file permissions set by the channel owner. If you have permission to create/upload files you will see control buttons above the file list.</dd>
|
||||
<dt><a href='#' onclick='contextualHelp1("#tabs-collapse-1", 0); return false;' title="Click to highlight element...">Channel Content Tabs</a></dt>
|
||||
<dd>The channel content tabs are links to other content published by the channel. The <b>About</b> tab links to the channel profile. The <b>Photos</b> tab links to the channel photo galleries. The <b>Files</b> tab links to the general shared files published by the channel.</dd>
|
||||
</dl>
|
10
doc/context/mail/help.html
Normal file
10
doc/context/mail/help.html
Normal file
@ -0,0 +1,10 @@
|
||||
<dl class="dl-horizontal">
|
||||
<dt>General</dt>
|
||||
<dd>The messages displayed in private mail are visible only to you and the single recipient. </dd>
|
||||
<dt>Combined View</dt>
|
||||
<dd>Complete conversations can be viewed in a continuous thread by selecting <b>Combined View</b>. Available conversations are displayed beneath the menu in the side panel.</dd>
|
||||
<dt>Inbox/Outbox</dt>
|
||||
<dd>Individual sent messages are viewed by selecting <b>Outbox</b>, and incoming messages are viewed using the <b>Inbox</b> filter.</dd>
|
||||
<dt>New Message</dt>
|
||||
<dd>Individual messages have delivery reports that can be viewed using the drop-down menu. Messages can also be recalled from the same menu, which can prevent the recipient from viewing the message <i>if they have not already read it</i>.</dd>
|
||||
</dl>
|
26
doc/context/network/help.html
Normal file
26
doc/context/network/help.html
Normal file
@ -0,0 +1,26 @@
|
||||
<script>
|
||||
var contextualHelp1 = function (target, openSidePanel) {
|
||||
$("#help-content").removeClass('help-content-open'); // Close the help panel
|
||||
$("#navbar-collapse-1").removeClass('in'); // Collapse the navbar for small screens
|
||||
if (openSidePanel) {
|
||||
$("main").addClass('region_1-on'); // Open the side panel to highlight element
|
||||
} else {
|
||||
$("main").removeClass('region_1-on');
|
||||
}
|
||||
// Animate the page scroll to the element and then pulse the element to direct attention
|
||||
$('html,body').animate({scrollTop: $(target).offset().top - $('#navbar-collapse-1').height() - 20}, 'slow');
|
||||
for (i = 0; i < 3; i++) {
|
||||
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>General</dt>
|
||||
<dd>The network page displays a stream of posts and conversations, typically ordered by the most recently updated. This page is highly customizable.</dd>
|
||||
<dt><a href='#' onclick='contextualHelp1("#profile-jot-wrapper", 0); return false;' title="Click to highlight element...">Create a Post</a></dt>
|
||||
<dd>At the top of the page there is a text box that says "Share". Clicking this box opens a new post editor. The post editor is customizable, but the basic editor provides fields for a post body and an optional post <b>Title</b>. Buttons below the text area to the left provide shortcuts to text formatting and inserting links, images, and other data into the post. The buttons to the right provide a post preview, the post permissions setting, and a <b>Submit</b> button to send the post.</dd>
|
||||
<dt><a href='#' onclick='contextualHelp1("#group-sidebar", 1); return false;' title="Click to highlight element...">Privacy Groups</a></dt>
|
||||
<dd>The privacy groups you have created are displayed in the side panel. Selecting them filters posts to those created by channels in the chosen group.</dd>
|
||||
<dt><a href='#' onclick='$("#dbtn-acl").click(); return false;' title="Click to highlight element...">Post Permissions</a></dt>
|
||||
<dd>The access control list (ACL) is what you use to set who can see your new post. Pressing the ACL button beside the Submit button will display a dialog in which you can select what channels and/or privacy groups can see the post. You can also select who is explicitly denied access. For example, say you are planning a surprise party for a friend. You can send an invitation post to everyone in your <b>Friends</b> group <i>except</i> the friend you are surprising. In this case you "show" the <b>Friends</b> group but "don't show" that one person.</dd>
|
||||
</dl>
|
22
doc/context/photos/help.html
Normal file
22
doc/context/photos/help.html
Normal file
@ -0,0 +1,22 @@
|
||||
<script>
|
||||
var contextualHelp1 = function (target, openSidePanel) {
|
||||
$("#help-content").removeClass('help-content-open'); // Close the help panel
|
||||
$("#navbar-collapse-1").removeClass('in'); // Collapse the navbar for small screens
|
||||
if (openSidePanel) {
|
||||
$("main").addClass('region_1-on'); // Open the side panel to highlight element
|
||||
} else {
|
||||
$("main").removeClass('region_1-on');
|
||||
}
|
||||
// Animate the page scroll to the element and then pulse the element to direct attention
|
||||
$('html,body').animate({scrollTop: $(target).offset().top - $('#navbar-collapse-1').height() - 20}, 'slow');
|
||||
for (i = 0; i < 3; i++) {
|
||||
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>General</dt>
|
||||
<dd>This page displays a channel's photo albums. The images visible to the observer depend on the individual image permissions.</dd>
|
||||
<dt><a href='#' onclick='contextualHelp1("#tabs-collapse-1", 0); return false;' title="Click to highlight element...">Channel Content Tabs</a></dt>
|
||||
<dd>The channel content tabs are links to other content published by the channel. The <b>About</b> tab links to the channel profile. The <b>Photos</b> tab links to the channel photo galleries. The <b>Files</b> tab links to the general shared files published by the channel.</dd>
|
||||
</dl>
|
22
doc/context/profile/help.html
Normal file
22
doc/context/profile/help.html
Normal file
@ -0,0 +1,22 @@
|
||||
<script>
|
||||
var contextualHelp1 = function (target, openSidePanel) {
|
||||
$("#help-content").removeClass('help-content-open'); // Close the help panel
|
||||
$("#navbar-collapse-1").removeClass('in'); // Collapse the navbar for small screens
|
||||
if (openSidePanel) {
|
||||
$("main").addClass('region_1-on'); // Open the side panel to highlight element
|
||||
} else {
|
||||
$("main").removeClass('region_1-on');
|
||||
}
|
||||
// Animate the page scroll to the element and then pulse the element to direct attention
|
||||
$('html,body').animate({scrollTop: $(target).offset().top - $('#navbar-collapse-1').height() - 20}, 'slow');
|
||||
for (i = 0; i < 3; i++) {
|
||||
$(target).fadeTo('slow', 0.1).fadeTo('slow', 1.0);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>General</dt>
|
||||
<dd>This is the profile page of a channel. It typically displays information describing the channel. If the channel represents a person in a social network, for example, then the profile might provide contact information and other personal details about the person. Channels can have multiple profiles, where the displayed profile depends on the observer.</dd>
|
||||
<dt><a href='#' onclick='contextualHelp1("#tabs-collapse-1", 0); return false;' title="Click to highlight element...">Channel Content Tabs</a></dt>
|
||||
<dd>The channel content tabs are links to other content published by the channel. The <b>About</b> tab links to the channel profile. The <b>Photos</b> tab links to the channel photo galleries. The <b>Files</b> tab links to the general shared files published by the channel.</dd>
|
||||
</dl>
|
@ -1,27 +1,27 @@
|
||||
[table]
|
||||
[tr][th]Field[/th][th]Description[/th][th]Type[/th][th]Null[/th][th]Key[/th][th]Default[/th][th]Extra
|
||||
[/th][/tr]
|
||||
[tr][td]tid[/td][td][/td][td]int(10) unsigned[/td][td]NO[/td][td]PRI[/td][td]NULL[/td][td]auto_increment
|
||||
[tr][td]tid[/td][td]sequential index[/td][td]int(10) unsigned[/td][td]NO[/td][td]PRI[/td][td]NULL[/td][td]auto_increment
|
||||
[/td][/tr]
|
||||
[tr][td]aid[/td][td][/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||
[tr][td]aid[/td][td]channel_account_id of the controlling channel[/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||
[/td][/tr]
|
||||
[tr][td]uid[/td][td][/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||
[tr][td]uid[/td][td]channel_id of the controlling channel[/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]0[/td][td]
|
||||
[/td][/tr]
|
||||
[tr][td]oid[/td][td][/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||
[tr][td]oid[/td][td]DB index of linked thing[/td][td]int(10) unsigned[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||
[/td][/tr]
|
||||
[tr][td]otype[/td][td][/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]
|
||||
[tr][td]type[/td][td][/td][td]tinyint(3) unsigned[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||
[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]
|
||||
[/td][/tr]
|
||||
[tr][td]term[/td][td][/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]
|
||||
[tr][td]url[/td][td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||
[tr][td]url[/td]relevant link (for tags and mentions, a link to the associated resource)[td][/td][td]char(255)[/td][td]NO[/td][td][/td][td]NULL[/td][td]
|
||||
[/td][/tr]
|
||||
[tr][td]imgurl[/td][td][/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||
[tr][td]imgurl[/td][td]rarely used - an image associated with this taxonomy term[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td]NULL[/td][td]
|
||||
[/td][/tr]
|
||||
[tr][td]term_hash[/td][td][/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td][/td][td]
|
||||
[tr][td]term_hash[/td][td]unique hash for this entry[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td][/td][td]
|
||||
[/td][/tr]
|
||||
[tr][td]parent_hash[/td][td][/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td][/td][td]
|
||||
[tr][td]parent_hash[/td][td]for hierarchical taxonomies, the hash of the relevant parent[/td][td]char(255)[/td][td]NO[/td][td]MUL[/td][td][/td][td]
|
||||
[/td][/tr]
|
||||
[/table]
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
[h3]Externe Ressourcen[/h3]
|
||||
[zrl=[baseurl]/help/external-resource-links]Links zu externen Ressourcen[/zrl]
|
||||
|
||||
[url=https://github.com/redmatrix/redmatrix]Haupt-Website[/url]
|
||||
[url=https://github.com/redmatrix/redmatrix-addons]Addons-Website[/url]
|
||||
[url=https://github.com/redmatrix/hubzilla]Haupt-Website[/url]
|
||||
[url=https://github.com/redmatrix/hubzilla-addons]Addons-Website[/url]
|
||||
|
||||
[url=[baseurl]/help/credits]$Projectname Credits[/url]
|
||||
|
||||
|
@ -21,7 +21,7 @@ Returns the global app structure ($a).
|
||||
|
||||
* App::get_observer()
|
||||
|
||||
(App:: is usually assigned to the global $a), so $a->get_observer() or get_app()->get_observer() - returns an xchan structure representing the current viewer if authenticated (locally or remotely).
|
||||
(App:: is usually assigned to the global $a), so App::get_observer() or App::get_observer() - returns an xchan structure representing the current viewer if authenticated (locally or remotely).
|
||||
|
||||
* get_config($family,$key), get_pconfig($uid,$family,$key)
|
||||
|
||||
|
@ -242,7 +242,7 @@ Befor you register a first user switch off the registration mails.
|
||||
Open /var/www/.htconfig.php
|
||||
and make sure "0" is set in this line
|
||||
[code]
|
||||
$a->config['system']['verify_email'] = 0;
|
||||
App::$config['system']['verify_email'] = 0;
|
||||
[/code]
|
||||
You should be able to change the file as "yourself" (instead of using root or www-data).
|
||||
|
||||
|
@ -30,7 +30,7 @@ To configure this, please look in your .htconfig.php file for the following text
|
||||
// DIRECTORY_MODE_PRIMARY = main directory server
|
||||
// DIRECTORY_MODE_STANDALONE = "off the grid" or private directory services
|
||||
|
||||
$a->config['system']['directory_mode'] = DIRECTORY_MODE_STANDALONE;
|
||||
App::$config['system']['directory_mode'] = DIRECTORY_MODE_STANDALONE;
|
||||
[/code]
|
||||
|
||||
|
||||
|
@ -47,9 +47,9 @@ Private messages are encrypted during transport and storage. In this day and age
|
||||
|
||||
This provides the ability to select posts by date ranges
|
||||
|
||||
[b]Collections Filter[/b]
|
||||
[b]Privacy Group Filter[/b]
|
||||
|
||||
Enable widget to display stream posts only from selected collections. This also toggles the outbound permissions while you are viewing a collection. This is analogous to Google "circles" or Disapora "aspects".
|
||||
Enable widget to display stream posts only from selected privacy groups. This also toggles the outbound permissions while you are viewing a group. This is analogous to Google "circles" or Disapora "aspects".
|
||||
|
||||
[b]Saved Searches[/b]
|
||||
|
||||
|
@ -8,22 +8,22 @@ $a is a class defined in boot.php and passed all around $Projectname as a global
|
||||
|
||||
We don't ever create more than one instance and always modify the elements of the single instance. The mechanics of this are somewhat tricky. If you have a function that is passed $a and needs to modify $a you need to declare it as a reference with '&' e.g.
|
||||
|
||||
[code]function foo(&$a) { $a->something = 'x'; // whatever };
|
||||
[code]function foo(&$a) { App::$something = 'x'; // whatever };
|
||||
|
||||
*or* access it within your function as a global variable via get_app()
|
||||
|
||||
function foo() {
|
||||
$a = get_app();
|
||||
$a->something = 'x';
|
||||
App::$something = 'x';
|
||||
}
|
||||
|
||||
|
||||
function foo($a) { $a->something = 'x'; };
|
||||
function foo($a) { App::$something = 'x'; };
|
||||
|
||||
will *not* change the global app state.
|
||||
|
||||
function foo() {
|
||||
get_app()->something = 'x';
|
||||
App::$something = 'x';
|
||||
}
|
||||
[/code]
|
||||
|
||||
|
@ -8,7 +8,7 @@ Short anser: No, there isn't. There are reasons. You are able to change permisso
|
||||
If a posting is public this is even harder, as the $Projectname is a global network and there is no way to follow a post, let alone reclaim it reliably. Other networks that may receive your post have no reliable way to delete or reclaim the post.
|
||||
|
||||
[h3]I downloaded my channel and imported it (cloned my identity) to another site but there is no content, no posts, no photos. What is wrong???[/h3]
|
||||
To be honest: Nothing. That's the way it is right now. Technically it is surely possible to take at least your own posts and maybe even files with you, but this has simply put not implemented yet. When creating this feature we thought that keeping all your contacts was more important. Your friends have already seen your old content. Once we find someone willing to implement this, it will be done. :)
|
||||
Posts and photos/files are provided separately from the channel basic information. This is due to memory limitations dealing with years of conversations and photo archives. Posts and conversations can be synced separately from the basic channel information. Photos and file archives can be transferred using a plugin tool such as 'redfiles', which is currently listed as "experimental". When creating this feature we thought that keeping all your contacts was the most important task. Your friends have already seen your old content. Posts/conversations were next in priority and these may now be synced. Files and photos are the last bit to get completely working. Once we find someone willing to finish implementing this, it will be done. :)
|
||||
[h3]I can't see private resources[/h3]
|
||||
You have probably disabled third party cookies. You need to enable them for remote authentication to work.
|
||||
[h3]There are a lot of foreign language posts. Let's auto-translate them.[/h3]
|
||||
|
@ -106,9 +106,9 @@ There is also experimental support for OpenID authentication which may be used i
|
||||
|
||||
Channels may have permissions to become "derivative channels" where two or more existing channels combine to create a new topical channel.
|
||||
|
||||
[b]Collections[/b]
|
||||
[b]Privacy Groups[/b]
|
||||
|
||||
"Collections" is our implementation of privacy groups, which is similar to Google "Circles" and Diaspora "Aspects". This allows you to filter your incoming stream by collections or groups, and automatically set the outbound Access Control List to only those in the Collection when you post. You may over-ride this at any time (prior to sending the post).
|
||||
Our implementation of privacy groups is similar to Google "Circles" and Diaspora "Aspects". This allows you to filter your incoming stream by selected groups, and automatically set the outbound Access Control List to only those in that privacy group when you post. You may over-ride this at any time (prior to sending the post).
|
||||
|
||||
|
||||
[b]Directory Services[/b]
|
||||
|
71
doc/federate.bb
Normal file
71
doc/federate.bb
Normal file
@ -0,0 +1,71 @@
|
||||
[h2]Creating protocol federation services[/h2]
|
||||
|
||||
There are three main components to writing federation plugins. These are:
|
||||
|
||||
[1] Channel discovery and making connections
|
||||
[2] Sending posts/messages
|
||||
[3] Receiving posts/messages
|
||||
|
||||
In addition, federation drivers must handle
|
||||
|
||||
[4] differences in privacy policies (and content formats)
|
||||
|
||||
|
||||
[h3]Making connections[/h3]
|
||||
|
||||
The core application provides channel discovery in the following sequence:
|
||||
|
||||
[1] Zot channel discovery
|
||||
[2] Webfinger (channel@hub) lookup
|
||||
[2.1] RFC7033 webfinger
|
||||
[2.2] XRD based webfinger (old style)
|
||||
[3] URL discovery (currently only used to discover RSS feeds)
|
||||
[4] If all of these fail, the network is "unknown" and we are unable to communicate with or connect with the channel. An 'xchan' record [i]may[/i] still be created [b]if[/b] there is enough information known to identify a unique channel.
|
||||
|
||||
Any of the lookup services may be bound to a plugin and extended. When a channel is discovered, we create an 'xchan' record which is a platform neutral representation of the channel identity. If we need to send information to the channel, a 'hubloc' (hub location) record is also generally required. A 'follow' plugin hook is provided to bypass webfinger and this discovery sequence completely.
|
||||
|
||||
The final step in gluing this together is to create an 'abook' record, which attaches an xchan in a relationship to a local channel with a given set of permissions.
|
||||
|
||||
For networks which do not support nomadic identity, your plugin must also set "abook_instance" which is a comma-separated list of local URLs that the remote channel is connected with. For instance if your member was connected to my channel clone at https://example.com, the abook_instance for that connection would read 'https://example.com'. If you also connected to my clone at https://abc.example.com, the string would be changed to 'https://example.com,https://abc.example.com'. This allows local channels to differentiate which instance a given remote channel is connected with and avoid delivery failures to those channels from other clone instances.
|
||||
|
||||
A federation plugin for a webfinger based system needs only to examine the webfinger or XRD results and identify a protocol stack which can be used to connect or communicate. Then create an xchan record with the given 'xchan_network' type and a hubloc record with the same 'hubloc_network' with the information given. Currently the plugin will need to create the entire record, but in the future this will be extended so that the plugin only need identify a network name and the record will be populated with all other known values.
|
||||
|
||||
An xchan record is always required in order to connect. To connect, create an abook record with the desired permissions.
|
||||
|
||||
Additional information that your plugin requires for communication can be stored in the xconfig table and/or abconfig table if there is no convenient or appropriate table column in the xchan or hubloc tables.
|
||||
|
||||
When a connection is made, we generally call the notifier (include/notifier.php) to send a message to the remote channel. This is bound to the hook 'permissions_create'. Your plugin will need to handle this in order to send a "follow" or "make friends" message to the other network.
|
||||
|
||||
Notes: The first stage zot lookup will be replaced with a webfinger lookup. This work is in progress. A separate lookup was required initially as webfinger does not allow non-SSL connections. We will provide non-SSL zot lookups (usually test and development sites) via the "old" XRD based webfinger to avoid this limitation.
|
||||
|
||||
The core application will attempt to create xchan records for projects identified as members of the "open web"; currently Hubzilla, Friendica, Diaspora, GNU-Social and Pump.io. This is so that comments can be passed amongst project sites and the network correctly identified. A federation plugin is required to fully federate with other networks, but comments may be passed to sites without such a plugin installed so that there are no unexplained holes in conversations.
|
||||
|
||||
The core application must also provide signing ability for Diaspora comments since they require a special signing format and must be signed by the comment author regardless of whether that channel federates with Diaspora. The owner of the conversation may federate with Diaspora so the comments must be signed. This is unfortunate but necessary.
|
||||
|
||||
|
||||
[h3]Sending Messages[/h3]
|
||||
|
||||
Whenever any message is sent (with the sole exception of directory communications), we invoke the notifier (include/notifier.php), and pass it the type of message and generally an identifier to lookup the information being sent from the database (items or conversational things, private mail, permissions updates, etc.).
|
||||
|
||||
The notifier has several hooks which may be used by plugins in different ways, depending on how their delivery loop works. For different message types and complex delivery situations you may need to tie into multiple hooks. The 'permissions_create' hook was mentioned in the first section. There is also a 'permissions_update' message if permissions have changed and the other end of the link needs to be advised. Few services will provide or handle this (as their permissions are static), but it is also used for instance to send profile and profile photo update messages and you may wish to handle this.
|
||||
|
||||
The next plugin hook is 'notifier_process'. It is passed an array providing the complete state of the notifier and is called once per notifier invocation. It contains the complete list of recipients (with xchan_network set for each).
|
||||
|
||||
There is also 'notifier_hub' which like 'notifier_process' is passed the complete state of the notifier, but the difference is that it is called for each individual hub or distinct URL delivery and may be matched on the hubloc_network type. Hub delivery is much more efficient than recipient delivery but may not be suitable for all protocol stacks.
|
||||
|
||||
|
||||
Your plugin will be required to understand the message state and recipients and translate the sent item to the desired format. You will also be required to check privacy and block communication to anybody but the intended recipients - *if* it is a private communication. The plugin will often at this point stick the message into the queue and return the queue id to the notifier.
|
||||
|
||||
|
||||
Queue handlers exist already for simple posted data. If you create a queue entry with 'post' type we'll open an HTTP POST request and post the data provided and acknowledge success or failure. You can create other forms of communication by providing a different outq_driver type and handling the processing of queue requests yourself. Delivery reporting is available if you wish to acknowledge different error conditions, or anything beyond success/failure. Advanced delivery reporting will also require a custom queue type. The basic 'post' type only deals with success (communication successful with the remote site) and failure.
|
||||
|
||||
|
||||
|
||||
[h3]Receiving Messages[/h3]
|
||||
|
||||
|
||||
Receiving messages from the remote network will probably require a 'receive' endpoint or module dedicated to your network communication protocol. This is a URL route that your plugin may need to register with the'module_loaded' hook. You module will then take responsibility for importing any data which arrives at that endpoint and translating it to the format required for this project and storing the resulting data. The basic structure we use is an extensible activitystream item but with slightly different field names and several optional fields. It can be easily mapped to an activitystream. Additional data can be stored in the "iconfig" table. item_store() and item_store_update() are generally used to store the data and send appropriate notifications. Similiar facilities are available for private mail and profile information.
|
||||
|
||||
|
||||
|
||||
|
61
doc/filesync.md
Normal file
61
doc/filesync.md
Normal file
@ -0,0 +1,61 @@
|
||||
File Sync and Clone
|
||||
===================
|
||||
|
||||
|
||||
|
||||
File cloning across multiple instances of a channel is a very hard problem, due to the nature of PHP memory allocation. This needs to be handled dramatically differently than cloning or syncing of other information. (Processing one large video file or 40-50 photos could exhaust memory). Therefore we can't easily just dump all the data to a dump file and sequentially process it. Loading the dump file itself is likely to exhaust memory.
|
||||
|
||||
There are also two primary operations we are considering. The first is the hardest - saving and then importing all your channel information into a new channel clone. The second is synchronising file changes as they occur across two or more "active" clones.
|
||||
|
||||
For the first cut at this tool we will concentrate on the second case, while trying to maintain some measure of compatibility with the first case so that we can re-use the same tools.
|
||||
|
||||
Meta Data
|
||||
=========
|
||||
|
||||
|
||||
First we need the metadata for the file in order to precisely re-construct its structure on another site. This requires the following information:
|
||||
|
||||
'attach' structure (without file contents - which is the default) for the file itself **and** its parent directories so that we can re-create its precise place in the file system, since we do not know if the parent directory has been imported previously or ever.
|
||||
|
||||
'photo' structure for any photo elements which were created as a result of uploading this file into the system. This typically contains several different 'scales' or thumbnail images, some of which may be cropped for profile photo use or cover photo use. We need to retain the cropping information which is not present in the metadata, but only in the stored data. The actual thumbnail image data may or may not be included in the metadata. A cover photo of large scale (scale #7) could potentially cause memory issues. Not as bad as a 100M video, but if you have several of these they could add up.
|
||||
|
||||
'item' entries which are linked to this file. These can be file share activities, the "parent item" linked to photos, and any attached conversation items (photo likes, comments, etc.)
|
||||
|
||||
All of these items will require URL replacement and re-signing of the item as they are relocated to another site.
|
||||
|
||||
|
||||
File Data
|
||||
=========
|
||||
|
||||
Then we have the actual file data we need to reconstruct the file. This needs to be stored separately from the meta-data to avoid memory exhaustion when processing. The actual file data can be used to reconstruct the attach structure and the first four photo scales. If this is a photo, we need access to the "#4 scale" (profile photo) and the #7 scale (cover photo) as they were originally cropped. All other thumbnails can be generated from these.
|
||||
|
||||
|
||||
|
||||
File Sync
|
||||
=========
|
||||
|
||||
|
||||
We will consider this operation first because it is probably the most straightforward to implement. When a photo is added to or removed or changed from the source system, we will send a clone sync packet to all known clones containing the metadata - but **no file data** . We can only send one sync packet per file operation that needs to be synced.
|
||||
|
||||
The receiving end will create and perform URL translation on all the metadata structures and store them. Then it will need to fetch the actual data. Assuming CURL supports streaming, an authenticated request is sent to the original site and the original file is requested and streamed directly to disk (bypassing all processing). If photo scale #4 or scale #7 is required, these are requested and stored into their respective structures. We're assuming in this case that the cover photo large scale will not exhaust memory. If CURL cannot be made to support streaming, request packets need to be queued and sent to the origination site to obtain "chunks" of the file and re-assembled once all chunks have been retrieved.
|
||||
|
||||
The authenticated request depends on the mechanism. For CURL streaming, some signed secret with a timestamp will probably need to be generated and posted to the file origination site. Then the data can be retrieved with minimal internal processing and dumped directly to disk using stdio buffering. In the case of a zot request, the zot request packet will be validated, however scheduling chunk batches and re-assembling them could be tricky.
|
||||
|
||||
|
||||
File Backup/Restore
|
||||
===================
|
||||
|
||||
This is much more complicated as we do not have an authenticate web server to request data from. The metadata can be mostly the same, but we need some form of signalling that we will not be fetching the file via the web. This will likely require a client side process to parse each metadata file and locate a file on disk which it is associated with. Then the data would need to be streamed to the destination server with a special endpoint designed for this task. A java app might be the best option here to retain platform neutrality.
|
||||
|
||||
Another option would be to use WebDAV for this step. The metadata files would be uploaded first, and then the data files. If a data file corresponded to an existing metadata file, the metadata would be processed; the file stored appropriately, and the metadata file then removed. In this case, photos of scales 4 and 7 would need to be provided in the metadata.
|
||||
|
||||
|
||||
Optionally, this step could also be performed with a filesystem local to the destination server. This would be the highest performance, and a suite of shell-based tools (in the case of Linux) could perform the "client-side" of the task.
|
||||
|
||||
The complexity of this task mandates careful planning into how the data is organised and stored and if necessary backed up remotely or transmitted for backup by the source website.
|
||||
|
||||
|
||||
Backward Compatibility
|
||||
======================
|
||||
|
||||
There are some obvious issues with making data available for backup or cloning which existed on the system prior to the existence of restore/sync tools. To keep the tools themselves relatively uncomplicated (to the extent possible given the constraints) backward compatibility may have to be preformed by dedicated plugin or addon.
|
25
doc/fr/about.bb
Normal file
25
doc/fr/about.bb
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
$Projectname est un réseau de communication décentralisé, qui a pour but de proposer un moyen de communication qui est résistant à la censure, respecte la confidentialité et qui est indépendant des grandes companies mondiales. Ces companies géantes fonctionnent comme des espions. Ce sont des monopoles centralisés sur internet. A l'orignie internet ne fonctionnait pas ainsi, il était décentralisé.
|
||||
|
||||
$Projectname est libre et open source. Il est conçu pour pouvoir monter en charge depuis un petite Raspberry Pi jusqu'à un serveur puissant à plusieurs coeurs. Il peut être utilisé pour servir de moyen de communication entre quelques individus mais peut monter pour héberger plusieurs milliers d'utilisateurs.
|
||||
|
||||
$Projectname a pour but d'être utilisable sans documentation. Il est facile à utiliser pour un usage quotidien pour un utilisateur moyen mais aussi par des administrateurs système ou des développeurs.
|
||||
|
||||
Comment utiliser ? Cela dépend de ce que vous voulez en faire.
|
||||
|
||||
Il est écrit en php. Cela le rend facile à installer sur des hébergement actuels.
|
||||
|
||||
It is written in the PHP scripting language, thus making it trivial to install on any hosting platform in use today comme par exemple [url=http://mediatemple.com/]Media Temple[/url] ou bien [url=http://www.dreamhost.com/r.cgi?455365/]Dreamhost[/url] ou bien encore [url=https://www.linode.com]Linode[/url], [url=http://greenqloud.com]GreenQloud[/url] ou [url=https://aws.amazon.com]Amazon AWS[/url]. Il fonctionne aussi trés bien sur un VPS de OVH.
|
||||
|
||||
En d'autres mots, $Projectname peut tourner sur n'importe quelle plateforme qui a un serveur web, une base de donnée mysql et du php.
|
||||
|
||||
|
||||
En plus, $Projectname offre un grand nombre de suppléments :
|
||||
|
||||
[b]Identification en un clic :[/b] cela signifie que vous pouvez accéder à d'autres sits $Projectname simplement en cliquant sur un lien. L'authentificaiton se fera alors automatiquement sans mot de passe. Oubliez le temps ou il vous fallait un grand nom de mot de passe pour aller sur différents sites.
|
||||
|
||||
[b]Clone :[/b] Votre présence en ligne n'a plus besoin d'être faite sur un seul et unique site. Vous pouvez cloner ou importer votre identité (on peut aussi dire votre canal) sur un autre serveur (hub). Si votre serveur principal a des problème et s'arrête, pas de problème, vos contacts, vos messages seront continueront automatiquement à être accessible grĉe à votre canal clone. [i](*: Pour le moment seul les messages sont clonés)[/i]
|
||||
|
||||
[b]Confidentialité :[/b] Votre identité $Projectname (Zot IDs) peut être supprimé, sauvegardé ou cloné. L'utilisateur à le total contrôle sur ses donnés. Et si vous décidez de supprimer totalement votre compte avec tous le contenu, tout ce que vous avez à faire est de cliquer sur le bouton de suppression du compte. C'est immédiat. Aucune question ne vous sera posé sur la raion. Vous être libre de le faire quand vous voulez.
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
73
doc/fr/git_for_non_developers.bb
Normal file
73
doc/fr/git_for_non_developers.bb
Normal file
@ -0,0 +1,73 @@
|
||||
[b]Git pour les non développeurs[/b]
|
||||
|
||||
Bon vous traduivez ou contribuez à un thème et chaque fois que vous faites un pull request, vous devez parler avec un des développeurs avant que vos changements soient pris en compte.
|
||||
|
||||
Vous devez trouver un petit tutorial pour vous aider à maintenair les choses synchronisé. C'est trés facile
|
||||
|
||||
|
||||
|
||||
After you've created a fork of the repo (just click "fork" at github), you need to clone your own copy.
|
||||
|
||||
For the sake of examples, we'll assume you're working on a theme called redexample (which does not exist).
|
||||
|
||||
[code]git clone https://github.com/username/red.git[/code]
|
||||
|
||||
Once you've done that, cd into the directory, and add an upstream.
|
||||
|
||||
[code]
|
||||
cd red
|
||||
git remote add upstream https://github.com/redmatrix/redmatrix
|
||||
[/code]
|
||||
|
||||
From now on, you can pull upstream changes with the command
|
||||
[code]git fetch upstream[/code]
|
||||
|
||||
Before your changes can be merged automatically, you will often need to merge upstream changes.
|
||||
|
||||
[code]
|
||||
git merge upstream/master
|
||||
[/code]
|
||||
|
||||
You should always merge upstream before pushing any changes, and [i]must[/i] merge upstream with any pull requests to make them automatically mergeable.
|
||||
|
||||
99% of the time, this will all go well. The only time it won't is if somebody else has been editing the same files as you - and often, only if they have been editing the same lines of the same files. If that happens, that would be a good time to request help until you get the hang of handling your own merge conflicts.
|
||||
|
||||
Then you just need to add your changes [code]git add view/theme/redexample/[/code]
|
||||
|
||||
This will add all the files in view/theme/redexample and any subdirectories. If your particular files are mixed throughout the code, you should add one at a time. Try not to do git add -a, as this will add everything, including temporary files (we mostly, but not always catch those with a .gitignore) and any local changes you have, but did not intend to commit.
|
||||
|
||||
Once you have added all the files you have changed, you need to commit them. [code]git commit[/code]
|
||||
|
||||
This will open up an editor where you can describe the changes you have made. Save this file, and exit the editor.
|
||||
|
||||
Finally, push the changes to your own git
|
||||
[code]git push[/code]
|
||||
|
||||
And that's it, your repo is up to date!
|
||||
|
||||
All you need to do now is actually create the pull request. There are two ways to do this.
|
||||
|
||||
The easy way, if you're using Github is to simply click the green button at the top of your own copy of the repository, enter a description of the changes, and click 'create pull request'. The
|
||||
main repository, themes, and addons all have their main branch at Github, so this method can be used most of the time.
|
||||
|
||||
Most people can stop here.
|
||||
|
||||
Some projects in the extended RedMatrix ecosphere have no Github presence, to pull request these is a bit different - you'll have to create your pull request manually. Fortunately, this isn't
|
||||
much harder.
|
||||
|
||||
[code]git request-pull -p <start> <url>[/code]
|
||||
|
||||
Start is the name of a commit to start at. This must exist upstream. Normally, you just want master.
|
||||
|
||||
URL is the URL of [i]your[/i] repo.
|
||||
|
||||
One can also specify <end>. This defaults to HEAD.
|
||||
|
||||
Example:
|
||||
[code]
|
||||
git request-pull master https://example.com/project
|
||||
[/code]
|
||||
|
||||
And simply send the output to the project maintainer.
|
||||
|
||||
#include doc/macros/main_footer.bb;
|
12
doc/fr/main.bb
Normal file
12
doc/fr/main.bb
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
[zrl=[baseurl]/help/about][b]$Projectname c'est quoi ?[/b][/zrl]
|
||||
$Projectname est un logiciel de publication et de communication décentralisé qui vous permet de garder le contrôle de vos besoins et de vos données. C'est vous et seulement vous qui décidez qui vous autorisez à voir vos publications.
|
||||
|
||||
|
||||
[zrl=[baseurl]/help/features][b]$Projectname fonctionalités[/b][/zrl]
|
||||
$Projectname est un réseau global distribué qui est souple et peut monter en puissance depuis un petit site d'une personne jusqu'à pouvant héberger une communauté de nombreuses personnes.
|
||||
|
||||
$Projectname fonctionne en tant que réseau global distribué. Il est souple et peut monter en puissance. On peut l'utiliser pour une famille, pour une communauté en ligne, pour des forums, des blogs et des pages web.
|
||||
|
||||
[zrl=[baseurl]/help/what_is_zot][b]Zot c'est quoi ?[/b][/zrl]
|
||||
Zot est un protocole de communication inventé spécialement pour $Projectname. En tant que membre vous n'êtes plus lié à un site web unique ou à un hub grâce à l'identité nomade. Vous pouvez migrer facilement sur d'autres serveurs et garder vos contacts. Vous pouvez aussi cloner votre cannal et il se trouvera sur plusieurs serveurs. Au cas ou un serveur ne fonctionnerait plus, vous ne perdrez pas vos données. En plus si vous êtes dans $Projectname vous n'aurez plus besoin de vous identifier plusieurs fois même pour accéder à l'autres site $Projectname site. Zot est donc le coeur de $Projectname.
|
@ -14,7 +14,7 @@ Once you've done that, cd into the directory, and add an upstream.
|
||||
|
||||
[code]
|
||||
cd red
|
||||
git remote add upstream https://github.com/redmatrix/redmatrix
|
||||
git remote add upstream https://github.com/redmatrix/hubzilla
|
||||
[/code]
|
||||
|
||||
From now on, you can pull upstream changes with the command
|
||||
|
@ -3,7 +3,7 @@
|
||||
$Projectname contains many configuration options hidden from the main admin panel.
|
||||
|
||||
These are generally options considered too niche, confusing, or advanced for
|
||||
the average member. These settings can be activated from the the top level Red
|
||||
the average member. These settings can be activated from the the top level web
|
||||
directory with the syntax [code]util/config cat key value[/code] for a site
|
||||
configuration, or [code]util/pconfig channel_id cat key value[/code] for a
|
||||
member configuration.
|
||||
@ -11,14 +11,14 @@ member configuration.
|
||||
This document assumes you're an administrator.
|
||||
|
||||
[b]pconfig[/b]
|
||||
[b]system > user_scalable[/b]
|
||||
[b]system.user_scalable[/b]
|
||||
Determine if the app is scalable on touch screens. Defaults to on, to
|
||||
disable, set to zero - real zero, not just false.
|
||||
[b]system > always_my_theme[/b]
|
||||
[b]system.always_my_theme[/b]
|
||||
Always use your own theme when viewing channels on the same hub. This
|
||||
will break in some quite imaginative ways when viewing channels with
|
||||
theme dependent Comanche.
|
||||
[b]system > paranoia[/b]
|
||||
[b]system.paranoia[/b]
|
||||
Sets the security level of IP checking. If the IP address of a logged-in session changes
|
||||
apply this level to determine if the account should be logged out as a security breach.
|
||||
Options are:
|
||||
@ -26,151 +26,185 @@ This document assumes you're an administrator.
|
||||
1 - check 3 octets
|
||||
2 - check 2 octets
|
||||
3 - check for any difference at all
|
||||
[b]system > prevent_tag_hijacking[/b]
|
||||
[b]system.prevent_tag_hijacking[/b]
|
||||
Prevent foreign networks hijacking hashtags in your posts and directing them at its own resources.
|
||||
[b]system > blocked[/b]
|
||||
[b]system.blocked[/b]
|
||||
An array of xchans blocked by this channel. Technically, this is a
|
||||
hidden config and does belong here, however, addons (notably
|
||||
superblock) have made this available in the UI.
|
||||
[b]system > default_cipher[/b]
|
||||
[b]system.default_cipher[/b]
|
||||
Set the default cipher used for E2EE items.
|
||||
[b]system > network_page_default[/b]
|
||||
[b]system.network_page_default[/b]
|
||||
Set default params when viewing the network page. This should contain
|
||||
the same querystring as manual filtering.
|
||||
[b]system > display_friend_count[/b]
|
||||
[b]system.display_friend_count[/b]
|
||||
Set the number of connections to display in the connections profile
|
||||
widget.
|
||||
[b]system > taganyone[/b]
|
||||
[b]system.taganyone[/b]
|
||||
Requires the config of the same name to be enabled. Allow the @mention tagging
|
||||
of anyone, whether you are connected or not. This doesn't scale.
|
||||
[b]system > startpage[/b]
|
||||
[b]system.startpage[/b]
|
||||
Another of those technically hidden configs made available by addons.
|
||||
Sets the default page to view when logging in. This is exposed to the
|
||||
UI by the startpage addon.
|
||||
[b]system > forcepublicuploads[/b]
|
||||
[b]system.forcepublicuploads[/b]
|
||||
Force uploaded photos to be public when uploaded as wall items. It
|
||||
makes far more sense to just set your permissions properly in the first
|
||||
place. Do that instead.
|
||||
[b]system > do_not_track[/b]
|
||||
[b]system.do_not_track[/b]
|
||||
As the browser header. This will break many identity based features.
|
||||
You should really just set permissions that make sense.
|
||||
|
||||
[b]Site config[/b]
|
||||
[b]system > taganyone[/b]
|
||||
[b]system.taganyone[/b]
|
||||
Allow the @mention tagging of anyone whether you are connected or not.
|
||||
[b]system > directorytags[/b]
|
||||
Set the number of keyword tags displayed on the directory page.
|
||||
[b]system > startpage[/b]
|
||||
[b]system.directorytags[/b]
|
||||
Set the number of keyword tags displayed on the directory page. Default is 50 unless set to a
|
||||
positive integer.
|
||||
[b]system.disable_directory_keywords[/b]
|
||||
If '1', do not show directory keywords. If the hub is a directory server, prevent returning
|
||||
tags to any directory clients. Please do not set this for directory servers in the RED_GLOBAL realm.
|
||||
[b]system.disable_dreport[/b]
|
||||
If '1', don't store or link to delivery reports
|
||||
[b]system.startpage[/b]
|
||||
Set the default page to be taken to after a login for all channels at
|
||||
this website. Can be overwritten by user settings.
|
||||
[b]system > projecthome[/b]
|
||||
Set the project homepage as the homepage of your hub.
|
||||
[b]system > workflow_channel_next[/b]
|
||||
The page to direct users to immediately after creating a channel.
|
||||
[b]system > max_daily_registrations[/b]
|
||||
[b]system.projecthome[/b]
|
||||
Set the project homepage as the homepage of your hub. (Obsolete)
|
||||
[b]system.auto_channel_create[/b]
|
||||
Add the necessary form elements to create the first channel on the account registration page, and create it
|
||||
(possibly following email validation or administrator approval). This precludes the ability to import a channel
|
||||
from another site as the first channel created on this site for a new account.
|
||||
Use with system.default_permissions_role to streamline registration.
|
||||
[b]system.default_permissions_role[/b]
|
||||
If set to a valid permissions role name, use that role for
|
||||
the first channel created by a new account and don't ask for the "Channel Type" on
|
||||
the channel creation form. Examples of valid names are: 'social', 'social_restricted', 'social_private',
|
||||
'forum', 'forum_restricted' and 'forum_private'.
|
||||
Read more about permissions roles [zrl=[baseurl]/help/roles]here[/zrl].
|
||||
[b]system.workflow_channel_next[/b]
|
||||
The page to direct new members to immediately after creating a channel.
|
||||
[b]system.workflow_register_next[/b]
|
||||
The page to direct members to immediately after creating an account (only when auto_channel_create or UNO is enabled).
|
||||
[b]system.max_daily_registrations[/b]
|
||||
Set the maximum number of new registrations allowed on any day.
|
||||
Useful to prevent oversubscription after a bout of publicity
|
||||
for the project.
|
||||
[b]system > tos_url[/b]
|
||||
[b]system.tos_url[/b]
|
||||
Set an alternative link for the ToS location.
|
||||
[b]system > block_public_search[/b]
|
||||
[b]system.block_public_search[/b]
|
||||
Similar to block_public, except only blocks public access to
|
||||
search features. Useful for sites that want to be public, but
|
||||
keep getting hammered by search engines.
|
||||
[b]system > paranoia[/b]
|
||||
[b]system.proc_run_use_exec
|
||||
If 1, use the exec system call in proc_run to run background tasks. By default
|
||||
we use proc_open and proc_close. On some (currently rare) systems this does not work well.
|
||||
[b]system.paranoia[/b]
|
||||
As the pconfig, but on a site-wide basis. Can be overwritten
|
||||
by member settings.
|
||||
[b]system > openssl_conf_file[/b]
|
||||
[b]system.transport_security_header[/b]
|
||||
if non-zero and SSL is being used, include a strict-transport-security header on webpages
|
||||
[b]system.poke_basic[/b]
|
||||
Reduce the number of poke verbs to exactly 1 ("poke"). Disable other verbs.
|
||||
[b]system.openssl_conf_file[/b]
|
||||
Specify a file containing OpenSSL configuration. Read the code first.
|
||||
If you can't read the code, don't play with it.
|
||||
[b]system > optimize_items[/b]
|
||||
[b]system.optimize_items[/b]
|
||||
Runs optimise_table during some tasks to keep your database nice and
|
||||
defragmented. This comes at a performance cost while the operations
|
||||
are running, but also keeps things a bit faster while it's not.
|
||||
There also exist CLI utilities for performing this operation, which you
|
||||
may prefer, especially if you're a large site.
|
||||
[b]system > expire_limit
|
||||
[b]system.expire_limit
|
||||
Don't expire any more than this number of posts per channel per
|
||||
expiration run to keep from exhausting memory. Default 5000.
|
||||
[b]system > dlogfile[/b]
|
||||
[b]system.dlogfile[/b]
|
||||
Logfile to use for logging development errors. Exactly the same as
|
||||
logger otherwise. This isn't magic, and requires your own logging
|
||||
statements. Developer tool.
|
||||
[b]system > authlog[/b]
|
||||
[b]system.authlog[/b]
|
||||
Logfile to use for logging auth errors. Used to plug in to server
|
||||
side software such as fail2ban. Auth failures are still logged to
|
||||
the main logs as well.
|
||||
[b]system > hide_in_statistics[/b]
|
||||
[b]system.hide_in_statistics[/b]
|
||||
Tell the red statistics servers to completely hide this hub in hub lists.
|
||||
[b]system > reserved_channels[/b]
|
||||
[b]system.reserved_channels[/b]
|
||||
Don't allow members to register channels with this comma separated
|
||||
list of names (no spaces)
|
||||
[b]system > auto_follow[/b]
|
||||
[b]system.auto_follow[/b]
|
||||
Make the first channel of an account auto-follow channels listed here - comma separated list of webbies (member@hub addresses).
|
||||
[b]system > admin_email[/b]
|
||||
[b]system.admin_email[/b]
|
||||
Specifies the administrator's email for this site. This is initially set during install.
|
||||
[b]system > cron_hour[/b]
|
||||
[b]system.cron_hour[/b]
|
||||
Specify an hour in which to run cron_daily. By default with no config, this will run at midnight UTC.
|
||||
[b]system > minimum_feedcheck_minutes[/b]
|
||||
[b]system.minimum_feedcheck_minutes[/b]
|
||||
The minimum interval between polling RSS feeds. If this is lower than the cron interval, feeds will be polled with each cronjob. Defaults to 60 if not set. The site setting can also be over-ridden on a channel by channel basis by a service class setting aptly named 'minimum_feedcheck_minutes'.
|
||||
[b]system > blacklisted_sites[/b]
|
||||
[b]system.blacklisted_sites[/b]
|
||||
An array of specific hubs to block from this hub completely.
|
||||
[b]system > ignore_imagick[/b]
|
||||
[b]system.ignore_imagick[/b]
|
||||
Ignore imagick and use GD, even if imagick is installed on the server. Prevents some issues with PNG files in older versions of imagick.
|
||||
[b]system > no_age_restriction[/b]
|
||||
[b]system.no_age_restriction[/b]
|
||||
Do not restrict registration to people over the age of 13. This carries legal responsibilities in many countries to require that age be provided and to block all personal information from minors, so please check your local laws before changing.
|
||||
[b]system > override_poll_lockfile[/b]
|
||||
[b]system.override_poll_lockfile[/b]
|
||||
Ignore the lock file in the poller process to allow more than one process to run at a time.
|
||||
[b]system > projecthome[/b]
|
||||
[b]system.projecthome[/b]
|
||||
Display the project page on your home page for logged out viewers.
|
||||
[b]system > sellpage[/b]
|
||||
[b]system.sellpage[/b]
|
||||
A URL shown in the public sites list to sell your hub - display service classes, etc.
|
||||
[b]randprofile > check[/b]
|
||||
[b]randprofile.check[/b]
|
||||
When requesting a random profile, check that it actually exists first
|
||||
[b]randprofile > retry[/b]
|
||||
[b]randprofile.retry[/b]
|
||||
Number of times to retry getting a random profile
|
||||
[b]system > photo_cache_time[/b]
|
||||
[b]system.photo_cache_time[/b]
|
||||
How long to cache photos, in seconds. Default is 86400 (1 day).
|
||||
Longer time increases performance, but it also means it takes longer for changed permissions to apply.
|
||||
[b]system > poco_rating_enable[/b]
|
||||
[b]system.poco_rating_enable[/b]
|
||||
Distributed reputation reporting and data collection may be disabled. If your site does not participate in distributed reputation you will also not be able to make use of the data from your connections on other sites. By default and in the absence of any setting it is enabled. Individual members can opt out by restricting who can see their connections or by not providing any reputation information for their connections.
|
||||
[b]system > register_link[/b]
|
||||
[b]system.register_link[/b]
|
||||
path to direct to from the "register" link on the login form. On closed sites this will direct to 'pubsites'. For open sites it will normally redirect to 'register' but you may change this to a custom site page offering subscriptions or whatever.
|
||||
[b]system > max_import_size[/b]
|
||||
[b]system.max_import_size[/b]
|
||||
If configured, the maximum length of an imported text message. This is normally left at 200Kbytes or more to accomodate Friendica private photos, which are embedded.
|
||||
[b]system > tempdir[/b]
|
||||
Place to store temporary files, default is defined in the PHP configuration
|
||||
[b]system > uploaddir[/b]
|
||||
Location to upload files (default is system.tempdir)
|
||||
[b]system > disable_discover_tab[/b]
|
||||
[b]system.tempdir[/b]
|
||||
Place to store temporary files (currently unused), default is defined in the PHP configuration
|
||||
[b]system.uploaddir[/b]
|
||||
Location to upload files (default is system.tempdir, currently used only by js_upload plugin)
|
||||
[b]system.disable_discover_tab[/b]
|
||||
This allows you to completely disable the ability to discover public content from external sites.
|
||||
[b]system > sys_expire_days[/b]
|
||||
[b]system.sys_expire_days[/b]
|
||||
How many days to keep discovered public content from other sites
|
||||
[b]system > openssl_encrypt[/b]
|
||||
[b]system.openssl_encrypt[/b]
|
||||
Use openssl encryption engine, default is false (uses mcrypt for AES encryption)
|
||||
[b]system > max_tagged_forums[/b]
|
||||
[b]system.max_tagged_forums[/b]
|
||||
Spam prevention. Limits the number of tagged forums which are recognised in any post. Default is 2. Only the first 'n' tags will be delivered as forums, the others will not cause any delivery.
|
||||
[b]system > openssl_conf_file[/b]
|
||||
[b]system.openssl_conf_file[/b]
|
||||
Needed in some Windows installations to locate the openssl configuration file on the system.
|
||||
[b]system > hide_help[/b]
|
||||
[b]system.hide_help[/b]
|
||||
Don't display help documentation link in nav bar
|
||||
[b]system > expire_delivery_reports[/b]
|
||||
Expiration in days for delivery reports - default 30
|
||||
[b]system.expire_delivery_reports[/b]
|
||||
Expiration in days for delivery reports - default 10
|
||||
[b]system.platform_name[/b] *
|
||||
What to report as the platform name in webpages and statistics. (*) Must be set in .htconfig.php
|
||||
[b]system.hide_version[/b] *
|
||||
If true, do not report the software version on webpages and tools. (*) Must be set in .htconfig.php
|
||||
[b]system.hidden_version_siteinfo[/b]
|
||||
If true, do not report the software version on siteinfo pages (system.hide_version also hides the version on these pages, this setting *only* hides the version on siteinfo pages).
|
||||
[b]system.email_notify_icon_url[/b]
|
||||
URL of image (32x32) to display in email notifications (HTML bodies).
|
||||
|
||||
[b]Directory config[/b]
|
||||
[b]Directory search defaults[/b]
|
||||
[b]directory > safemode[/b]
|
||||
[b]directory.safemode[/b]
|
||||
0 or 1.
|
||||
[b]directory > globaldir[/b]
|
||||
[b]directory.globaldir[/b]
|
||||
0 or 1. Default 0. If you visit the directory on a site you'll just see the members of that site by default. You have to go through an extra step to see the people in the rest of the network; and by doing so there's a clear delineation that these people *aren't* members of that site but of a larger network.
|
||||
[b]directory > pubforums[/b]
|
||||
[b]directory.pubforums[/b]
|
||||
0 or 1. Public forums *should* be default 0.
|
||||
[b]Directory server configuration (see [zrl=[baseurl]/help/directories]help/directories[/zrl])[/b]
|
||||
[b]system > directory_server[/b]
|
||||
[b]system > directory_primary[/b]
|
||||
[b]system > directory_realm[/b]
|
||||
[b]system > realm_token[/b]
|
||||
[b]system > directory_mode[/b]
|
||||
[b]system.directory_server[/b]
|
||||
[b]system.directory_primary[/b]
|
||||
[b]system.directory_realm[/b]
|
||||
[b]system.realm_token[/b]
|
||||
[b]system.directory_mode[/b]
|
||||
|
||||
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
[h2]discover_by_webbie[/h2]
|
14
doc/hook/discover_channel_webfinger.bb
Normal file
14
doc/hook/discover_channel_webfinger.bb
Normal file
@ -0,0 +1,14 @@
|
||||
[h2]discover_channel_webfinger[/h2]
|
||||
|
||||
Called after performing channel discovery using RFC7033 webfinger and where the channel is not recognised as zot.
|
||||
|
||||
Passed an array:
|
||||
|
||||
address: URL or address that is being discovered
|
||||
success: set to true if the plugin discovers something
|
||||
webfinger: array of webfinger links (output of webfinger_rfc7033())
|
||||
|
||||
|
||||
if your plugin indicates success you are expected to generate and populate an xchan (and hubloc) record prior to returning.
|
||||
|
||||
|
@ -8,5 +8,5 @@ The hook data for this call consists of an array
|
||||
|
||||
This element contains the HTML content which was prepared for this page by calling the module_content() function. It is invoked after the content has been created. It does not contain the result of AJAX or asynchronous page load calls.
|
||||
|
||||
The current module may be determined by lookin at $a->module
|
||||
The current module may be determined by lookin at App::$module
|
||||
|
||||
|
@ -6,5 +6,5 @@ The hook data for this call consists of an array
|
||||
|
||||
This element contains the HTML content before calling the module_content() function. It is invoked before the content region has been populated. This may or may not be empty as there may be other processes or addons generating content prior to your hook handler is run. Be certain to preserve any current content. Typically anything you add here will be placed at the top of the content region of the page, but in any event prior to the main content region being generated.
|
||||
|
||||
The current module may be determined by lookin at $a->module
|
||||
The current module may be determined by lookin at App::$module
|
||||
|
||||
|
@ -127,7 +127,7 @@ Hooks allow plugins/addons to "hook into" the code at many points and alter the
|
||||
[zrl=[baseurl]/help/hook/directory_item]directory_item[/zrl]
|
||||
Called when generating a directory listing for display
|
||||
|
||||
[zrl=[baseurl]/help/hook/discover_by_webbie]discover_by_webbie[/zrl]
|
||||
[zrl=[baseurl]/help/hook/discover_channel_webfinger]discover_channel_webfinger[/zrl]
|
||||
Called when performing a webfinger lookup
|
||||
|
||||
[zrl=[baseurl]/help/hook/display_item]display_item[/zrl]
|
||||
|
10
doc/roles.md
10
doc/roles.md
@ -11,11 +11,11 @@ The channel is a typical social networking profile. By default posts and publish
|
||||
|
||||
**Restricted**
|
||||
|
||||
By default all posts and published items are sent to your 'Friends' collection and not made public. New friends are added to this collection. You can over-ride this and create a public post or published item if you desire. You are listed in the directory. Your online presence (for chat) and your connections (friends) are visible to your profile viewers.
|
||||
By default all posts and published items are sent to your 'Friends' privacy group and not made public. New friends are added to this privacy group. You can over-ride this and create a public post or published item if you desire. You are listed in the directory. Your online presence (for chat) and your connections (friends) are visible to your profile viewers.
|
||||
|
||||
**Private**
|
||||
|
||||
By default all posts and published items are sent to your 'Friends' collection. New friends are added to this collection. You can over-ride this and create a public post or public item if you desire. You are NOT listed in the directory. Only your connections can see your other connections. Your online presence is hidden.
|
||||
By default all posts and published items are sent to your 'Friends' privacy group. New friends are added to this privacy group. You can over-ride this and create a public post or public item if you desire. You are NOT listed in the directory. Only your connections can see your other connections. Your online presence is hidden.
|
||||
|
||||
|
||||
##Forum
|
||||
@ -27,11 +27,11 @@ The channel is a typical forum. By default posts and published items are public.
|
||||
|
||||
**Restricted**
|
||||
|
||||
By default all posts and published items are sent to the channel's 'Friends' collection. New friends are added to this collection. Members may post by @mention+ or wall-to-wall post, but posts and replies may also be seen by other receipients of the top-level post who are not members. The channel is visible in the directory. Members must be manually added by the forum owner.
|
||||
By default all posts and published items are sent to the channel's 'Friends' privacy group. New friends are added to this privacy group. Members may post by @mention+ or wall-to-wall post, but posts and replies may also be seen by other receipients of the top-level post who are not members. The channel is visible in the directory. Members must be manually added by the forum owner.
|
||||
|
||||
**Private**
|
||||
|
||||
By default all posts and published items are sent to your 'Friends' collection. New friends are added to this collection. The owner can over-ride this and create a public post or public item if desired. Members cannot. You are NOT listed in the directory. Only your connections can see your other connections. Your online presence is hidden. Members must be manually added by the forum owner. Posting by @mention+ is disabled. Posts can only be made via wall-to-wall posts, and sent to members of the 'Friends' collection. They are not publicly visible.
|
||||
By default all posts and published items are sent to your 'Friends' privacy group. New friends are added to this privacy group. The owner can over-ride this and create a public post or public item if desired. Members cannot. You are NOT listed in the directory. Only your connections can see your other connections. Your online presence is hidden. Members must be manually added by the forum owner. Posting by @mention+ is disabled. Posts can only be made via wall-to-wall posts, and sent to members of the 'Friends' privacy group. They are not publicly visible.
|
||||
|
||||
|
||||
##Feed
|
||||
@ -44,7 +44,7 @@ Similiar to Social - Mostly Public, but tailored for RSS feed sources. Items may
|
||||
|
||||
**Restricted**
|
||||
|
||||
Not listed in directory. Online presence is meaningless, therefore hidden. Feed is published only to members of the 'Friends' collection. New connections are automatically added to this collections. Members must be manually approved by the channel owner.
|
||||
Not listed in directory. Online presence is meaningless, therefore hidden. Feed is published only to members of the 'Friends' privacy group. New connections are automatically added to this privacy group. Members must be manually approved by the channel owner.
|
||||
|
||||
|
||||
##Special
|
||||
|
@ -31,9 +31,9 @@ Some connections in the mention auto-complete box behave differently than others
|
||||
|
||||
[b]Private Mentions[/b]
|
||||
|
||||
If you wish to restrict a post to a single person or a number of people, you can do this by selecting channels or collections from the privacy tool. You can also just tag them with a privacy tag. A privacy tag is a name preceded by the two characters @! - and in addition to tagging these channels, will also change the privacy permissions of the post to only include them. You can have more than one privacy tag, for instance @!bob and @!linda will send the post only to Bob and Linda. This mechanism over-rides the privacy selector.
|
||||
If you wish to restrict a post to a single person or a number of people, you can do this by selecting channels or privacy groups from the privacy tool. You can also just tag them with a privacy tag. A privacy tag is a name preceded by the two characters @! - and in addition to tagging these channels, will also change the privacy permissions of the post to only include them. You can have more than one privacy tag, for instance @!bob and @!linda will send the post only to Bob and Linda. This mechanism over-rides the privacy selector.
|
||||
|
||||
You may also tag public collections. When you create or edit a collection, there is a checkbox to allow the group members to be seen by others. If this box is checked for a collection and you tag (for instance) @!Friends - the post will be restricted to the Friends collection. Check that the collection is public before doing this - as there is no way to take back a post except to delete it. The collection name will appear in the post and will alert members of that collection that they are members of it.
|
||||
You may also tag privacy groups which are "public". When you create or edit a privacy group, there is a checkbox to allow the group members to be seen by others. If this box is checked for a group and you tag (for instance) @!Friends - the post will be restricted to the Friends group. Check that the group is public before doing this - as there is no way to take back a post except to delete it. The group name will appear in the post and will alert members of that group that they are members of it.
|
||||
|
||||
|
||||
[b]Mentions and Comments[/b]
|
||||
|
@ -8,7 +8,6 @@ We need much more than this, but here are areas where developers can help. Pleas
|
||||
[li]SAML 2.0 and OpenID Connect provider functionality[/li]
|
||||
[li]Create bug tracker module[/li]
|
||||
[li]Filing posts - provide a dropdown menu integrated with the 'post actions menu'[/li]
|
||||
[li]integrate Mozilla Persona (possibly via plugin) https://github.com/mozilla/id-specs/blob/prod/browserid/index.md and become an idP[/li]
|
||||
[li]translation plugins - moses or apertium[/li]
|
||||
[li]plugins - provide 'disable' which is softer than 'uninstall' for those plugins which create additional DB tables[/li]
|
||||
[li]Infinite scroll improvements (i.e. embedded page links) see http://scrollsample.appspot.com/items [/li]
|
||||
@ -18,9 +17,7 @@ We need much more than this, but here are areas where developers can help. Pleas
|
||||
[li]Integrate the "open site" list with the register page[/li]
|
||||
[li]Support comments and member notes on documentation pages (to achieve an effect similar to php.net)[/li]
|
||||
[li]Support comments on webpages[/li]
|
||||
[li]implement oembed provider interface[/li]
|
||||
[li]refactor the oembed client interface so that we can safely sandbox remote content[/li]
|
||||
[li]Many modern social apps now have both a profile photo and a "cover photo". Add support for this. [/li]
|
||||
[li]Write more webpage layouts[/li]
|
||||
[li]Write more webpage widgets[/li]
|
||||
[li]restricted access OAuth clients[/li]
|
||||
@ -35,12 +32,9 @@ We need much more than this, but here are areas where developers can help. Pleas
|
||||
[li]API extensions, for Twitter API - search, friending, threading. For Red API, lots of stuff[/li]
|
||||
[li]Import channel from Diaspora/Friendica (Diaspora partially done)[/li]
|
||||
[li]MediaGoblin photo "crosspost" connector[/li]
|
||||
[li]Create management page/UI for extensible profile fields[/li]
|
||||
[li]Create interface to include/exclude and re-order standard profile fields[/li]
|
||||
[li]App taxonomy[/li]
|
||||
[li]Customisable App collection pages[/li]
|
||||
[li]replace the tinymce visual editor and/or make the visual editor pluggable and responsive to different output formats. We probably want library/bbedit for bbcode. This needs a fair bit of work to catch up with our "enhanced bbcode", but start with images, links, bold and highlight and work from there.[/li]
|
||||
[li]Photos module - turn photos into normal conversations and fix tagging[/li]
|
||||
[li]Create mobile clients for the top platforms - which involves extending the API so that we can do stuff far beyond the current crop of Twitter/Statusnet clients. Ditto for mobile themes. We can probably use something like the Friendica Android app as a base to start from.[/li]
|
||||
[li](in progress Habeas Codice) Implement owned and exchangeable "things".[/li]
|
||||
[li]Family Account creation - using service classes (an account holder can create a certain number of sub-accounts which are all tied to their subscription - if the subscription lapses they all go away).[/li]
|
||||
|
@ -1,4 +1,5 @@
|
||||
<?php /** @file */
|
||||
|
||||
if(class_exists('BaseObject'))
|
||||
return;
|
||||
|
||||
|
@ -75,12 +75,12 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') {
|
||||
$a = get_app();
|
||||
|
||||
if(! $xchan) {
|
||||
if($a->poi) {
|
||||
$xchan = $a->poi;
|
||||
if(App::$poi) {
|
||||
$xchan = App::$poi;
|
||||
}
|
||||
elseif(is_array($a->profile) && $a->profile['channel_hash']) {
|
||||
elseif(is_array(App::$profile) && App::$profile['channel_hash']) {
|
||||
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($a->profile['channel_hash'])
|
||||
dbesc(App::$profile['channel_hash'])
|
||||
);
|
||||
if($r)
|
||||
$xchan = $r[0];
|
||||
@ -102,7 +102,7 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') {
|
||||
}
|
||||
|
||||
if(array_key_exists('channel_id',$xchan))
|
||||
$a->profile_uid = $xchan['channel_id'];
|
||||
App::$profile_uid = $xchan['channel_id'];
|
||||
|
||||
$url = (($observer)
|
||||
? z_root() . '/magic?f=&dest=' . $xchan['xchan_url'] . '&addr=' . $xchan['xchan_addr']
|
||||
@ -111,7 +111,7 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') {
|
||||
|
||||
return replace_macros(get_markup_template('xchan_vcard.tpl'),array(
|
||||
'$name' => $xchan['xchan_name'],
|
||||
'$photo' => ((is_array($a->profile) && array_key_exists('photo',$a->profile)) ? $a->profile['photo'] : $xchan['xchan_photo_l']),
|
||||
'$photo' => ((is_array(App::$profile) && array_key_exists('photo',App::$profile)) ? App::$profile['photo'] : $xchan['xchan_photo_l']),
|
||||
'$follow' => $xchan['xchan_addr'],
|
||||
'$link' => zid($xchan['xchan_url']),
|
||||
'$connect' => $connect,
|
||||
@ -235,7 +235,7 @@ function account_remove($account_id,$local = true,$unset_session=true) {
|
||||
unset($_SESSION['authenticated']);
|
||||
unset($_SESSION['uid']);
|
||||
notice( sprintf(t("User '%s' deleted"),$account_email) . EOL);
|
||||
goaway(get_app()->get_baseurl());
|
||||
goaway(z_root());
|
||||
}
|
||||
return $r;
|
||||
|
||||
@ -263,7 +263,7 @@ function rrmdir($path)
|
||||
return false;
|
||||
}
|
||||
|
||||
function channel_remove($channel_id, $local = true, $unset_session=true) {
|
||||
function channel_remove($channel_id, $local = true, $unset_session=false) {
|
||||
|
||||
if(! $channel_id)
|
||||
return;
|
||||
@ -331,25 +331,25 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
|
||||
dbesc(datetime_convert()),
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
// if this was the default channel, set another one as default
|
||||
if($a->account['account_default_channel'] == $channel_id) {
|
||||
if(App::$account['account_default_channel'] == $channel_id) {
|
||||
$r = q("select channel_id from channel where channel_account_id = %d and channel_removed = 0 limit 1",
|
||||
intval($a->account['account_id']),
|
||||
intval(App::$account['account_id']),
|
||||
intval(PAGE_REMOVED));
|
||||
if ($r) {
|
||||
$rr = q("update account set account_default_channel = %d where account_id = %d",
|
||||
intval($r[0]['channel_id']),
|
||||
intval($a->account['account_id']));
|
||||
intval(App::$account['account_id']));
|
||||
logger("Default channel deleted, changing default to channel_id " . $r[0]['channel_id']);
|
||||
}
|
||||
else {
|
||||
$rr = q("update account set account_default_channel = 0 where account_id = %d",
|
||||
intval($r[0]['channel_id']),
|
||||
intval($a->account['account_id']));
|
||||
intval(App::$account['account_id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
logger('deleting hublocs',LOGGER_DEBUG);
|
||||
|
||||
$r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s' and hubloc_url = '%s' ",
|
||||
@ -389,9 +389,8 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
|
||||
proc_run('php','include/directory.php',$channel_id);
|
||||
|
||||
if($channel_id == local_channel() && $unset_session) {
|
||||
unset($_SESSION['authenticated']);
|
||||
unset($_SESSION['uid']);
|
||||
goaway($a->get_baseurl());
|
||||
\Zotlabs\Web\Session::nuke();
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ require_once('include/items.php');
|
||||
*/
|
||||
|
||||
class Conversation extends BaseObject {
|
||||
|
||||
private $threads = array();
|
||||
private $mode = null;
|
||||
private $observer = null;
|
||||
@ -47,33 +48,26 @@ class Conversation extends BaseObject {
|
||||
|
||||
$a = $this->get_app();
|
||||
|
||||
$this->observer = $a->get_observer();
|
||||
$this->observer = App::get_observer();
|
||||
$ob_hash = (($this->observer) ? $this->observer['xchan_hash'] : '');
|
||||
|
||||
switch($mode) {
|
||||
case 'network':
|
||||
// if(array_key_exists('firehose',$a->data) && intval($a->data['firehose'])) {
|
||||
// $this->profile_owner = intval($a->data['firehose']);
|
||||
// $this->writable = false;
|
||||
// }
|
||||
// else {
|
||||
$this->profile_owner = local_channel();
|
||||
$this->writable = true;
|
||||
// }
|
||||
$this->profile_owner = local_channel();
|
||||
$this->writable = true;
|
||||
break;
|
||||
case 'channel':
|
||||
$this->profile_owner = $a->profile['profile_uid'];
|
||||
$this->profile_owner = App::$profile['profile_uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
break;
|
||||
case 'display':
|
||||
// in this mode we set profile_owner after initialisation (from conversation()) and then
|
||||
// pull some trickery which allows us to re-invoke this function afterward
|
||||
// it's an ugly hack so FIXME
|
||||
// $this->profile_owner = $a->profile['uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
break;
|
||||
case 'page':
|
||||
$this->profile_owner = $a->profile['uid'];
|
||||
$this->profile_owner = App::$profile['uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
break;
|
||||
default:
|
||||
@ -142,11 +136,11 @@ class Conversation extends BaseObject {
|
||||
public function add_thread($item) {
|
||||
$item_id = $item->get_id();
|
||||
if(!$item_id) {
|
||||
logger('[ERROR] Conversation::add_thread : Item has no ID!!', LOGGER_DEBUG);
|
||||
logger('Item has no ID!!', LOGGER_DEBUG, LOG_ERR);
|
||||
return false;
|
||||
}
|
||||
if($this->get_thread($item->get_id())) {
|
||||
logger('[WARN] Conversation::add_thread : Thread already exists ('. $item->get_id() .').', LOGGER_DEBUG);
|
||||
logger('Thread already exists ('. $item->get_id() .').', LOGGER_DEBUG, LOG_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -177,11 +171,6 @@ class Conversation extends BaseObject {
|
||||
}
|
||||
}
|
||||
require_once('include/identity.php');
|
||||
// $sys = get_sys_channel();
|
||||
|
||||
// if($sys && $item->get_data_value('uid') == $sys['channel_id']) {
|
||||
// $item->set_commentable(false);
|
||||
// }
|
||||
|
||||
$item->set_conversation($this);
|
||||
$this->threads[] = $item;
|
||||
@ -209,7 +198,7 @@ class Conversation extends BaseObject {
|
||||
$item_data = $item->get_template_data($conv_responses);
|
||||
}
|
||||
if(!$item_data) {
|
||||
logger('[ERROR] Conversation::get_template_data : Failed to get item template data ('. $item->get_id() .').', LOGGER_DEBUG);
|
||||
logger('Failed to get item template data ('. $item->get_id() .').', LOGGER_DEBUG, LOG_ERR);
|
||||
return false;
|
||||
}
|
||||
$result[] = $item_data;
|
||||
|
@ -8,7 +8,7 @@ require_once('include/photo/photo_driver.php');
|
||||
function import_diaspora($data) {
|
||||
$a = get_app();
|
||||
|
||||
$account = $a->get_account();
|
||||
$account = App::get_account();
|
||||
if(! $account)
|
||||
return false;
|
||||
|
||||
|
@ -97,7 +97,7 @@ class Item extends BaseObject {
|
||||
$mode = $conv->get_mode();
|
||||
|
||||
if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
|
||||
$edpost = array($a->get_baseurl($ssl_state)."/editpost/".$item['id'], t("Edit"));
|
||||
$edpost = array(z_root()."/editpost/".$item['id'], t("Edit"));
|
||||
else
|
||||
$edpost = false;
|
||||
|
||||
@ -241,7 +241,7 @@ class Item extends BaseObject {
|
||||
$has_bookmarks = false;
|
||||
if(is_array($item['term'])) {
|
||||
foreach($item['term'] as $t) {
|
||||
if($t['type'] == TERM_BOOKMARK)
|
||||
if(!UNO && $t['type'] == TERM_BOOKMARK)
|
||||
$has_bookmarks = true;
|
||||
}
|
||||
}
|
||||
@ -264,7 +264,7 @@ class Item extends BaseObject {
|
||||
if($keep_reports === 0)
|
||||
$keep_reports = 30;
|
||||
|
||||
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0)
|
||||
if((! get_config('system','disable_dreport')) && strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC',"now - $keep_reports days")) > 0)
|
||||
$dreport = t('Delivery Report');
|
||||
|
||||
if(strcmp(datetime_convert('UTC','UTC',$item['created']),datetime_convert('UTC','UTC','now - 12 hours')) > 0)
|
||||
@ -681,14 +681,20 @@ class Item extends BaseObject {
|
||||
$qc = ((local_channel()) ? get_pconfig(local_channel(),'system','qcomment') : null);
|
||||
$qcomment = (($qc) ? explode("\n",$qc) : null);
|
||||
|
||||
$arr = array('comment_buttons' => '','id' => $this->get_id());
|
||||
call_hooks('comment_buttons',$arr);
|
||||
$comment_buttons = $arr['comment_buttons'];
|
||||
|
||||
|
||||
$comment_box = replace_macros($template,array(
|
||||
'$return_path' => '',
|
||||
'$threaded' => $this->is_threaded(),
|
||||
'$jsreload' => (($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''),
|
||||
'$jsreload' => '', //(($conv->get_mode() === 'display') ? $_SESSION['return_url'] : ''),
|
||||
'$type' => (($conv->get_mode() === 'channel') ? 'wall-comment' : 'net-comment'),
|
||||
'$id' => $this->get_id(),
|
||||
'$parent' => $this->get_id(),
|
||||
'$qcomment' => $qcomment,
|
||||
'$comment_buttons' => $comment_buttons,
|
||||
'$profile_uid' => $conv->get_profile_owner(),
|
||||
'$mylink' => $observer['xchan_url'],
|
||||
'$mytitle' => t('This is you'),
|
||||
@ -708,7 +714,7 @@ class Item extends BaseObject {
|
||||
'$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false),
|
||||
'$encrypt' => t('Encrypt text'),
|
||||
'$cipher' => $conv->get_cipher(),
|
||||
'$sourceapp' => get_app()->sourcename
|
||||
'$sourceapp' => App::$sourcename
|
||||
|
||||
));
|
||||
|
||||
|
@ -11,6 +11,7 @@ require_once('include/text.php');
|
||||
require_once('include/language.php');
|
||||
require_once('include/datetime.php');
|
||||
require_once('include/crypto.php');
|
||||
require_once('include/identity.php');
|
||||
|
||||
|
||||
function check_account_email($email) {
|
||||
@ -247,7 +248,7 @@ function verify_email_address($arr) {
|
||||
|
||||
$res = mail($arr['email'], email_header_encode(sprintf( t('Registration confirmation for %s'), get_config('system','sitename'))),
|
||||
$email_msg,
|
||||
'From: ' . 'Administrator' . '@' . get_app()->get_hostname() . "\n"
|
||||
'From: ' . 'Administrator' . '@' . App::get_hostname() . "\n"
|
||||
. 'Content-type: text/plain; charset=UTF-8' . "\n"
|
||||
. 'Content-transfer-encoding: 8bit'
|
||||
);
|
||||
@ -313,7 +314,7 @@ function send_reg_approval_email($arr) {
|
||||
|
||||
$res = mail($admin['email'], sprintf( t('Registration request at %s'), get_config('system','sitename')),
|
||||
$email_msg,
|
||||
'From: ' . t('Administrator') . '@' . get_app()->get_hostname() . "\n"
|
||||
'From: ' . t('Administrator') . '@' . App::get_hostname() . "\n"
|
||||
. 'Content-type: text/plain; charset=UTF-8' . "\n"
|
||||
. 'Content-transfer-encoding: 8bit'
|
||||
);
|
||||
@ -329,7 +330,7 @@ function send_reg_approval_email($arr) {
|
||||
return($delivered ? true : false);
|
||||
}
|
||||
|
||||
function send_verification_email($email,$password) {
|
||||
function send_register_success_email($email,$password) {
|
||||
|
||||
$email_msg = replace_macros(get_intltext_template('register_open_eml.tpl'), array(
|
||||
'$sitename' => get_config('system','sitename'),
|
||||
@ -340,7 +341,7 @@ function send_verification_email($email,$password) {
|
||||
|
||||
$res = mail($email, sprintf( t('Registration details for %s'), get_config('system','sitename')),
|
||||
$email_msg,
|
||||
'From: ' . t('Administrator') . '@' . get_app()->get_hostname() . "\n"
|
||||
'From: ' . t('Administrator') . '@' . App::get_hostname() . "\n"
|
||||
. 'Content-type: text/plain; charset=UTF-8' . "\n"
|
||||
. 'Content-transfer-encoding: 8bit'
|
||||
);
|
||||
@ -353,7 +354,7 @@ function send_verification_email($email,$password) {
|
||||
* @param string $hash
|
||||
* @return array|boolean
|
||||
*/
|
||||
function user_allow($hash) {
|
||||
function account_allow($hash) {
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
@ -406,6 +407,9 @@ function user_allow($hash) {
|
||||
|
||||
pop_lang();
|
||||
|
||||
if(get_config('system','auto_channel_create') || UNO)
|
||||
auto_channel_create($register[0]['uid']);
|
||||
|
||||
if ($res) {
|
||||
info( t('Account approved.') . EOL );
|
||||
return true;
|
||||
@ -414,7 +418,7 @@ function user_allow($hash) {
|
||||
|
||||
|
||||
/**
|
||||
* @brief Denies a user registration.
|
||||
* @brief Denies an account registration.
|
||||
*
|
||||
* This does not have to go through user_remove() and save the nickname
|
||||
* permanently against re-registration, as the person was not yet
|
||||
@ -423,7 +427,8 @@ function user_allow($hash) {
|
||||
* @param string $hash
|
||||
* @return boolean
|
||||
*/
|
||||
function user_deny($hash) {
|
||||
|
||||
function account_deny($hash) {
|
||||
|
||||
$register = q("SELECT * FROM register WHERE hash = '%s' LIMIT 1",
|
||||
dbesc($hash)
|
||||
@ -452,11 +457,14 @@ function user_deny($hash) {
|
||||
|
||||
}
|
||||
|
||||
// called from regver to activate an account from the email verification link
|
||||
|
||||
function user_approve($hash) {
|
||||
function account_approve($hash) {
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
// Note: when the password in the register table is 'verify', the uid actually contains the account_id
|
||||
|
||||
$register = q("SELECT * FROM `register` WHERE `hash` = '%s' and password = 'verify' LIMIT 1",
|
||||
dbesc($hash)
|
||||
);
|
||||
@ -491,6 +499,10 @@ function user_approve($hash) {
|
||||
intval($register[0]['uid'])
|
||||
);
|
||||
|
||||
|
||||
if(get_config('system','auto_channel_create') || UNO)
|
||||
auto_channel_create($register[0]['uid']);
|
||||
|
||||
info( t('Account verified. Please login.') . EOL );
|
||||
|
||||
return true;
|
||||
@ -643,7 +655,7 @@ function account_service_class_allows($aid, $property, $usage = false) {
|
||||
function service_class_fetch($uid, $property) {
|
||||
$a = get_app();
|
||||
if($uid == local_channel()) {
|
||||
$service_class = $a->account['account_service_class'];
|
||||
$service_class = App::$account['account_service_class'];
|
||||
}
|
||||
else {
|
||||
$r = q("select account_service_class as service_class
|
||||
|
@ -23,7 +23,7 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) {
|
||||
|
||||
// e.g. 'network_pre_group_deny', 'profile_pre_group_allow'
|
||||
|
||||
call_hooks($a->module . '_pre_' . $selname, $arr);
|
||||
call_hooks(App::$module . '_pre_' . $selname, $arr);
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
@ -39,7 +39,7 @@ function group_select($selname,$selclass,$preselected = false,$size = 4) {
|
||||
}
|
||||
$o .= "</select>\r\n";
|
||||
|
||||
call_hooks($a->module . '_post_' . $selname, $o);
|
||||
call_hooks(App::$module . '_post_' . $selname, $o);
|
||||
|
||||
|
||||
return $o;
|
||||
@ -127,7 +127,7 @@ function contact_selector($selname, $selclass, $preselected = false, $options) {
|
||||
|
||||
// e.g. 'network_pre_contact_deny', 'profile_pre_contact_allow'
|
||||
|
||||
call_hooks($a->module . '_pre_' . $selname, $arr);
|
||||
call_hooks(App::$module . '_pre_' . $selname, $arr);
|
||||
|
||||
if(count($r)) {
|
||||
foreach($r as $rr) {
|
||||
@ -145,7 +145,7 @@ function contact_selector($selname, $selclass, $preselected = false, $options) {
|
||||
|
||||
$o .= "</select>\r\n";
|
||||
|
||||
call_hooks($a->module . '_post_' . $selname, $o);
|
||||
call_hooks(App::$module . '_post_' . $selname, $o);
|
||||
|
||||
return $o;
|
||||
}*/
|
||||
@ -182,7 +182,7 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
|
||||
|
||||
// e.g. 'network_pre_contact_deny', 'profile_pre_contact_allow'
|
||||
|
||||
call_hooks($a->module . '_pre_' . $selname, $arr);
|
||||
call_hooks(App::$module . '_pre_' . $selname, $arr);
|
||||
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
@ -200,7 +200,7 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
|
||||
|
||||
$o .= "</select>\r\n";
|
||||
|
||||
call_hooks($a->module . '_post_' . $selname, $o);
|
||||
call_hooks(App::$module . '_post_' . $selname, $o);
|
||||
|
||||
return $o;
|
||||
}
|
||||
@ -210,10 +210,13 @@ function fixacl(&$item) {
|
||||
$item = str_replace(array('<','>'),array('',''),$item);
|
||||
}
|
||||
|
||||
function populate_acl($defaults = null,$show_jotnets = true) {
|
||||
function populate_acl($defaults = null,$show_jotnets = true, $showall = '') {
|
||||
|
||||
$allow_cid = $allow_gid = $deny_cid = $deny_gid = false;
|
||||
|
||||
if(! $showall)
|
||||
$showall = t('Visible to your default audience');
|
||||
|
||||
if(is_array($defaults)) {
|
||||
$allow_cid = ((strlen($defaults['allow_cid']))
|
||||
? explode('><', $defaults['allow_cid']) : array() );
|
||||
@ -231,22 +234,21 @@ function populate_acl($defaults = null,$show_jotnets = true) {
|
||||
|
||||
$jotnets = '';
|
||||
if($show_jotnets) {
|
||||
logger('jot_networks');
|
||||
call_hooks('jot_networks', $jotnets);
|
||||
}
|
||||
|
||||
$tpl = get_markup_template("acl_selector.tpl");
|
||||
$o = replace_macros($tpl, array(
|
||||
'$showall'=> t("Visible to your default audience"),
|
||||
'$show' => t("Show"),
|
||||
'$hide' => t("Don't show"),
|
||||
'$allowcid' => json_encode($allow_cid),
|
||||
'$allowgid' => json_encode($allow_gid),
|
||||
'$denycid' => json_encode($deny_cid),
|
||||
'$denygid' => json_encode($deny_gid),
|
||||
'$jnetModalTitle' => t('Other networks and post services'),
|
||||
'$jotnets' => $jotnets,
|
||||
'$aclModalTitle' => t('Permissions'),
|
||||
'$showall' => $showall,
|
||||
'$show' => t("Show"),
|
||||
'$hide' => t("Don't show"),
|
||||
'$allowcid' => json_encode($allow_cid),
|
||||
'$allowgid' => json_encode($allow_gid),
|
||||
'$denycid' => json_encode($deny_cid),
|
||||
'$denygid' => json_encode($deny_gid),
|
||||
'$jnetModalTitle' => t('Other networks and post services'),
|
||||
'$jotnets' => $jotnets,
|
||||
'$aclModalTitle' => t('Permissions'),
|
||||
'$aclModalDismiss' => t('Close')
|
||||
));
|
||||
|
||||
|
@ -11,7 +11,7 @@ function profile_activity($changed, $value) {
|
||||
|
||||
require_once('include/items.php');
|
||||
|
||||
$self = $a->get_channel();
|
||||
$self = App::get_channel();
|
||||
|
||||
if(! count($self))
|
||||
return;
|
||||
|
100
include/api.php
100
include/api.php
@ -34,7 +34,7 @@ require_once('include/api_auth.php');
|
||||
|
||||
function api_user() {
|
||||
$aid = get_account_id();
|
||||
$channel = get_app()->get_channel();
|
||||
$channel = App::get_channel();
|
||||
|
||||
if(($aid) && (x($_REQUEST,'channel'))) {
|
||||
|
||||
@ -79,7 +79,7 @@ require_once('include/api_auth.php');
|
||||
$type="json";
|
||||
|
||||
foreach ($API as $p=>$info){
|
||||
if (strpos($a->query_string, $p)===0){
|
||||
if (strpos(App::$query_string, $p)===0){
|
||||
$called_api= explode("/",$p);
|
||||
//unset($_SERVER['PHP_AUTH_USER']);
|
||||
if ($info['auth'] === true && api_user() === false) {
|
||||
@ -88,18 +88,18 @@ require_once('include/api_auth.php');
|
||||
|
||||
load_contact_links(api_user());
|
||||
|
||||
$channel = $a->get_channel();
|
||||
$channel = App::get_channel();
|
||||
|
||||
logger('API call for ' . $channel['channel_name'] . ': ' . $a->query_string);
|
||||
logger('API call for ' . $channel['channel_name'] . ': ' . App::$query_string);
|
||||
logger('API parameters: ' . print_r($_REQUEST,true));
|
||||
|
||||
$type="json";
|
||||
|
||||
if (strpos($a->query_string, ".xml")>0) $type="xml";
|
||||
if (strpos($a->query_string, ".json")>0) $type="json";
|
||||
if (strpos($a->query_string, ".rss")>0) $type="rss";
|
||||
if (strpos($a->query_string, ".atom")>0) $type="atom";
|
||||
if (strpos($a->query_string, ".as")>0) $type="as";
|
||||
if (strpos(App::$query_string, ".xml")>0) $type="xml";
|
||||
if (strpos(App::$query_string, ".json")>0) $type="json";
|
||||
if (strpos(App::$query_string, ".rss")>0) $type="rss";
|
||||
if (strpos(App::$query_string, ".atom")>0) $type="atom";
|
||||
if (strpos(App::$query_string, ".as")>0) $type="as";
|
||||
|
||||
$r = call_user_func($info['func'], $a, $type);
|
||||
if ($r===false) return;
|
||||
@ -141,7 +141,7 @@ require_once('include/api_auth.php');
|
||||
}
|
||||
}
|
||||
header("HTTP/1.1 404 Not Found");
|
||||
logger('API call not implemented: '.$a->query_string." - ".print_r($_REQUEST,true));
|
||||
logger('API call not implemented: '.App::$query_string." - ".print_r($_REQUEST,true));
|
||||
$r = '<status><error>not implemented</error></status>';
|
||||
switch($type){
|
||||
case "xml":
|
||||
@ -171,12 +171,12 @@ require_once('include/api_auth.php');
|
||||
$arr['$user'] = $user_info;
|
||||
$arr['$rss'] = array(
|
||||
'alternate' => $user_info['url'],
|
||||
'self' => $a->get_baseurl(). "/". $a->query_string,
|
||||
'base' => $a->get_baseurl(),
|
||||
'self' => z_root(). "/". App::$query_string,
|
||||
'base' => z_root(),
|
||||
'updated' => api_date(null),
|
||||
'atom_updated' => datetime_convert('UTC','UTC','now',ATOM_TIME),
|
||||
'language' => $user_info['language'],
|
||||
'logo' => $a->get_baseurl()."/images/rm-64.png",
|
||||
'logo' => z_root()."/images/rm-64.png",
|
||||
);
|
||||
|
||||
return $arr;
|
||||
@ -213,7 +213,7 @@ require_once('include/api_auth.php');
|
||||
$extra_query .= " AND abook_channel = ".intval(api_user());
|
||||
}
|
||||
|
||||
if (is_null($user) && argc() > (count($called_api)-1) && (strstr($a->cmd,'/users'))){
|
||||
if (is_null($user) && argc() > (count($called_api)-1) && (strstr(App::$cmd,'/users'))){
|
||||
$argid = count($called_api);
|
||||
list($xx, $null) = explode(".",argv($argid));
|
||||
if(is_numeric($xx)){
|
||||
@ -318,7 +318,7 @@ require_once('include/api_auth.php');
|
||||
'location' => ($usr) ? $usr[0]['channel_location'] : '',
|
||||
'profile_image_url' => $uinfo[0]['xchan_photo_l'],
|
||||
'url' => $uinfo[0]['xchan_url'],
|
||||
'contact_url' => $a->get_baseurl() . "/connections/".$uinfo[0]['abook_id'],
|
||||
'contact_url' => z_root() . "/connections/".$uinfo[0]['abook_id'],
|
||||
'protected' => false,
|
||||
'friends_count' => intval($countfriends),
|
||||
'created_at' => api_date($uinfo[0]['abook_created']),
|
||||
@ -326,7 +326,7 @@ require_once('include/api_auth.php');
|
||||
'time_zone' => 'UTC', //$uinfo[0]['timezone'],
|
||||
'geo_enabled' => false,
|
||||
'statuses_count' => intval($countitms), //#XXX: fix me
|
||||
'lang' => get_app()->language,
|
||||
'lang' => App::$language,
|
||||
'description' => (($profile) ? $profile[0]['pdesc'] : ''),
|
||||
'followers_count' => intval($countfollowers),
|
||||
'favourites_count' => intval($starred),
|
||||
@ -486,7 +486,7 @@ require_once('include/api_auth.php');
|
||||
|
||||
function api_account_logout(&$a, $type){
|
||||
require_once('include/auth.php');
|
||||
nuke_session();
|
||||
\Zotlabs\Web\Session::nuke();
|
||||
return api_apply_template("user", $type, array('$user' => null));
|
||||
|
||||
}
|
||||
@ -635,13 +635,13 @@ require_once('include/api_auth.php');
|
||||
|
||||
|
||||
function api_albums(&$a,$type) {
|
||||
json_return_and_die(photos_albums_list($a->get_channel(),$a->get_observer()));
|
||||
json_return_and_die(photos_albums_list(App::get_channel(),App::get_observer()));
|
||||
}
|
||||
api_register_func('api/red/albums','api_albums', true);
|
||||
|
||||
function api_photos(&$a,$type) {
|
||||
$album = $_REQUEST['album'];
|
||||
json_return_and_die(photos_list_photos($a->get_channel(),$a->get_observer(),$album));
|
||||
json_return_and_die(photos_list_photos(App::get_channel(),App::get_observer(),$album));
|
||||
}
|
||||
api_register_func('api/red/photos','api_photos', true);
|
||||
|
||||
@ -768,7 +768,7 @@ require_once('include/api_auth.php');
|
||||
}
|
||||
$txt = html2bbcode($txt);
|
||||
|
||||
$a->argv[1] = $user_info['screen_name'];
|
||||
App::$argv[1] = $user_info['screen_name'];
|
||||
|
||||
$_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
|
||||
$_FILES['userfile'] = $_FILES['media'];
|
||||
@ -872,7 +872,7 @@ require_once('include/api_auth.php');
|
||||
// upload each image if we have any
|
||||
$_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
|
||||
require_once('mod/wall_attach.php');
|
||||
$a->data['api_info'] = $user_info;
|
||||
App::$data['api_info'] = $user_info;
|
||||
$media = wall_attach_post($a);
|
||||
|
||||
if(strlen($media)>0)
|
||||
@ -885,7 +885,7 @@ require_once('include/api_auth.php');
|
||||
// upload each image if we have any
|
||||
$_REQUEST['silent']='1'; //tell wall_upload function to return img info instead of echo
|
||||
require_once('mod/wall_attach.php');
|
||||
$a->data['api_info'] = $user_info;
|
||||
App::$data['api_info'] = $user_info;
|
||||
$media = wall_attach_post($a);
|
||||
|
||||
if(strlen($media)>0)
|
||||
@ -960,7 +960,7 @@ require_once('include/api_auth.php');
|
||||
$arr['records'] = 999999;
|
||||
$arr['item_type'] = '*';
|
||||
|
||||
$i = items_fetch($arr,$a->get_channel(),get_observer_hash());
|
||||
$i = items_fetch($arr,App::get_channel(),get_observer_hash());
|
||||
|
||||
if(! $i)
|
||||
json_return_and_die(array());
|
||||
@ -1230,7 +1230,7 @@ require_once('include/api_auth.php');
|
||||
$sql_extra .= ' AND `item`.`parent` = `item`.`id`';
|
||||
|
||||
if (api_user() != $user_info['uid']) {
|
||||
$observer = get_app()->get_observer();
|
||||
$observer = App::get_observer();
|
||||
require_once('include/permissions.php');
|
||||
if(! perm_is_allowed($user_info['uid'],(($observer) ? $observer['xchan_hash'] : ''),'view_stream'))
|
||||
return '';
|
||||
@ -1272,8 +1272,8 @@ require_once('include/api_auth.php');
|
||||
break;
|
||||
case "as":
|
||||
$as = api_format_as($a, $ret, $user_info);
|
||||
$as['title'] = $a->config['sitename']." Home Timeline";
|
||||
$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
|
||||
$as['title'] = App::$config['sitename']." Home Timeline";
|
||||
$as['link']['url'] = z_root()."/".$user_info["screen_name"]."/all";
|
||||
return($as);
|
||||
break;
|
||||
}
|
||||
@ -1333,8 +1333,8 @@ require_once('include/api_auth.php');
|
||||
break;
|
||||
case "as":
|
||||
$as = api_format_as($a, $ret, $user_info);
|
||||
$as['title'] = $a->config['sitename']. " " . t('Public Timeline');
|
||||
$as['link']['url'] = $a->get_baseurl()."/";
|
||||
$as['title'] = App::$config['sitename']. " " . t('Public Timeline');
|
||||
$as['link']['url'] = z_root()."/";
|
||||
return($as);
|
||||
break;
|
||||
}
|
||||
@ -1409,7 +1409,7 @@ require_once('include/api_auth.php');
|
||||
|
||||
//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
|
||||
|
||||
$observer = get_app()->get_observer();
|
||||
$observer = App::get_observer();
|
||||
|
||||
$item_normal = item_normal();
|
||||
|
||||
@ -1526,7 +1526,7 @@ require_once('include/api_auth.php');
|
||||
|
||||
//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
|
||||
|
||||
$myurl = $a->get_baseurl() . '/channel/'. $a->user['nickname'];
|
||||
$myurl = z_root() . '/channel/'. App::$user['nickname'];
|
||||
$myurl = substr($myurl,strpos($myurl,'://')+3);
|
||||
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
|
||||
$diasp_url = str_replace('/channel/','/u/',$myurl);
|
||||
@ -1561,8 +1561,8 @@ require_once('include/api_auth.php');
|
||||
break;
|
||||
case "as":
|
||||
$as = api_format_as($a, $ret, $user_info);
|
||||
$as["title"] = $a->config['sitename']." Mentions";
|
||||
$as['link']['url'] = $a->get_baseurl()."/";
|
||||
$as["title"] = App::$config['sitename']." Mentions";
|
||||
$as['link']['url'] = z_root()."/";
|
||||
return($as);
|
||||
break;
|
||||
}
|
||||
@ -1633,7 +1633,7 @@ require_once('include/api_auth.php');
|
||||
$arr['cid'] = $user_info['id'];
|
||||
|
||||
|
||||
$r = items_fetch($arr,get_app()->get_channel(),get_observer_hash());
|
||||
$r = items_fetch($arr,App::get_channel(),get_observer_hash());
|
||||
|
||||
$ret = api_format_items($r,$user_info);
|
||||
|
||||
@ -1752,7 +1752,7 @@ require_once('include/api_auth.php');
|
||||
$sql_extra .= ' AND `item`.`parent` = `item`.`id`';
|
||||
|
||||
if (api_user() != $user_info['uid']) {
|
||||
$observer = get_app()->get_observer();
|
||||
$observer = App::get_observer();
|
||||
require_once('include/permissions.php');
|
||||
if(! perm_is_allowed($user_info['uid'],(($observer) ? $observer['xchan_hash'] : ''),'view_stream'))
|
||||
return '';
|
||||
@ -1783,8 +1783,8 @@ require_once('include/api_auth.php');
|
||||
break;
|
||||
case "as":
|
||||
$as = api_format_as($a, $ret, $user_info);
|
||||
$as['title'] = $a->config['sitename']." Home Timeline";
|
||||
$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
|
||||
$as['title'] = App::$config['sitename']." Home Timeline";
|
||||
$as['link']['url'] = z_root()."/".$user_info["screen_name"]."/all";
|
||||
return($as);
|
||||
break;
|
||||
}
|
||||
@ -1801,7 +1801,7 @@ require_once('include/api_auth.php');
|
||||
function api_format_as($a, $ret, $user_info) {
|
||||
|
||||
$as = array();
|
||||
$as['title'] = $a->config['sitename']." Public Timeline";
|
||||
$as['title'] = App::$config['sitename']." Public Timeline";
|
||||
$items = array();
|
||||
foreach ($ret as $item) {
|
||||
$singleitem["actor"]["displayName"] = $item["user"]["name"];
|
||||
@ -1857,7 +1857,7 @@ require_once('include/api_auth.php');
|
||||
$items[] = $singleitem;
|
||||
}
|
||||
$as['items'] = $items;
|
||||
$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
|
||||
$as['link']['url'] = z_root()."/".$user_info["screen_name"]."/all";
|
||||
$as['link']['rel'] = "alternate";
|
||||
$as['link']['type'] = "text/html";
|
||||
return($as);
|
||||
@ -1978,8 +1978,8 @@ require_once('include/api_auth.php');
|
||||
'entities' => '',
|
||||
'objecttype' => (($item['obj_type']) ? $item['obj_type'] : ACTIVITY_OBJ_NOTE),
|
||||
'verb' => (($item['verb']) ? $item['verb'] : ACTIVITY_POST),
|
||||
'self' => $a->get_baseurl()."/api/statuses/show/".$item['id'].".".$type,
|
||||
'edit' => $a->get_baseurl()."/api/statuses/show/".$item['id'].".".$type,
|
||||
'self' => z_root()."/api/statuses/show/".$item['id'].".".$type,
|
||||
'edit' => z_root()."/api/statuses/show/".$item['id'].".".$type,
|
||||
);
|
||||
|
||||
$status = array_merge($status, $status2);
|
||||
@ -2088,8 +2088,8 @@ require_once('include/api_auth.php');
|
||||
load_config('system');
|
||||
|
||||
$name = get_config('system','sitename');
|
||||
$server = $a->get_hostname();
|
||||
$logo = $a->get_baseurl() . '/images/rm-64.png';
|
||||
$server = App::get_hostname();
|
||||
$logo = z_root() . '/images/rm-64.png';
|
||||
$email = get_config('system','admin_email');
|
||||
$closed = ((get_config('system','register_policy') == REGISTER_CLOSED) ? 'true' : 'false');
|
||||
$private = ((get_config('system','block_public')) ? 'true' : 'false');
|
||||
@ -2097,7 +2097,7 @@ require_once('include/api_auth.php');
|
||||
if(get_config('system','api_import_size'))
|
||||
$texlimit = string(get_config('system','api_import_size'));
|
||||
$ssl = ((get_config('system','have_ssl')) ? 'true' : 'false');
|
||||
$sslserver = (($ssl === 'true') ? str_replace('http:','https:',$a->get_baseurl()) : '');
|
||||
$sslserver = (($ssl === 'true') ? str_replace('http:','https:',z_root()) : '');
|
||||
|
||||
$config = array(
|
||||
'site' => array('name' => $name,'server' => $server, 'theme' => 'default', 'path' => '',
|
||||
@ -2106,10 +2106,10 @@ require_once('include/api_auth.php');
|
||||
'private' => $private, 'textlimit' => $textlimit, 'sslserver' => $sslserver, 'ssl' => $ssl,
|
||||
'shorturllength' => '30',
|
||||
'hubzilla' => array(
|
||||
'PLATFORM_NAME' => PLATFORM_NAME,
|
||||
'RED_VERSION' => RED_VERSION,
|
||||
'PLATFORM_NAME' => Zotlabs\Project\System::get_platform_name(),
|
||||
'RED_VERSION' => Zotlabs\Project\System::get_project_version(),
|
||||
'ZOT_REVISION' => ZOT_REVISION,
|
||||
'DB_UPDATE_VERSION' => DB_UPDATE_VERSION
|
||||
'DB_UPDATE_VERSION' => Zotlabs\Project\System::get_update_version()
|
||||
)
|
||||
));
|
||||
|
||||
@ -2142,12 +2142,12 @@ require_once('include/api_auth.php');
|
||||
|
||||
if($type === 'xml') {
|
||||
header("Content-type: application/xml");
|
||||
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<version>' . RED_VERSION . '</version>' . "\r\n";
|
||||
echo '<?xml version="1.0" encoding="UTF-8"?>' . "\r\n" . '<version>' . Zotlabs\Project\System::get_project_version() . '</version>' . "\r\n";
|
||||
killme();
|
||||
}
|
||||
elseif($type === 'json') {
|
||||
header("Content-type: application/json");
|
||||
echo '"' . RED_VERSION . '"';
|
||||
echo '"' . Zotlabs\Project\System::get_project_version() . '"';
|
||||
killme();
|
||||
}
|
||||
}
|
||||
@ -2270,9 +2270,9 @@ require_once('include/api_auth.php');
|
||||
if ($page<0) $page=0;
|
||||
|
||||
$start = $page*$count;
|
||||
$channel = $a->get_channel();
|
||||
$channel = App::get_channel();
|
||||
|
||||
$profile_url = $a->get_baseurl() . '/channel/' . $channel['channel_address'];
|
||||
$profile_url = z_root() . '/channel/' . $channel['channel_address'];
|
||||
if ($box=="sentbox") {
|
||||
$sql_extra = "`from_xchan`='".dbesc( $channel['channel_hash'] )."'";
|
||||
}
|
||||
|
@ -20,9 +20,9 @@ function api_login(&$a){
|
||||
if (!is_null($token)){
|
||||
$oauth->loginUser($token->uid);
|
||||
|
||||
$a->set_oauth_key($consumer->key);
|
||||
App::set_oauth_key($consumer->key);
|
||||
|
||||
call_hooks('logged_in', $a->user);
|
||||
call_hooks('logged_in', App::$user);
|
||||
return;
|
||||
}
|
||||
killme();
|
||||
|
@ -48,12 +48,12 @@ function parse_app_description($f) {
|
||||
$ret = array();
|
||||
|
||||
$baseurl = z_root();
|
||||
$channel = get_app()->get_channel();
|
||||
$channel = App::get_channel();
|
||||
$address = (($channel) ? $channel['channel_address'] : '');
|
||||
|
||||
//future expansion
|
||||
|
||||
$observer = get_app()->get_observer();
|
||||
$observer = App::get_observer();
|
||||
|
||||
|
||||
$lines = @file($f);
|
||||
@ -217,7 +217,7 @@ function app_render($papp,$mode = 'view') {
|
||||
return '';
|
||||
break;
|
||||
case 'observer':
|
||||
$observer = get_app()->get_observer();
|
||||
$observer = App::get_observer();
|
||||
if(! $observer)
|
||||
return '';
|
||||
break;
|
||||
@ -239,7 +239,7 @@ function app_render($papp,$mode = 'view') {
|
||||
$hosturl = z_root() . '/';
|
||||
}
|
||||
elseif(remote_channel()) {
|
||||
$observer = get_app()->get_observer();
|
||||
$observer = App::get_observer();
|
||||
if($observer && $observer['xchan_network'] === 'zot') {
|
||||
// some folks might have xchan_url redirected offsite, use the connurl
|
||||
$x = parse_url($observer['xchan_connurl']);
|
||||
@ -354,7 +354,7 @@ function app_store($arr) {
|
||||
}
|
||||
|
||||
|
||||
$darray['app_id'] = ((x($arr,'guid')) ? $arr['guid'] : random_string(). '.' . get_app()->get_hostname());
|
||||
$darray['app_id'] = ((x($arr,'guid')) ? $arr['guid'] : random_string(). '.' . App::get_hostname());
|
||||
$darray['app_sig'] = ((x($arr,'sig')) ? $arr['sig'] : '');
|
||||
$darray['app_author'] = ((x($arr,'author')) ? $arr['author'] : get_observer_hash());
|
||||
$darray['app_name'] = ((x($arr,'name')) ? escape_tags($arr['name']) : t('Unknown'));
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
require_once('include/permissions.php');
|
||||
require_once('include/security.php');
|
||||
require_once('include/group.php');
|
||||
|
||||
/**
|
||||
* @brief Guess the mimetype from file ending.
|
||||
@ -845,7 +846,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
||||
|
||||
// Caution: This re-uses $sql_options set further above
|
||||
|
||||
$r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_options limit 1",
|
||||
$r = q("select * from attach where uid = %d and hash = '%s' $sql_options limit 1",
|
||||
intval($channel_id),
|
||||
dbesc($hash)
|
||||
);
|
||||
@ -863,6 +864,12 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
||||
// This would've been called already with a success result in photos_upload() if it was a photo.
|
||||
call_hooks('photo_upload_end',$ret);
|
||||
}
|
||||
|
||||
$sync = attach_export_data($channel,$hash);
|
||||
|
||||
if($sync)
|
||||
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
@ -1242,7 +1249,7 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
|
||||
$channel_address = (($c) ? $c[0]['channel_address'] : 'notfound');
|
||||
$photo_sql = (($is_photo) ? " and is_photo = 1 " : '');
|
||||
|
||||
$r = q("SELECT hash, flags, is_dir, is_photo, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1",
|
||||
$r = q("SELECT hash, os_storage, flags, is_dir, is_photo, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1",
|
||||
dbesc($resource),
|
||||
intval($channel_id)
|
||||
);
|
||||
@ -1313,7 +1320,9 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
file_activity($channel_id, $object, $object['allow_cid'], $object['allow_gid'], $object['deny_cid'], $object['deny_gid'], 'update', $notify=0);
|
||||
file_activity($channel_id, $object, $object['allow_cid'], $object['allow_gid'], $object['deny_cid'], $object['deny_gid'], 'update', $notify=1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1468,13 +1477,13 @@ function pipe_streams($in, $out) {
|
||||
* @param string $deny_cid
|
||||
* @param string $deny_gid
|
||||
* @param string $verb
|
||||
* @param boolean $no_activity
|
||||
* @param boolean $notify
|
||||
*/
|
||||
function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $verb, $notify) {
|
||||
|
||||
require_once('include/items.php');
|
||||
|
||||
$poster = get_app()->get_observer();
|
||||
$poster = App::get_observer();
|
||||
|
||||
//if we got no object something went wrong
|
||||
if(!$object)
|
||||
@ -1514,13 +1523,21 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
|
||||
|
||||
$mid = item_message_id();
|
||||
|
||||
$arr = array();
|
||||
$objtype = ACTIVITY_OBJ_FILE;
|
||||
|
||||
$arr = array();
|
||||
$arr['aid'] = get_account_id();
|
||||
$arr['uid'] = $channel_id;
|
||||
$arr['item_wall'] = 1;
|
||||
$arr['item_origin'] = 1;
|
||||
$arr['item_unseen'] = 1;
|
||||
|
||||
$objtype = ACTIVITY_OBJ_FILE;
|
||||
$arr['author_xchan'] = $poster['xchan_hash'];
|
||||
$arr['owner_xchan'] = $poster['xchan_hash'];
|
||||
$arr['title'] = '';
|
||||
$arr['item_hidden'] = 1;
|
||||
$arr['obj_type'] = $objtype;
|
||||
$arr['resource_id'] = $object['hash'];
|
||||
$arr['resource_type'] = 'attach';
|
||||
|
||||
$private = (($arr_allow_cid[0] || $arr_allow_gid[0] || $arr_deny_cid[0] || $arr_deny_gid[0]) ? 1 : 0);
|
||||
|
||||
@ -1548,36 +1565,27 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
|
||||
|
||||
}
|
||||
|
||||
//send update activity and create a new one
|
||||
if($update && $verb == 'post' ) {
|
||||
//send update activity and create a new one
|
||||
|
||||
//updates should be sent to everybody with recursive perms and all eventual former allowed members ($object['allow_cid'] etc.).
|
||||
$u_arr_allow_cid = array_unique(array_merge($arr_allow_cid, expand_acl($object['allow_cid'])));
|
||||
$u_arr_allow_gid = array_unique(array_merge($arr_allow_gid, expand_acl($object['allow_gid'])));
|
||||
$u_arr_deny_cid = array_unique(array_merge($arr_deny_cid, expand_acl($object['deny_cid'])));
|
||||
$u_arr_deny_gid = array_unique(array_merge($arr_deny_gid, expand_acl($object['deny_gid'])));
|
||||
|
||||
$private = (($u_arr_allow_cid[0] || $u_arr_allow_gid[0] || $u_arr_deny_cid[0] || $u_arr_deny_gid[0]) ? 1 : 0);
|
||||
|
||||
$u_mid = item_message_id();
|
||||
|
||||
$arr['aid'] = get_account_id();
|
||||
$arr['uid'] = $channel_id;
|
||||
$arr['mid'] = $u_mid;
|
||||
$arr['parent_mid'] = $u_mid;
|
||||
$arr['author_xchan'] = $poster['xchan_hash'];
|
||||
$arr['owner_xchan'] = $poster['xchan_hash'];
|
||||
$arr['title'] = '';
|
||||
//updates should be visible to everybody -> perms may have changed
|
||||
$arr['allow_cid'] = '';
|
||||
$arr['allow_gid'] = '';
|
||||
$arr['deny_cid'] = '';
|
||||
$arr['deny_gid'] = '';
|
||||
$arr['item_hidden'] = 1;
|
||||
$arr['item_private'] = 0;
|
||||
$arr['allow_cid'] = perms2str($u_arr_allow_cid);
|
||||
$arr['allow_gid'] = perms2str($u_arr_allow_gid);
|
||||
$arr['deny_cid'] = perms2str($u_arr_deny_cid);
|
||||
$arr['deny_gid'] = perms2str($u_arr_deny_gid);
|
||||
$arr['item_private'] = $private;
|
||||
$arr['verb'] = ACTIVITY_UPDATE;
|
||||
$arr['obj_type'] = $objtype;
|
||||
$arr['object'] = $u_jsonobject;
|
||||
$arr['resource_id'] = $object['hash'];
|
||||
$arr['resource_type'] = 'attach';
|
||||
$arr['body'] = '';
|
||||
|
||||
$post = item_store($arr);
|
||||
@ -1593,32 +1601,25 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
|
||||
//notice( t('File activity updated') . EOL);
|
||||
}
|
||||
|
||||
//don't create new activity if notify was not enabled
|
||||
if(! $notify) {
|
||||
return;
|
||||
}
|
||||
|
||||
$arr = array();
|
||||
//don't create new activity if we have an update request but there is no item to update
|
||||
//this can e.g. happen when deleting images
|
||||
if(! $y && $verb == 'update') {
|
||||
return;
|
||||
}
|
||||
|
||||
$arr['aid'] = get_account_id();
|
||||
$arr['uid'] = $channel_id;
|
||||
$arr['mid'] = $mid;
|
||||
$arr['parent_mid'] = $mid;
|
||||
$arr['item_wall'] = 1;
|
||||
$arr['item_origin'] = 1;
|
||||
$arr['item_unseen'] = 1;
|
||||
$arr['author_xchan'] = $poster['xchan_hash'];
|
||||
$arr['owner_xchan'] = $poster['xchan_hash'];
|
||||
$arr['title'] = '';
|
||||
$arr['allow_cid'] = perms2str($arr_allow_cid);
|
||||
$arr['allow_gid'] = perms2str($arr_allow_gid);
|
||||
$arr['deny_cid'] = perms2str($arr_deny_cid);
|
||||
$arr['deny_gid'] = perms2str($arr_deny_gid);
|
||||
$arr['item_hidden'] = 1;
|
||||
$arr['item_private'] = $private;
|
||||
$arr['verb'] = (($update) ? ACTIVITY_UPDATE : ACTIVITY_POST);
|
||||
$arr['obj_type'] = $objtype;
|
||||
$arr['resource_id'] = $object['hash'];
|
||||
$arr['resource_type'] = 'attach';
|
||||
$arr['object'] = (($update) ? $u_jsonobject : $jsonobject);
|
||||
$arr['body'] = '';
|
||||
|
||||
@ -1701,11 +1702,11 @@ function recursive_activity_recipients($arr_allow_cid, $arr_allow_gid, $arr_deny
|
||||
$ret = array();
|
||||
$parent_arr = array();
|
||||
$count_values = array();
|
||||
$poster = get_app()->get_observer();
|
||||
$poster = App::get_observer();
|
||||
|
||||
//turn allow_gid into allow_cid's
|
||||
foreach($arr_allow_gid as $gid) {
|
||||
$in_group = in_group($gid);
|
||||
$in_group = group_get_members($gid);
|
||||
$arr_allow_cid = array_unique(array_merge($arr_allow_cid, $in_group));
|
||||
}
|
||||
|
||||
@ -1727,7 +1728,7 @@ function recursive_activity_recipients($arr_allow_cid, $arr_allow_gid, $arr_deny
|
||||
* */
|
||||
if($parent_arr['allow_gid']) {
|
||||
foreach($parent_arr['allow_gid'][$count] as $gid) {
|
||||
$in_group = in_group($gid);
|
||||
$in_group = group_get_members($gid);
|
||||
$parent_arr['allow_cid'][$count] = array_unique(array_merge($parent_arr['allow_cid'][$count], $in_group));
|
||||
}
|
||||
}
|
||||
@ -1808,31 +1809,6 @@ function recursive_activity_recipients($arr_allow_cid, $arr_allow_gid, $arr_deny
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns members of a group.
|
||||
*
|
||||
* @param int $group_id id of the group to look up
|
||||
*/
|
||||
function in_group($group_id) {
|
||||
$group_members = array();
|
||||
|
||||
/** @TODO make these two queries one with a join. */
|
||||
$x = q("SELECT id FROM groups WHERE hash = '%s'",
|
||||
dbesc($group_id)
|
||||
);
|
||||
|
||||
$r = q("SELECT xchan FROM group_member WHERE gid = %d",
|
||||
intval($x[0]['id'])
|
||||
);
|
||||
|
||||
foreach($r as $ig) {
|
||||
$group_members[] = $ig['xchan'];
|
||||
}
|
||||
|
||||
return $group_members;
|
||||
}
|
||||
|
||||
|
||||
function filepath_macro($s) {
|
||||
|
||||
return str_replace(
|
||||
@ -1844,3 +1820,89 @@ function filepath_macro($s) {
|
||||
|
||||
}
|
||||
|
||||
function attach_export_data($channel, $resource_id, $deleted = false) {
|
||||
|
||||
$ret = array();
|
||||
|
||||
$paths = array();
|
||||
|
||||
$hash_ptr = $resource_id;
|
||||
|
||||
$ret['fetch_url'] = z_root() . '/getfile';
|
||||
$ret['original_channel'] = $channel['channel_address'];
|
||||
|
||||
|
||||
if($deleted) {
|
||||
$ret['attach'] = array(array('hash' => $resource_id, 'deleted' => 1));
|
||||
return $ret;
|
||||
}
|
||||
|
||||
do {
|
||||
$r = q("select * from attach where hash = '%s' and uid = %d limit 1",
|
||||
dbesc($hash_ptr),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if(! $r)
|
||||
break;
|
||||
|
||||
if($hash_ptr === $resource_id) {
|
||||
$attach_ptr = $r[0];
|
||||
}
|
||||
|
||||
$hash_ptr = $r[0]['folder'];
|
||||
$paths[] = $r[0];
|
||||
} while($hash_ptr);
|
||||
|
||||
|
||||
|
||||
|
||||
$paths = array_reverse($paths);
|
||||
|
||||
$ret['attach'] = $paths;
|
||||
|
||||
|
||||
if($attach_ptr['is_photo']) {
|
||||
$r = q("select * from photo where resource_id = '%s' and uid = %d order by scale asc",
|
||||
dbesc($resource_id),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if($r) {
|
||||
for($x = 0; $x < count($r); $x ++) {
|
||||
$r[$x]['data'] = base64_encode($r[$x]['data']);
|
||||
}
|
||||
$ret['photo'] = $r;
|
||||
}
|
||||
|
||||
$r = q("select * from item where resource_id = '%s' and resource_type = 'photo' and uid = %d ",
|
||||
dbesc($resource_id),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if($r) {
|
||||
$ret['item'] = array();
|
||||
$items = q("select item.*, item.id as item_id from item where item.parent = %d ",
|
||||
intval($r[0]['id'])
|
||||
);
|
||||
if($items) {
|
||||
xchan_query($items);
|
||||
$items = fetch_post_tags($items,true);
|
||||
foreach($items as $rr)
|
||||
$ret['item'][] = encode_item($rr,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* strip off 'store/nickname/' from the provided path */
|
||||
|
||||
function get_attach_binname($s) {
|
||||
$p = $s;
|
||||
if(strpos($s,'store/') === 0) {
|
||||
$p = substr($s,6);
|
||||
$p = substr($p,strpos($p,'/')+1);
|
||||
}
|
||||
return $p;
|
||||
}
|
@ -12,33 +12,6 @@
|
||||
require_once('include/api_auth.php');
|
||||
require_once('include/security.php');
|
||||
|
||||
/**
|
||||
* @brief Resets the current session.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function nuke_session() {
|
||||
new_cookie(0); // 0 means delete on browser exit
|
||||
|
||||
unset($_SESSION['authenticated']);
|
||||
unset($_SESSION['account_id']);
|
||||
unset($_SESSION['uid']);
|
||||
unset($_SESSION['visitor_id']);
|
||||
unset($_SESSION['administrator']);
|
||||
unset($_SESSION['cid']);
|
||||
unset($_SESSION['theme']);
|
||||
unset($_SESSION['mobile_theme']);
|
||||
unset($_SESSION['show_mobile']);
|
||||
unset($_SESSION['page_flags']);
|
||||
unset($_SESSION['delegate']);
|
||||
unset($_SESSION['delegate_channel']);
|
||||
unset($_SESSION['my_url']);
|
||||
unset($_SESSION['my_address']);
|
||||
unset($_SESSION['addr']);
|
||||
unset($_SESSION['return_url']);
|
||||
unset($_SESSION['remote_service_class']);
|
||||
unset($_SESSION['remote_hub']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Verify login credentials.
|
||||
@ -124,11 +97,11 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
|
||||
|
||||
// process a logout request
|
||||
|
||||
if(((x($_POST, 'auth-params')) && ($_POST['auth-params'] === 'logout')) || ($a->module === 'logout')) {
|
||||
if(((x($_POST, 'auth-params')) && ($_POST['auth-params'] === 'logout')) || (App::$module === 'logout')) {
|
||||
// process logout request
|
||||
$args = array('channel_id' => local_channel());
|
||||
call_hooks('logging_out', $args);
|
||||
nuke_session();
|
||||
\Zotlabs\Web\Session::nuke();
|
||||
info( t('Logged out.') . EOL);
|
||||
goaway(z_root());
|
||||
}
|
||||
@ -144,7 +117,7 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
|
||||
intval(ACCOUNT_ROLE_ADMIN)
|
||||
);
|
||||
if($x) {
|
||||
new_cookie(60 * 60 * 24); // one day
|
||||
\Zotlabs\Web\Session::new_cookie(60 * 60 * 24); // one day
|
||||
$_SESSION['last_login_date'] = datetime_convert();
|
||||
unset($_SESSION['visitor_id']); // no longer a visitor
|
||||
authenticate_success($x[0], true, true);
|
||||
@ -155,75 +128,41 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
|
||||
dbesc($_SESSION['visitor_id'])
|
||||
);
|
||||
if($r) {
|
||||
get_app()->set_observer($r[0]);
|
||||
App::set_observer($r[0]);
|
||||
}
|
||||
else {
|
||||
unset($_SESSION['visitor_id']);
|
||||
unset($_SESSION['authenticated']);
|
||||
}
|
||||
$a->set_groups(init_groups_visitor($_SESSION['visitor_id']));
|
||||
App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
|
||||
}
|
||||
|
||||
// already logged in user returning
|
||||
|
||||
if(x($_SESSION, 'uid') || x($_SESSION, 'account_id')) {
|
||||
|
||||
// first check if we're enforcing that sessions can't change IP address
|
||||
// @todo what to do with IPv6 addresses
|
||||
if($_SESSION['addr'] && $_SESSION['addr'] != $_SERVER['REMOTE_ADDR']) {
|
||||
logger('SECURITY: Session IP address changed: ' . $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
|
||||
|
||||
$partial1 = substr($_SESSION['addr'], 0, strrpos($_SESSION['addr'], '.'));
|
||||
$partial2 = substr($_SERVER['REMOTE_ADDR'], 0, strrpos($_SERVER['REMOTE_ADDR'], '.'));
|
||||
|
||||
$paranoia = intval(get_pconfig($_SESSION['uid'], 'system', 'paranoia'));
|
||||
if(! $paranoia)
|
||||
$paranoia = intval(get_config('system', 'paranoia'));
|
||||
|
||||
switch($paranoia) {
|
||||
case 0:
|
||||
// no IP checking
|
||||
break;
|
||||
case 2:
|
||||
// check 2 octets
|
||||
$partial1 = substr($partial1, 0, strrpos($partial1, '.'));
|
||||
$partial2 = substr($partial2, 0, strrpos($partial2, '.'));
|
||||
if($partial1 == $partial2)
|
||||
break;
|
||||
case 1:
|
||||
// check 3 octets
|
||||
if($partial1 == $partial2)
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
// check any difference at all
|
||||
logger('Session address changed. Paranoid setting in effect, blocking session. '
|
||||
. $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
|
||||
nuke_session();
|
||||
goaway(z_root());
|
||||
break;
|
||||
}
|
||||
}
|
||||
Zotlabs\Web\Session::return_check();
|
||||
|
||||
$r = q("select * from account where account_id = %d limit 1",
|
||||
intval($_SESSION['account_id'])
|
||||
);
|
||||
|
||||
if(($r) && (($r[0]['account_flags'] == ACCOUNT_OK) || ($r[0]['account_flags'] == ACCOUNT_UNVERIFIED))) {
|
||||
get_app()->account = $r[0];
|
||||
App::$account = $r[0];
|
||||
$login_refresh = false;
|
||||
if(! x($_SESSION,'last_login_date')) {
|
||||
$_SESSION['last_login_date'] = datetime_convert('UTC','UTC');
|
||||
}
|
||||
if(strcmp(datetime_convert('UTC','UTC','now - 12 hours'), $_SESSION['last_login_date']) > 0 ) {
|
||||
$_SESSION['last_login_date'] = datetime_convert();
|
||||
Zotlabs\Web\Session::extend_cookie();
|
||||
$login_refresh = true;
|
||||
}
|
||||
authenticate_success($r[0], false, false, false, $login_refresh);
|
||||
}
|
||||
else {
|
||||
$_SESSION['account_id'] = 0;
|
||||
nuke_session();
|
||||
\Zotlabs\Web\Session::nuke();
|
||||
goaway(z_root());
|
||||
}
|
||||
} // end logged in user returning
|
||||
@ -231,7 +170,7 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
|
||||
else {
|
||||
|
||||
if(isset($_SESSION)) {
|
||||
nuke_session();
|
||||
\Zotlabs\Web\Session::nuke();
|
||||
}
|
||||
|
||||
// handle a fresh login request
|
||||
@ -264,16 +203,16 @@ else {
|
||||
$record = $addon_auth['user_record'];
|
||||
}
|
||||
else {
|
||||
$record = get_app()->account = account_verify_password($_POST['username'], $_POST['password']);
|
||||
$record = App::$account = account_verify_password($_POST['username'], $_POST['password']);
|
||||
|
||||
if(get_app()->account) {
|
||||
$_SESSION['account_id'] = get_app()->account['account_id'];
|
||||
if(App::$account) {
|
||||
$_SESSION['account_id'] = App::$account['account_id'];
|
||||
}
|
||||
else {
|
||||
notice( t('Failed authentication') . EOL);
|
||||
}
|
||||
|
||||
logger('authenticate: ' . print_r(get_app()->account, true), LOGGER_DEBUG);
|
||||
logger('authenticate: ' . print_r(App::$account, true), LOGGER_ALL);
|
||||
}
|
||||
|
||||
if((! $record) || (! count($record))) {
|
||||
@ -301,11 +240,13 @@ else {
|
||||
// (i.e. expire when the browser is closed), even when there's a time expiration
|
||||
// on the cookie
|
||||
|
||||
if($_POST['remember']) {
|
||||
new_cookie(31449600); // one year
|
||||
if($_POST['remember_me']) {
|
||||
$_SESSION['remember_me'] = 1;
|
||||
\Zotlabs\Web\Session::new_cookie(31449600); // one year
|
||||
}
|
||||
else {
|
||||
new_cookie(0); // 0 means delete on browser exit
|
||||
$_SESSION['remember_me'] = 0;
|
||||
\Zotlabs\Web\Session::new_cookie(0); // 0 means delete on browser exit
|
||||
}
|
||||
|
||||
// if we haven't failed up this point, log them in.
|
||||
|
@ -473,7 +473,7 @@ function format_event_diaspora($ev) {
|
||||
$ev['start'] , $bd_format ))
|
||||
: day_translate(datetime_convert('UTC', 'UTC',
|
||||
$ev['start'] , $bd_format)))
|
||||
. '](' . $a->get_baseurl() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['start'])) . ")\n";
|
||||
. '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['start'])) . ")\n";
|
||||
|
||||
if(! $ev['nofinish'])
|
||||
$o .= t('Finishes:') . ' ' . '['
|
||||
@ -481,7 +481,7 @@ function format_event_diaspora($ev) {
|
||||
$ev['finish'] , $bd_format ))
|
||||
: day_translate(datetime_convert('UTC', 'UTC',
|
||||
$ev['finish'] , $bd_format )))
|
||||
. '](' . $a->get_baseurl() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['finish'])) . ")\n";
|
||||
. '](' . z_root() . '/localtime/?f=&time=' . urlencode(datetime_convert('UTC','UTC',$ev['finish'])) . ")\n";
|
||||
|
||||
if(strlen($ev['location']))
|
||||
$o .= t('Location:') . bb2diaspora($ev['location'])
|
||||
|
@ -37,7 +37,7 @@ function tryzrlvideo($match) {
|
||||
if($zrl)
|
||||
$link = zid($link);
|
||||
|
||||
return '<video controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . get_app()->videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
|
||||
return '<video controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . App::$videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
|
||||
}
|
||||
|
||||
// [noparse][i]italic[/i][/noparse] turns into
|
||||
@ -243,9 +243,7 @@ function bb_ShareAttributes($match) {
|
||||
if ($matches[1] != "")
|
||||
$message_id = $matches[1];
|
||||
|
||||
|
||||
/** @FIXME - this should really be a wall-item-ago so it will get updated on the client */
|
||||
$reldate = (($posted) ? relative_date($posted) : '');
|
||||
$reldate = '<span class="autotime" title="' . datetime_convert('UTC', date_default_timezone_get(), $posted, 'c') . '" >' . datetime_convert('UTC', date_default_timezone_get(), $posted, 'r') . '</span>';
|
||||
|
||||
$headline = '<div class="shared_container"> <div class="shared_header">';
|
||||
|
||||
@ -280,9 +278,9 @@ function bb_location($match) {
|
||||
function bb_iframe($match) {
|
||||
$a = get_app();
|
||||
|
||||
$sandbox = ((strpos($match[1], $a->get_hostname())) ? ' sandbox="allow-scripts" ' : '');
|
||||
$sandbox = ((strpos($match[1], App::get_hostname())) ? ' sandbox="allow-scripts" ' : '');
|
||||
|
||||
return '<iframe ' . $sandbox . ' src="' . $match[1] . '" width="' . $a->videowidth . '" height="' . $a->videoheight . '"><a href="' . $match[1] . '">' . $match[1] . '</a></iframe>';
|
||||
return '<iframe ' . $sandbox . ' src="' . $match[1] . '" width="' . App::$videowidth . '" height="' . App::$videoheight . '"><a href="' . $match[1] . '">' . $match[1] . '</a></iframe>';
|
||||
}
|
||||
|
||||
function bb_ShareAttributesSimple($match) {
|
||||
@ -315,9 +313,9 @@ function bb_ShareAttributesSimple($match) {
|
||||
|
||||
function rpost_callback($match) {
|
||||
if ($match[2]) {
|
||||
return str_replace($match[0], get_rpost_path(get_app()->get_observer()) . '&title=' . urlencode($match[2]) . '&body=' . urlencode($match[3]), $match[0]);
|
||||
return str_replace($match[0], get_rpost_path(App::get_observer()) . '&title=' . urlencode($match[2]) . '&body=' . urlencode($match[3]), $match[0]);
|
||||
} else {
|
||||
return str_replace($match[0], get_rpost_path(get_app()->get_observer()) . '&body=' . urlencode($match[3]), $match[0]);
|
||||
return str_replace($match[0], get_rpost_path(App::get_observer()) . '&body=' . urlencode($match[3]), $match[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -401,7 +399,7 @@ function bb_observer($Text) {
|
||||
|
||||
$a = get_app();
|
||||
|
||||
$observer = $a->get_observer();
|
||||
$observer = App::get_observer();
|
||||
|
||||
if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
|
||||
if ($observer) {
|
||||
@ -415,7 +413,7 @@ function bb_observer($Text) {
|
||||
}
|
||||
}
|
||||
|
||||
$channel = $a->get_channel();
|
||||
$channel = App::get_channel();
|
||||
|
||||
if (strpos($Text,'[/channel]') !== false) {
|
||||
if ($channel) {
|
||||
@ -477,7 +475,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
|
||||
if($cache)
|
||||
$observer = false;
|
||||
else
|
||||
$observer = $a->get_observer();
|
||||
$observer = App::get_observer();
|
||||
|
||||
if ((strpos($Text,'[/observer]') !== false) || (strpos($Text,'[/rpost]') !== false)) {
|
||||
if ($observer) {
|
||||
@ -494,7 +492,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
|
||||
if($cache)
|
||||
$channel = false;
|
||||
else
|
||||
$channel = $a->get_channel();
|
||||
$channel = App::get_channel();
|
||||
|
||||
if (strpos($Text,'[/channel]') !== false) {
|
||||
if ($channel) {
|
||||
@ -593,6 +591,11 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
|
||||
$Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" target="_blank" >$1</a>', $Text);
|
||||
$Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" target="_blank" >$2</a>', $Text);
|
||||
}
|
||||
|
||||
// Remove bookmarks from UNO
|
||||
if (UNO)
|
||||
$Text = str_replace('<span class="bookmark-identifier">#^</span>', '', $Text);
|
||||
|
||||
// Perform MAIL Search
|
||||
if (strpos($Text,'[/mail]') !== false) {
|
||||
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1" target="_blank" >$1</a>', $Text);
|
||||
@ -684,7 +687,11 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
|
||||
}
|
||||
// Check for centered text
|
||||
if (strpos($Text,'[/center]') !== false) {
|
||||
$Text = preg_replace("(\[center\](.*?)\[\/center\])ism", "<div style=\"text-align:center;\">$1</div>", $Text);
|
||||
$Text = preg_replace("(\[center\](.*?)\[\/center\])ism", "<div style=\"text-align:center;\">$1</div>", $Text);
|
||||
}
|
||||
// Check for footer
|
||||
if (strpos($Text,'[/footer]') !== false) {
|
||||
$Text = preg_replace("(\[footer\](.*?)\[\/footer\])ism", "<div class=\"wall-item-footer\">$1</div>", $Text);
|
||||
}
|
||||
// Check for list text
|
||||
$Text = str_replace("[*]", "<li>", $Text);
|
||||
@ -841,7 +848,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
|
||||
// crypt
|
||||
if (strpos($Text,'[/crypt]') !== false) {
|
||||
$x = random_string();
|
||||
$Text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism",'<br /><div id="' . $x . '"><img src="' .$a->get_baseurl() . '/images/lock_icon.gif" onclick="red_decrypt(\'rot13\',\'\',\'$1\',\'#' . $x . '\');" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br /></div>', $Text);
|
||||
$Text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism",'<br /><div id="' . $x . '"><img src="' .z_root() . '/images/lock_icon.gif" onclick="red_decrypt(\'rot13\',\'\',\'$1\',\'#' . $x . '\');" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br /></div>', $Text);
|
||||
$Text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $Text);
|
||||
}
|
||||
|
||||
@ -921,7 +928,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
|
||||
// $Text = preg_replace("/\[youtube\]https?:\/\/youtu.be\/(.*?)\[\/youtube\]/ism", '[youtube]$1[/youtube]', $Text);
|
||||
|
||||
// if ($tryoembed)
|
||||
// $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="http://www.youtube.com/embed/$1" frameborder="0"></iframe>', $Text);
|
||||
// $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", '<iframe width="' . App::$videowidth . '" height="' . App::$videoheight . '" src="http://www.youtube.com/embed/$1" frameborder="0"></iframe>', $Text);
|
||||
// else
|
||||
// $Text = preg_replace("/\[youtube\]([A-Za-z0-9\-_=]+)(.*?)\[\/youtube\]/ism", "http://www.youtube.com/watch?v=$1", $Text);
|
||||
// }
|
||||
@ -935,7 +942,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
|
||||
// $Text = preg_replace("/\[vimeo\]https?:\/\/vimeo.com\/([0-9]+)(.*?)\[\/vimeo\]/ism", '[vimeo]$1[/vimeo]', $Text);
|
||||
|
||||
// if ($tryoembed)
|
||||
// $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . $a->videowidth . '" height="' . $a->videoheight . '" src="http://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $Text);
|
||||
// $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", '<iframe width="' . App::$videowidth . '" height="' . App::$videoheight . '" src="http://player.vimeo.com/video/$1" frameborder="0" ></iframe>', $Text);
|
||||
// else
|
||||
// $Text = preg_replace("/\[vimeo\]([0-9]+)(.*?)\[\/vimeo\]/ism", "http://vimeo.com/$1", $Text);
|
||||
// }
|
||||
|
@ -202,7 +202,7 @@ function chatroom_list($uid) {
|
||||
require_once('include/security.php');
|
||||
$sql_extra = permissions_sql($uid);
|
||||
|
||||
$r = q("select cr_name, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name",
|
||||
$r = q("select allow_cid, allow_gid, deny_cid, deny_gid, cr_name, cr_expire, cr_id, count(cp_id) as cr_inroom from chatroom left join chatpresence on cr_id = cp_room where cr_uid = %d $sql_extra group by cr_name, cr_id order by cr_name",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
|
@ -9,25 +9,32 @@ function cli_startup() {
|
||||
global $a, $db, $default_timezone;
|
||||
|
||||
if(is_null($a)) {
|
||||
$a = new App;
|
||||
$a = new miniApp;
|
||||
}
|
||||
|
||||
App::init();
|
||||
|
||||
if(is_null($db)) {
|
||||
@include(".htconfig.php");
|
||||
|
||||
$a->timezone = ((x($default_timezone)) ? $default_timezone : 'UTC');
|
||||
date_default_timezone_set($a->timezone);
|
||||
$a->convert();
|
||||
|
||||
if(! defined('UNO'))
|
||||
define('UNO', 0);
|
||||
|
||||
App::$timezone = ((x($default_timezone)) ? $default_timezone : 'UTC');
|
||||
date_default_timezone_set(App::$timezone);
|
||||
|
||||
require_once('include/dba/dba_driver.php');
|
||||
$db = dba_factory($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type);
|
||||
unset($db_host, $db_port, $db_user, $db_pass, $db_data, $db_type);
|
||||
};
|
||||
|
||||
require_once('include/session.php');
|
||||
\Zotlabs\Web\Session::init();
|
||||
|
||||
load_config('system');
|
||||
|
||||
$a->set_baseurl(get_config('system','baseurl'));
|
||||
App::set_baseurl(get_config('system','baseurl'));
|
||||
|
||||
load_hooks();
|
||||
|
||||
|
@ -56,34 +56,34 @@ function comanche_parser(&$a, $s, $pass = 0) {
|
||||
if($pass == 0) {
|
||||
$cnt = preg_match("/\[layout\](.*?)\[\/layout\]/ism", $s, $matches);
|
||||
if($cnt)
|
||||
$a->page['template'] = trim($matches[1]);
|
||||
App::$page['template'] = trim($matches[1]);
|
||||
|
||||
$cnt = preg_match("/\[template=(.*?)\](.*?)\[\/template\]/ism", $s, $matches);
|
||||
if($cnt) {
|
||||
$a->page['template'] = trim($matches[2]);
|
||||
$a->page['template_style'] = trim($matches[2]) . '_' . $matches[1];
|
||||
App::$page['template'] = trim($matches[2]);
|
||||
App::$page['template_style'] = trim($matches[2]) . '_' . $matches[1];
|
||||
}
|
||||
|
||||
$cnt = preg_match("/\[template\](.*?)\[\/template\]/ism", $s, $matches);
|
||||
if($cnt) {
|
||||
$a->page['template'] = trim($matches[1]);
|
||||
App::$page['template'] = trim($matches[1]);
|
||||
}
|
||||
|
||||
$cnt = preg_match("/\[theme=(.*?)\](.*?)\[\/theme\]/ism", $s, $matches);
|
||||
if($cnt) {
|
||||
$a->layout['schema'] = trim($matches[1]);
|
||||
$a->layout['theme'] = trim($matches[2]);
|
||||
App::$layout['schema'] = trim($matches[1]);
|
||||
App::$layout['theme'] = trim($matches[2]);
|
||||
}
|
||||
|
||||
$cnt = preg_match("/\[theme\](.*?)\[\/theme\]/ism", $s, $matches);
|
||||
if($cnt)
|
||||
$a->layout['theme'] = trim($matches[1]);
|
||||
App::$layout['theme'] = trim($matches[1]);
|
||||
|
||||
$cnt = preg_match_all("/\[webpage\](.*?)\[\/webpage\]/ism", $s, $matches, PREG_SET_ORDER);
|
||||
if($cnt) {
|
||||
// only the last webpage definition is used if there is more than one
|
||||
foreach($matches as $mtch) {
|
||||
$a->layout['webpage'] = comanche_webpage($a,$mtch[1]);
|
||||
App::$layout['webpage'] = comanche_webpage($a,$mtch[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ function comanche_parser(&$a, $s, $pass = 0) {
|
||||
$cnt = preg_match_all("/\[region=(.*?)\](.*?)\[\/region\]/ism", $s, $matches, PREG_SET_ORDER);
|
||||
if($cnt) {
|
||||
foreach($matches as $mtch) {
|
||||
$a->layout['region_' . $mtch[1]] = comanche_region($a,$mtch[2]);
|
||||
App::$layout['region_' . $mtch[1]] = comanche_region($a,$mtch[2]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,8 +122,8 @@ function comanche_menu($s, $class = '') {
|
||||
|
||||
function comanche_replace_region($match) {
|
||||
$a = get_app();
|
||||
if (array_key_exists($match[1], $a->page)) {
|
||||
return $a->page[$match[1]];
|
||||
if (array_key_exists($match[1], App::$page)) {
|
||||
return App::$page[$match[1]];
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,7 +136,7 @@ function comanche_replace_region($match) {
|
||||
* @return channel_id
|
||||
*/
|
||||
function comanche_get_channel_id() {
|
||||
$channel_id = ((is_array(get_app()->profile)) ? get_app()->profile['profile_uid'] : 0);
|
||||
$channel_id = ((is_array(App::$profile)) ? App::$profile['profile_uid'] : 0);
|
||||
|
||||
if ((! $channel_id) && (local_channel()))
|
||||
$channel_id = local_channel();
|
||||
@ -190,7 +190,7 @@ function comanche_block($s, $class = '') {
|
||||
}
|
||||
|
||||
if(trim($r[0]['body']) === '$content') {
|
||||
$o .= get_app()->page['content'];
|
||||
$o .= App::$page['content'];
|
||||
}
|
||||
else {
|
||||
$o .= prepare_text($r[0]['body'], $r[0]['mimetype']);
|
||||
@ -275,6 +275,7 @@ function comanche_widget($name, $text) {
|
||||
$vars = array();
|
||||
$matches = array();
|
||||
|
||||
|
||||
$cnt = preg_match_all("/\[var=(.*?)\](.*?)\[\/var\]/ism", $text, $matches, PREG_SET_ORDER);
|
||||
if ($cnt) {
|
||||
foreach ($matches as $mtch) {
|
||||
@ -287,8 +288,7 @@ function comanche_widget($name, $text) {
|
||||
if(! function_exists($func)) {
|
||||
if(file_exists('widget/' . trim($name) . '.php'))
|
||||
require_once('widget/' . trim($name) . '.php');
|
||||
elseif(folder_exists('widget/'. trim($name))
|
||||
&& (file_exists('widget/' . trim($name) . '/' . trim($name) . '.php')))
|
||||
elseif(file_exists('widget/' . trim($name) . '/' . trim($name) . '.php'))
|
||||
require_once('widget/' . trim($name) . '/' . trim($name) . '.php');
|
||||
}
|
||||
else {
|
||||
@ -378,6 +378,6 @@ function comanche_region(&$a, $s) {
|
||||
|
||||
|
||||
function register_page_template($arr) {
|
||||
get_app()->page_layouts[$arr['template']] = array($arr['variant']);
|
||||
App::$page_layouts[$arr['template']] = array($arr['variant']);
|
||||
return;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user