mirror of
https://codeberg.org/streams/streams.git
synced 2024-09-22 06:15:31 +00:00
commit
e81949bb09
569 changed files with 35630 additions and 20908 deletions
|
@ -2,10 +2,19 @@
|
|||
|
||||
Run hubzilla-setup.sh for an unattended installation of hubzilla.
|
||||
|
||||
The script is known to work with Debian 8.3 stable (Jessie)
|
||||
The script is known to work without adjustments with
|
||||
|
||||
+ Home-PC (Debian-8.3.0-amd64)
|
||||
+ DigitalOcean droplet (Debian 8.3 x64 / 512 MB Memory / 20 GB Disk / NYC3)
|
||||
+ Hardware
|
||||
- Mini-PC with Debian-9.2-amd64, or
|
||||
- Rapberry 3 with Raspbian, Debian-9.3
|
||||
+ DynDNS
|
||||
- selfHOST.de
|
||||
- freedns.afraid.org
|
||||
|
||||
## Disclaimers
|
||||
|
||||
- This script does work with Debian 9 only.
|
||||
- This script has to be used on a fresh debian install only (it does not take account for a possibly already installed and configured webserver or sql implementation).
|
||||
|
||||
# Step-by-Step Overwiew
|
||||
|
||||
|
@ -14,25 +23,28 @@ The script is known to work with Debian 8.3 stable (Jessie)
|
|||
Hardware
|
||||
|
||||
+ Internet connection and router at home
|
||||
+ Mini-pc connected to your router
|
||||
+ Mini-pc connected to your router (a Raspberry 3 will do for very small Hubs)
|
||||
+ USB drive for backups
|
||||
|
||||
Software
|
||||
|
||||
+ Fresh installation of Debian on your mini-pc
|
||||
+ Router with open ports 80 and 443 for your Debian
|
||||
+ Fresh installation of Debian 9 (Stretch)
|
||||
+ Router with open ports 80 and 443 for your Hub
|
||||
|
||||
## 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)
|
||||
+ Log on to your fresh Debian
|
||||
- apt-get install git
|
||||
- mkdir -p /var/www
|
||||
- cd /var/www
|
||||
- git clone https://github.com/redmatrix/hubzilla.git html
|
||||
- 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
|
||||
- cd /html/.homeinstall
|
||||
- cp hubzilla-config.txt.template hubzilla-config.txt
|
||||
- nano hubzilla-config.txt
|
||||
- Read the comments carefully
|
||||
- Enter your values: db pass, domain, values for dyn DNS
|
||||
- Make sure your external drive (for backups) is mounted
|
||||
- hubzilla-setup.sh as root
|
||||
- ... wait, wait, wait until the script is finised
|
||||
- reboot
|
||||
|
@ -46,23 +58,44 @@ Software
|
|||
|
||||
### Recommended: USB Drive for Backups
|
||||
|
||||
The installation will create a daily backup.
|
||||
The installation will create a daily backup written to an external drive.
|
||||
|
||||
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 the filesystems
|
||||
|
||||
The USB drive must be compatible with an encrpyted filesystem LUKS + ext4.
|
||||
- ext4 (if you do not want to encrypt the USB)
|
||||
- LUKS + ext4 (if you want to encrypt the USB)
|
||||
|
||||
The backup includes
|
||||
|
||||
- Hubzilla DB
|
||||
- Hubzilla installation /var/www/html
|
||||
- Certificates for letsencrypt
|
||||
|
||||
## Preparations Software
|
||||
|
||||
### Install Debian Linux on the Mini-PC
|
||||
|
||||
Download the stable Debian at https://www.debian.org/
|
||||
Download the stable Debian at https://www.debian.org/
|
||||
(Debian 8 is no longer supported.)
|
||||
|
||||
Create bootable USB drive with Debian on it. You could use the programm
|
||||
unetbootin, https://en.wikipedia.org/wiki/UNetbootin
|
||||
Create bootable USB drive with Debian on it.You could use
|
||||
|
||||
Switch of your mini pc, plug in your USB drive and start the mini pc from the
|
||||
- unetbootin, https://en.wikipedia.org/wiki/UNetbootin
|
||||
- or simply the linux command "dd"
|
||||
|
||||
Example for command dd...
|
||||
|
||||
su -
|
||||
dd if=2017-11-29-raspbian-stretch.img of=/dev/mmcblk0
|
||||
|
||||
Do not forget to unmount the SD card before and check if unmounted like in this example...
|
||||
|
||||
su -
|
||||
umount /dev/mmcblk0*
|
||||
df -h
|
||||
|
||||
|
||||
Switch off 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
|
||||
|
@ -79,28 +112,20 @@ You can use subdomains as well
|
|||
|
||||
my.cooldomain.org
|
||||
|
||||
There are two way to get a domain
|
||||
There are two ways to get a domain...
|
||||
|
||||
- buy a domain (recommended) or
|
||||
- register a free subdomain
|
||||
### Method 1: Buy a Domain
|
||||
|
||||
### Method 1: Get yourself an own Domain (recommended)
|
||||
...for example buy at selfHOST.de
|
||||
|
||||
...for example at selfHOST.de
|
||||
The cost are around 10,- € once and 1,50 € per month (2017).
|
||||
|
||||
### Method 2 Register a (free) Subdomain
|
||||
|
||||
Register a free subdomain for example at
|
||||
...for example register at freedns.afraid.org
|
||||
|
||||
- freeDNS
|
||||
- selfHOST
|
||||
Follow the instructions in .homeinstall/hubzilla-config.txt.
|
||||
|
||||
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
|
||||
|
||||
|
@ -135,10 +160,12 @@ 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.
|
||||
Modify the file "hubzilla-config.txt". Read the instructions there carefully and enter your values.
|
||||
|
||||
nano hubzilla-config.txt
|
||||
|
||||
Make sure your external drive (for backups) is plugged in and can be mounted as configured in "hubzilla-config.txt". Otherwise the daily backups will not work.
|
||||
|
||||
Run the script
|
||||
|
||||
./hubzilla-setup.sh
|
||||
|
@ -146,7 +173,7 @@ Run the script
|
|||
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
|
||||
Expected: A test page of hubzilla is shown. All checks there should be
|
||||
successfull. Go on...
|
||||
Expected: A page for the Hubzilla server configuration shows up.
|
||||
|
||||
|
@ -162,3 +189,28 @@ Leave db type "MySQL" untouched.
|
|||
|
||||
Follow the instructions in the next pages.
|
||||
|
||||
After the daily script was executed at 05:30 (am)
|
||||
|
||||
- look at var/www/html/hubzilla-daily.log
|
||||
- check your backup on the external drive
|
||||
- optionally view the daily log under yourdomain.org/admin/logs/
|
||||
- set the logfile to var/www/html/hubzilla-daily.log
|
||||
|
||||
## Note for the Rasperry
|
||||
|
||||
The script was tested with an Raspberry 3 under Raspian (Debian 9.3, 2017-11-29-raspbian-stretch.img).
|
||||
|
||||
It is recommended to deinstall these programms to avoid endless updates. Use...
|
||||
|
||||
sudo apt-get purge wolfram-engine sonic-pi
|
||||
sudo apt-get autoremove
|
||||
|
||||
It is recommended to run the Raspi without graphical frontend (X-Server). Use...
|
||||
|
||||
sudo raspi-config
|
||||
|
||||
to boot the Rapsi to the client console.
|
||||
|
||||
DO NOT FORGET TO CHANGE THE DEFAULT PASSWORD FOR USER PI!
|
||||
|
||||
|
||||
|
|
|
@ -70,15 +70,17 @@ selfhost_pass=
|
|||
# freedns_key=U1Z6aGt2R0NzMFNPNWRjbWxxZGpsd093OjE1Mzg5NDE5
|
||||
#
|
||||
#
|
||||
#freedns_key=
|
||||
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
|
||||
# The file system of the device (USB stick for example) must be compatible with
|
||||
#
|
||||
# - encrypted LUKS + ext4, or
|
||||
# - ext4
|
||||
#
|
||||
# You should test to mount the device befor you run the script
|
||||
# (hubzilla-setup.sh).
|
||||
|
@ -113,27 +115,21 @@ selfhost_pass=
|
|||
# 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
|
||||
#
|
||||
# Leave "backup_device_pass=" empty if the external device is not encrypted.
|
||||
#
|
||||
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)
|
||||
|
@ -160,18 +156,3 @@ mysqlpass=$db_pass
|
|||
# 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=
|
||||
|
||||
|
|
|
@ -114,7 +114,11 @@ function check_sanity {
|
|||
fi
|
||||
if [ ! -f /etc/debian_version ]
|
||||
then
|
||||
die "Ubuntu is not supported"
|
||||
die "Debian is supported only"
|
||||
fi
|
||||
if ! grep -q 'Linux 9' /etc/issue
|
||||
then
|
||||
die "Linux 9 (stretch) is supported only"x
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -253,11 +257,11 @@ function install_sendmail {
|
|||
}
|
||||
|
||||
function install_php {
|
||||
# openssl and mbstring are included in libapache2-mod-php5
|
||||
# to_to: php5-suhosin
|
||||
# openssl and mbstring are included in libapache2-mod-php
|
||||
print_info "installing php..."
|
||||
nocheck_install "libapache2-mod-php5 php5 php-pear php5-xcache php5-curl php5-mcrypt php5-gd"
|
||||
php5enmod mcrypt
|
||||
nocheck_install "libapache2-mod-php php php-pear php-curl php-mcrypt php-gd"
|
||||
sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php/7.0/apache2/php.ini
|
||||
sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php/7.0/apache2/php.ini
|
||||
}
|
||||
|
||||
function install_mysql {
|
||||
|
@ -277,18 +281,17 @@ function install_mysql {
|
|||
# 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
|
||||
# echo mysql-server mysql-server/root_password password xyzzy | debconf-set-selections
|
||||
# echo mysql-server 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
|
||||
echo mysql-server mysql-server/root_password password $mysqlpass | debconf-set-selections
|
||||
echo mysql-server mysql-server/root_password_again password $mysqlpass | debconf-set-selections
|
||||
nocheck_install "php-mysql mysql-server mysql-client"
|
||||
}
|
||||
|
||||
function install_phpmyadmin {
|
||||
|
@ -327,6 +330,7 @@ function install_phpmyadmin {
|
|||
echo "Include /etc/phpmyadmin/apache.conf" >> /etc/apache2/apache2.conf
|
||||
fi
|
||||
service apache2 restart
|
||||
/etc/init.d/mysql start
|
||||
}
|
||||
|
||||
function create_hubzilla_db {
|
||||
|
@ -455,11 +459,6 @@ function configure_cron_selfhost {
|
|||
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
|
||||
|
@ -511,6 +510,8 @@ END
|
|||
then
|
||||
die "Failed to load $url_http"
|
||||
fi
|
||||
# accept terms of service of letsencrypt
|
||||
./dehydrated --register --accept-terms
|
||||
# run script dehydrated
|
||||
#
|
||||
./dehydrated --cron --config $le_dir/config.sh
|
||||
|
@ -564,17 +565,13 @@ function check_https {
|
|||
}
|
||||
|
||||
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
|
||||
print_info "installing hubzilla addons..."
|
||||
cd /var/www/html/
|
||||
util/add_addon_repo https://github.com/redmatrix/hubzilla-addons.git hzaddons
|
||||
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/
|
||||
|
@ -589,73 +586,6 @@ function install_hubzilla {
|
|||
print_info "installed hubzilla"
|
||||
}
|
||||
|
||||
function install_hubzilla_plugins {
|
||||
print_info "installing hubzilla plugins..."
|
||||
cd /var/www/html
|
||||
plugin_install=.homeinstall/plugin_install.txt
|
||||
theme_install=.homeinstall/theme_install.txt
|
||||
# overwrite script to update the plugin and themes
|
||||
rm -f $plugins_update
|
||||
echo "cd /var/www/html" >> $plugins_update
|
||||
###################
|
||||
# write plugin file
|
||||
if [ ! -f "$plugin_install" ]
|
||||
then
|
||||
echo "# To install a plugin" >> $plugin_install
|
||||
echo "# 1. add the plugin in a new line and run" >> $plugin_install
|
||||
echo "# 2. run" >> $plugin_install
|
||||
echo "# cd /var/www/html/.homeinstall" >> $plugin_install
|
||||
echo "# ./hubzilla-setup.sh" >> $plugin_install
|
||||
echo "https://gitlab.com/zot/ownmapp.git ownMapp" >> $plugin_install
|
||||
echo "https://gitlab.com/zot/hubzilla-chess.git chess" >> $plugin_install
|
||||
fi
|
||||
# install plugins
|
||||
while read -r line; do
|
||||
[[ "$line" =~ ^#.*$ ]] && continue
|
||||
p_url=$(echo $line | awk -F' ' '{print $1}')
|
||||
p_name=$(echo $line | awk -F' ' '{print $2}')
|
||||
# basic check of format
|
||||
if [ ${#p_url} -ge 1 ] && [ ${#p_name} -ge 1 ]
|
||||
then
|
||||
# install addon
|
||||
util/add_addon_repo $line
|
||||
util/update_addon_repo $p_name # not sure if this line is neccessary
|
||||
echo "util/update_addon_repo $p_name" >> $plugins_update
|
||||
else
|
||||
print_info "skipping installation of a plugin from file $plugin_install - something wrong with format in line: $line"
|
||||
fi
|
||||
done < "$plugin_install"
|
||||
###################
|
||||
# write theme file
|
||||
if [ ! -f "$theme_install" ]
|
||||
then
|
||||
echo "# To install a theme" >> $theme_install
|
||||
echo "# 1. add the theme in a new line and run" >> $theme_install
|
||||
echo "# 2. run" >> $theme_install
|
||||
echo "# cd /var/www/html/.homeinstall" >> $theme_install
|
||||
echo "# ./hubzilla-setup.sh" >> $theme_install
|
||||
echo "https://github.com/DeadSuperHero/hubzilla-themes.git DeadSuperHeroThemes" >> $theme_install
|
||||
|
||||
fi
|
||||
# install plugins
|
||||
while read -r line; do
|
||||
[[ "$line" =~ ^#.*$ ]] && continue
|
||||
p_url=$(echo $line | awk -F' ' '{print $1}')
|
||||
p_name=$(echo $line | awk -F' ' '{print $2}')
|
||||
# basic check of format
|
||||
if [ ${#p_url} -ge 1 ] && [ ${#p_name} -ge 1 ]
|
||||
then
|
||||
# install addon
|
||||
util/add_theme_repo $line
|
||||
util/update_theme_repo $p_name # not sure if this line is neccessary
|
||||
echo "util/update_theme_repo $p_name" >> $plugins_update
|
||||
else
|
||||
print_info "skipping installation of a theme from file $theme_install - something wrong with format in line: $line"
|
||||
fi
|
||||
done < "$theme_install"
|
||||
print_info "installed hubzilla plugins and themes"
|
||||
}
|
||||
|
||||
function rewrite_to_https {
|
||||
print_info "configuring apache to redirect http to httpS ..."
|
||||
htaccessfile=/var/www/html/.htaccess
|
||||
|
@ -675,25 +605,19 @@ function rewrite_to_https {
|
|||
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
|
||||
# internal disk
|
||||
cp -f /etc/rsnapshot.conf $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
|
||||
echo "backup /var/lib/mysql/ localhost/" >> $snapshotconfig
|
||||
echo "backup /var/www/html/ localhost/" >> $snapshotconfig
|
||||
echo "backup /var/www/letsencrypt/ localhost/" >> $snapshotconfig
|
||||
# external disk
|
||||
if [ -n "$backup_device_name" ] && [ -n "$backup_device_pass" ]
|
||||
if [ -n "$backup_device_name" ]
|
||||
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 "/alpha/s/6/30/" $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`" ]
|
||||
|
@ -767,9 +691,7 @@ echo " if mount $backup_device_name $backup_mount_point" >> /var/www/$hub
|
|||
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 " rsnapshot -c $snapshotconfig_external_device alpha" >> /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
|
||||
|
@ -788,28 +710,22 @@ 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 " echo \"device could not be mounted $backup_device_name. No backup written.\"" >> /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 "du -h /var/lib/mysql/ | grep mysql/hubzilla" >> /var/www/$hubzilladaily
|
||||
echo "#" >> /var/www/$hubzilladaily
|
||||
echo "# update" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - updating dehydrated...\"" >> /var/www/$hubzilladaily
|
||||
echo "git -C /var/www/letsencrypt/ pull" >> /var/www/$hubzilladaily
|
||||
echo "echo \"\$(date) - updating hubhilla core...\"" >> /var/www/$hubzilladaily
|
||||
echo "git -C /var/www/html/ pull" >> /var/www/$hubzilladaily
|
||||
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 "(cd /var/www/html/ ; util/udall)" >> /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 "apt-get -q -y update && apt-get -q -y dist-upgrade && apt-get -q -y autoremove # 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
|
||||
|
@ -894,7 +810,6 @@ install_run_selfhost
|
|||
ping_domain
|
||||
configure_cron_freedns
|
||||
configure_cron_selfhost
|
||||
install_git
|
||||
install_letsencrypt
|
||||
configure_apache_for_https
|
||||
check_https
|
||||
|
|
24
.travis.yml
24
.travis.yml
|
@ -39,6 +39,7 @@ addons:
|
|||
php:
|
||||
- '7.0'
|
||||
- '7.1'
|
||||
- '7.2'
|
||||
# HHVM does not fulfil PHPUnit platform requirements as being compatible with PHP7 yet
|
||||
#- 'hhvm'
|
||||
|
||||
|
@ -69,7 +70,7 @@ matrix:
|
|||
mariadb: '10.1'
|
||||
# PHP7.1, PostgreSQL 9.6
|
||||
- php: '7.1'
|
||||
env: DB=pgsql POSTGRESQL_VERSION=9.6
|
||||
env: DB=pgsql POSTGRESQL_VERSION=9.6 PHPUNITFILE=phpunit-pgsql.xml
|
||||
# Use newer postgres than 9.2 default
|
||||
addons:
|
||||
postgresql: '9.6'
|
||||
|
@ -125,15 +126,19 @@ before_script:
|
|||
- if [[ "$DB" == "pgsql" ]]; then ./tests/travis/prepare_pgsql.sh; fi
|
||||
|
||||
# omitting "script:" will default to phpunit
|
||||
script: ./vendor/bin/phpunit $PHPUCOV -c tests/phpunit-$DB.xml
|
||||
script:
|
||||
- ./vendor/bin/phpunit $PHPUCOV -c tests/$PHPUNITFILE
|
||||
|
||||
after_success:
|
||||
# Generate API documentation and deploy it to gh-pages
|
||||
- cat tests/results/testdox.txt
|
||||
# Generate API documentation and prepare for deployment
|
||||
- ./tests/travis/gen_apidocs.sh
|
||||
#after_failure:
|
||||
after_failure:
|
||||
- cat tests/results/testdox.txt
|
||||
|
||||
# Deploying release and API documentation to GitHub
|
||||
#before_deploy:
|
||||
before_deploy:
|
||||
- if [[ "$CODECOV" == "1" ]]; then zip -9 -r -q tests/hubzilla-testresults.zip tests/results; fi
|
||||
deploy:
|
||||
- provider: pages
|
||||
skip_cleanup: true
|
||||
|
@ -152,6 +157,15 @@ deploy:
|
|||
repo: redmatrix/hubzilla
|
||||
tags: true
|
||||
condition: '(-n "$GH_TOKEN") && ("$TRAVIS_JOB_NUMBER" == "${TRAVIS_BUILD_NUMBER}.1")'
|
||||
# add code coverage and test results to release
|
||||
- provider: releases
|
||||
skip_cleanup: true
|
||||
api_key: $GH_TOKEN
|
||||
file: 'tests/hubzilla-testresults.zip'
|
||||
on:
|
||||
repo: redmatrix/hubzilla
|
||||
tags: true
|
||||
condition: '(-n "$GH_TOKEN") && ("$CODECOV" == "1")'
|
||||
#after_deploy:
|
||||
|
||||
#after_script:
|
||||
|
|
144
CHANGELOG
144
CHANGELOG
|
@ -1,3 +1,147 @@
|
|||
Hubzilla 3.0 (2018-01-09)
|
||||
- Updated homeinstall script
|
||||
- Sort cloud directory by 1. is_dir and 2. name
|
||||
- Document that imagick calls/execs ffmpeg for mp4 video thumbnails
|
||||
- Use pipe_stream() instead of file_{get, put}_contents() in attach_store()
|
||||
- Make homeinstall script ready for Debian 9
|
||||
- Add url and headings to bbco_autocomplete()
|
||||
- Remove additional linebreaks after headings
|
||||
- html2bbcode: use headings bbcode for headings
|
||||
- Don't zidify all permalinks, only zot permalinks
|
||||
- Make remote homelink link to the home host and not to the home channel
|
||||
- Auto promote beginner (techlevel 0) accounts to level 1 after they show signs of active participation.
|
||||
- Go back to including the photo thumbnail data in the export file.
|
||||
- Improvements to file import/export
|
||||
- Default value for xlink_rating_text
|
||||
- Implement IMoveTarget and recursive file/directory move/rename - github issue #680
|
||||
- Synchronise an attach_move operation to clones
|
||||
- Provide a themed page with an error notification on errors instead of an obtuse XML error structure in mod cloud
|
||||
- Disallow backslashes in wiki and wiki-page names
|
||||
- We only require one update module. The rest are superfluous.
|
||||
- Render installable elements as buttons instead of links
|
||||
- Implement chunked uploads for photos page
|
||||
- Remove warning for large files on cloud upload
|
||||
- Add a filter for notification to show new posts only
|
||||
- Implement chunked uploads for cloud
|
||||
- Use httpsig auth for getfile
|
||||
- Load the profile images in the custom acl selector only if we actually need them
|
||||
- Rework liveUpdate() and notificationsUpdate() (aka ping) to first do the liveUpdate and when this is done only do the ping once.
|
||||
- Don't include invisible "update activities" in category widget
|
||||
- Default profile assign
|
||||
- Provide system config option for minimum registration age.
|
||||
- Remove deprecated $a argument from advanced_profile()
|
||||
- Change to bbcode calling parameters
|
||||
- Extra checking of server headers in upload functions
|
||||
- Provide a handler for chunked uploads in mod file_upload
|
||||
- Optional divider between item header and body
|
||||
- Allow toggle to SMBC scaling mode.
|
||||
- Add thumbnail hook
|
||||
- Implement SVG thumbnails and expose security setting
|
||||
- Implement video thumbnail generator
|
||||
- Implement pdf thumbnails
|
||||
- Implement thumbnail generator for epubs
|
||||
- Make browser history buttons work with ajax calls in mod display and hq
|
||||
- Implement tile view for mod cloud (read only)
|
||||
- Add mp3 audio thumbnail generator
|
||||
- Set display_path for photo_upload from the DAV File interface
|
||||
- Provide a generalised interface for thumbnail generators to support various content types
|
||||
- Add ID3Parser library.
|
||||
- Text thumbnails in cloud tile mode
|
||||
- Revisit media breakpoints - do not switch to mobile view to early.
|
||||
- Add French to help pages language dropdown selector
|
||||
- Inroduce the HQ module - an alternative landing page for hubzilla
|
||||
- Strip author name from notify messages in notifications - github issue #911
|
||||
- Remove column item.diaspora_meta
|
||||
- Provide ability to pin apps to navbar from mod apps
|
||||
- Add private forums to forum widget
|
||||
- Move notifications style to widgets.css
|
||||
- Sort out a few more large image upload issues
|
||||
- Move notifications full-screen handling to notifications widget
|
||||
- Move mailhost settings from plugin to core
|
||||
- Sort combined private mail conversations by latest updated conversation instead of created parent
|
||||
- Filter atokens on acl search
|
||||
- Allow a site to block (public) the directory separately from other resources.
|
||||
- Improve removed_channel final cleanup - github issue #386
|
||||
- Cleanup of upload_to_comments(
|
||||
- Dedicate the first click to slideup the cover again but make sure the nav buttons remain functional
|
||||
- Set os_syspath in DAV file put operation so that photos will scale correctly.
|
||||
- Unit tests for Zotlabs\Access classes
|
||||
- Bring back tabindex to submit comments
|
||||
- attach.php minor cleanup and doc
|
||||
- Allow cloud filenames to include ampersands without messing up auth tokens (zid, owt, and zat, and the constant placeholder 'f=')
|
||||
- Provide short localised summary for likes that will end up in displayed notifications
|
||||
- Improving Doxygen documentation.
|
||||
- Update item_normal() to not include ACTIVITY_OBJ_FILE obj_type
|
||||
- Sort out issues with pubstream item interactions
|
||||
- Don't perform zot_refresh on dead sites unless $force is set
|
||||
- Do not send message_list responses to dead sites (this delivery method bypassed the notifier)
|
||||
- Support for netselect query
|
||||
- Add another delivery control parameter (queue threshold)
|
||||
- Add some documentation about shareable widgets
|
||||
- Allow plugin class widgets
|
||||
- Some more work on unit tests
|
||||
- Encrypt the owa token
|
||||
- Bring back the markdown post feature
|
||||
- We call Theme:url() statically, make it also static.
|
||||
- Table structure for pseudo or proxy channels (pchan)
|
||||
|
||||
Bugfixes
|
||||
- Fix sync non-default profile photo changes to clones - github issue #113
|
||||
- Fix prev/next buttons on connedit can show deleted connections - github issue #673
|
||||
- Fix affinity widget settings
|
||||
- Fix dupe bug in content hooks - github issue #943
|
||||
- Fix directory keywords returned from dir_tagadelic() in standalone mode
|
||||
- Fix argument warning when arguments are correct in util/dcp
|
||||
- Fix issue with long filenames in mod cloud
|
||||
- Fix misc. issues with new 'insert photo from photo album' github issue #475
|
||||
- Fix regression in channel sources delivery
|
||||
- Fix loading of theme-specific widgets
|
||||
- Fix unable to add wiki pages with spaces
|
||||
- Fix mod display and others that require a non-zero profile_uid for updates
|
||||
- Fix various PHP 7.2 issues
|
||||
- Fix typo in HTTPSig
|
||||
- Fix pagetitle lost importing a pdl element from conversation
|
||||
- Fix js warning - getelementbyid (id doesn't exist)
|
||||
- Fix some pubstream on/off weirdness
|
||||
- Fix default addressbook has no name - github issue #921
|
||||
- Fix double html ids in caldav widget if more than one sharee
|
||||
- Fix regression in cdav calendar widget
|
||||
- Fix sync packet not generated when deleting a file using the web browser interface
|
||||
- Fix album cover thumb generator
|
||||
- Fix like-button for images - github issue #826
|
||||
- Fix typo - github issue #910
|
||||
- Fix issue with group_rmv()
|
||||
- Fix php warnings on photo delete
|
||||
- Fix some conflicts between private tags and forum tags
|
||||
- Fix some schema issues
|
||||
- Fix wiki pages not updating after creating new page
|
||||
- Fix a PHP warning in Permissions::FilledPerms()
|
||||
- Fix unicode characters in urls tripping up url regexes - github issue #901
|
||||
- Fix second half of github issue #893
|
||||
- Fix common connections on suggestion page showing wildly different results than remote profile, and is consistently off by one
|
||||
- Fix cloud redirects with owt tokens
|
||||
- Fix issues with diaspora xchans
|
||||
- Fix memory overflow trying to delete a connection with a very high noise to signal ratio
|
||||
- Fix sql error in page module
|
||||
- Fix unstar
|
||||
|
||||
Plugins/Addon
|
||||
Diaspora: fix 'view full size' photo link - core github issue #947
|
||||
Diaspora: implement recent changes in diaspora account_migration spec
|
||||
GNU-Social: fix uploading a photo to a post results in double post - github issue 75
|
||||
GNU-Social: fix gnusoc plugin not respecting delayed delivery - github issue 74
|
||||
Pubcrawl: fix PHP warning
|
||||
Diaspora: remove garbage from magic envelope
|
||||
Diaspora: fix permalinks for zot reshares
|
||||
New addon: hzfiles - sync files across hubzilla servers
|
||||
Fix various PHP 7.2 issues
|
||||
Remove Firefox social plugin - it was deprecated and removed in firefox version 57
|
||||
Diaspora: unset id and parent for local comments
|
||||
Pubsubhubbub: set interactive flag to avoid delivery killing if block_public is enabled
|
||||
Mailhost addon moved to core
|
||||
Remove js_upload addon
|
||||
|
||||
|
||||
Hubzilla 2.8.1 (2017-11-11)
|
||||
- Rename channel app events to calendar and add nav_set_selected() to /cal
|
||||
- Load notifications links to /display via ajax if we are already in /display
|
||||
|
|
|
@ -3,10 +3,14 @@
|
|||
namespace Zotlabs\Access;
|
||||
|
||||
/**
|
||||
* @brief AccessList class.
|
||||
* @brief AccessList class which represents individual content ACLs.
|
||||
*
|
||||
* A class to hold an AccessList object with allowed and denied contacts and
|
||||
* groups.
|
||||
*
|
||||
* After evaluating @ref ::Zotlabs::Access::PermissionLimits "PermissionLimits"
|
||||
* and @ref ::Zotlabs::Lib::Permcat "Permcat"s individual content ACLs are evaluated.
|
||||
* These answer the question "Can Joe view *this* album/photo?".
|
||||
*/
|
||||
class AccessList {
|
||||
/**
|
||||
|
@ -103,7 +107,7 @@ class AccessList {
|
|||
* @brief Return an array consisting of the current access list components
|
||||
* where the elements are directly storable.
|
||||
*
|
||||
* @return Associative array with:
|
||||
* @return array An associative array with:
|
||||
* * \e string \b allow_cid => string of allowed cids
|
||||
* * \e string \b allow_gid => string of allowed gids
|
||||
* * \e string \b deny_cid => string of denied cids
|
||||
|
|
|
@ -2,35 +2,90 @@
|
|||
|
||||
namespace Zotlabs\Access;
|
||||
|
||||
use \Zotlabs\Lib as ZLib;
|
||||
use Zotlabs\Lib\PConfig;
|
||||
|
||||
/**
|
||||
* @brief Permission limits.
|
||||
*
|
||||
* Permission limits are a very high level permission setting. They are hard
|
||||
* limits by design.
|
||||
* "Who can view my photos (at all)?"
|
||||
* "Who can post photos in my albums (at all)?"
|
||||
*
|
||||
* For viewing permissions we generally set these to 'anybody' and for write
|
||||
* permissions we generally set them to 'those I allow', though many people
|
||||
* restrict the viewing permissions further for things like 'Can view my connections'.
|
||||
*
|
||||
* People get confused enough by permissions that we wanted a place to set their
|
||||
* privacy expectations once and be done with it.
|
||||
*
|
||||
* Connection related permissions like "Can Joe view my photos?" are handled by
|
||||
* @ref ::Zotlabs::Lib::Permcat "Permcat" and inherit from the channel's Permission
|
||||
* limits.
|
||||
*
|
||||
* @see Permissions
|
||||
*/
|
||||
class PermissionLimits {
|
||||
|
||||
/**
|
||||
* @brief Get standard permission limits.
|
||||
*
|
||||
* Viewing permissions and post_comments permission are set to 'anybody',
|
||||
* other permissions are set to 'those I allow'.
|
||||
*
|
||||
* The list of permissions comes from Permissions::Perms().
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function Std_Limits() {
|
||||
$limits = [];
|
||||
$perms = Permissions::Perms();
|
||||
$limits = array();
|
||||
|
||||
foreach($perms as $k => $v) {
|
||||
if(strstr($k,'view') || $k === 'post_comments')
|
||||
if(strstr($k, 'view') || $k === 'post_comments')
|
||||
$limits[$k] = PERMS_PUBLIC;
|
||||
else
|
||||
$limits[$k] = PERMS_SPECIFIC;
|
||||
}
|
||||
|
||||
return $limits;
|
||||
}
|
||||
|
||||
static public function Set($channel_id,$perm,$perm_limit) {
|
||||
ZLib\PConfig::Set($channel_id,'perm_limits',$perm,$perm_limit);
|
||||
/**
|
||||
* @brief Sets a permission limit for a channel.
|
||||
*
|
||||
* @param int $channel_id
|
||||
* @param string $perm
|
||||
* @param int $perm_limit one of PERMS_* constants
|
||||
*/
|
||||
static public function Set($channel_id, $perm, $perm_limit) {
|
||||
PConfig::Set($channel_id, 'perm_limits', $perm, $perm_limit);
|
||||
}
|
||||
|
||||
static public function Get($channel_id,$perm = '') {
|
||||
/**
|
||||
* @brief Get a channel's permission limits.
|
||||
*
|
||||
* Return a channel's permission limits from PConfig. If $perm is set just
|
||||
* return this permission limit, if not set, return an array with all
|
||||
* permission limits.
|
||||
*
|
||||
* @param int $channel_id
|
||||
* @param string $perm (optional)
|
||||
* @return
|
||||
* * \b boolean false if no perm_limits set for this channel
|
||||
* * \b int if $perm is set, return one of PERMS_* constants for this permission
|
||||
* * \b array with all permission limits, if $perm is not set
|
||||
*/
|
||||
static public function Get($channel_id, $perm = '') {
|
||||
if($perm) {
|
||||
return Zlib\PConfig::Get($channel_id,'perm_limits',$perm);
|
||||
return PConfig::Get($channel_id, 'perm_limits', $perm);
|
||||
}
|
||||
else {
|
||||
Zlib\PConfig::Load($channel_id);
|
||||
if(array_key_exists($channel_id,\App::$config) && array_key_exists('perm_limits',\App::$config[$channel_id]))
|
||||
return \App::$config[$channel_id]['perm_limits'];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PConfig::Load($channel_id);
|
||||
if(array_key_exists($channel_id, \App::$config)
|
||||
&& array_key_exists('perm_limits', \App::$config[$channel_id]))
|
||||
return \App::$config[$channel_id]['perm_limits'];
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -426,8 +426,10 @@ class Notifier {
|
|||
logger('notifier: encoded item: ' . print_r($x,true), LOGGER_DATA, LOG_DEBUG);
|
||||
|
||||
stringify_array_elms($recipients);
|
||||
if(! $recipients)
|
||||
if(! $recipients) {
|
||||
logger('no recipients');
|
||||
return;
|
||||
}
|
||||
|
||||
// logger('notifier: recipients: ' . print_r($recipients,true), LOGGER_NORMAL, LOG_DEBUG);
|
||||
|
||||
|
|
|
@ -221,6 +221,7 @@ class Apps {
|
|||
static public function translate_system_apps(&$arr) {
|
||||
$apps = array(
|
||||
'Apps' => t('Apps'),
|
||||
'Articles' => t('Articles'),
|
||||
'Cards' => t('Cards'),
|
||||
'Admin' => t('Site Admin'),
|
||||
'Report Bug' => t('Report Bug'),
|
||||
|
@ -352,7 +353,7 @@ class Apps {
|
|||
break;
|
||||
default:
|
||||
if($config)
|
||||
$unset = ((get_config('system', $require[0]) == $require[1]) ? false : true);
|
||||
$unset = ((get_config('system', $require[0]) === $require[1]) ? false : true);
|
||||
else
|
||||
$unset = ((local_channel() && feature_enabled(local_channel(),$require)) ? false : true);
|
||||
if($unset)
|
||||
|
|
|
@ -804,6 +804,8 @@ class Enotify {
|
|||
'when' => relative_date($item['created']),
|
||||
'class' => (intval($item['item_unseen']) ? 'notify-unseen' : 'notify-seen'),
|
||||
'b64mid' => ((in_array($item['verb'], [ACTIVITY_LIKE, ACTIVITY_DISLIKE])) ? 'b64.' . base64url_encode($item['thr_parent']) : 'b64.' . base64url_encode($item['mid'])),
|
||||
'notify_id' => 'undefined',
|
||||
'thread_top' => (($item['item_thread_top']) ? true : false),
|
||||
'message' => strip_tags(bbcode($itemem_text))
|
||||
);
|
||||
|
||||
|
|
122
Zotlabs/Lib/Img_filesize.php
Normal file
122
Zotlabs/Lib/Img_filesize.php
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
class Img_filesize {
|
||||
|
||||
private $url;
|
||||
|
||||
function __construct($url) {
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
function getSize() {
|
||||
$size = null;
|
||||
|
||||
if(stripos($this->url,z_root() . '/photo') !== false) {
|
||||
$size = self::getLocalFileSize($this->url);
|
||||
}
|
||||
if(! $size) {
|
||||
$size = getRemoteFileSize($this->url);
|
||||
}
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
|
||||
static function getLocalFileSize($url) {
|
||||
|
||||
$fname = basename($url);
|
||||
$resolution = 0;
|
||||
|
||||
if(strpos($fname,'.') !== false)
|
||||
$fname = substr($fname,0,strpos($fname,'.'));
|
||||
|
||||
if(substr($fname,-2,1) == '-') {
|
||||
$resolution = intval(substr($fname,-1,1));
|
||||
$fname = substr($fname,0,-2);
|
||||
}
|
||||
|
||||
$r = q("SELECT filesize FROM photo WHERE resource_id = '%s' AND imgscale = %d LIMIT 1",
|
||||
dbesc($fname),
|
||||
intval($resolution)
|
||||
);
|
||||
if($r) {
|
||||
return $r[0]['filesize'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to determine the size of a remote file by making an HTTP request for
|
||||
* a byte range, or look for the content-length header in the response.
|
||||
* The function aborts the transfer as soon as the size is found, or if no
|
||||
* length headers are returned, it aborts the transfer.
|
||||
*
|
||||
* @return int|null null if size could not be determined, or length of content
|
||||
*/
|
||||
function getRemoteFileSize($url)
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
|
||||
$headers = array(
|
||||
'Range: bytes=0-1',
|
||||
'Connection: close',
|
||||
);
|
||||
|
||||
$in_headers = true;
|
||||
$size = null;
|
||||
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2450.0 Iron/46.0.2450.0');
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, 0); // set to 1 to debug
|
||||
curl_setopt($ch, CURLOPT_STDERR, fopen('php://output', 'r'));
|
||||
|
||||
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $line) use (&$in_headers, &$size) {
|
||||
$length = strlen($line);
|
||||
|
||||
if (trim($line) == '') {
|
||||
$in_headers = false;
|
||||
}
|
||||
|
||||
list($header, $content) = explode(':', $line, 2);
|
||||
$header = strtolower(trim($header));
|
||||
|
||||
if ($header == 'content-range') {
|
||||
// found a content-range header
|
||||
list($rng, $s) = explode('/', $content, 2);
|
||||
$size = (int)$s;
|
||||
return 0; // aborts transfer
|
||||
} else if ($header == 'content-length' && 206 != curl_getinfo($curl, CURLINFO_HTTP_CODE)) {
|
||||
// found content-length header and this is not a 206 Partial Content response (range response)
|
||||
$size = (int)$content;
|
||||
return 0;
|
||||
} else {
|
||||
// continue
|
||||
return $length;
|
||||
}
|
||||
});
|
||||
|
||||
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) use ($in_headers) {
|
||||
if (!$in_headers) {
|
||||
// shouldn't be here unless we couldn't determine file size
|
||||
// abort transfer
|
||||
return 0;
|
||||
}
|
||||
|
||||
// write function is also called when reading headers
|
||||
return strlen($data);
|
||||
});
|
||||
|
||||
curl_exec($ch);
|
||||
curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $size;
|
||||
}
|
|
@ -3,51 +3,66 @@
|
|||
namespace Zotlabs\Lib;
|
||||
|
||||
/**
|
||||
* MarkdownSoap
|
||||
* @brief MarkdownSoap class.
|
||||
*
|
||||
* Purify Markdown for storage
|
||||
* @code{.php}
|
||||
* $x = new MarkdownSoap($string_to_be_cleansed);
|
||||
* $text = $x->clean();
|
||||
*
|
||||
* @endcode
|
||||
* What this does:
|
||||
* 1. extracts code blocks and privately escapes them from processing
|
||||
* 2. Run html purifier on the content
|
||||
* 3. put back the code blocks
|
||||
* 4. run htmlspecialchars on the entire content for safe storage
|
||||
*
|
||||
* At render time:
|
||||
* At render time:
|
||||
* @code{.php}
|
||||
* $markdown = \Zotlabs\Lib\MarkdownSoap::unescape($text);
|
||||
* $html = \Michelf\MarkdownExtra::DefaultTransform($markdown);
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
|
||||
|
||||
class MarkdownSoap {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $str;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $token;
|
||||
|
||||
private $str;
|
||||
|
||||
function __construct($s) {
|
||||
$this->str = $s;
|
||||
$this->str = $s;
|
||||
$this->token = random_string(20);
|
||||
}
|
||||
|
||||
|
||||
function clean() {
|
||||
|
||||
$x = $this->extract_code($this->str);
|
||||
|
||||
$x = $this->purify($x);
|
||||
|
||||
$x = $this->putback_code($x);
|
||||
$x = $this->putback_code($x);
|
||||
|
||||
$x = $this->escape($x);
|
||||
|
||||
|
||||
return $x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Extracts code blocks and privately escapes them from processing.
|
||||
*
|
||||
* @see encode_code()
|
||||
* @see putback_code()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
function extract_code($s) {
|
||||
|
||||
|
||||
$text = preg_replace_callback('{
|
||||
(?:\n\n|\A\n?)
|
||||
( # $1 = the code block -- one or more lines, starting with a space/tab
|
||||
|
@ -62,7 +77,7 @@ class MarkdownSoap {
|
|||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
function encode_code($matches) {
|
||||
return $this->token . ';' . base64_encode($matches[0]) . ';' ;
|
||||
}
|
||||
|
@ -71,8 +86,17 @@ class MarkdownSoap {
|
|||
return base64_decode($matches[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put back the code blocks.
|
||||
*
|
||||
* @see extract_code()
|
||||
* @see decode_code()
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
function putback_code($s) {
|
||||
$text = preg_replace_callback('{' . $this->token . '\;(.*?)\;}xm',[ $this, 'decode_code' ], $s);
|
||||
$text = preg_replace_callback('{' . $this->token . '\;(.*?)\;}xm', [ $this, 'decode_code' ], $s);
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
@ -84,20 +108,25 @@ class MarkdownSoap {
|
|||
}
|
||||
|
||||
function protect_autolinks($s) {
|
||||
$s = preg_replace('/\<(https?\:\/\/)(.*?)\>/','[$1$2]($1$2)',$s);
|
||||
$s = preg_replace('/\<(https?\:\/\/)(.*?)\>/', '[$1$2]($1$2)', $s);
|
||||
return $s;
|
||||
}
|
||||
|
||||
function unprotect_autolinks($s) {
|
||||
return $s;
|
||||
|
||||
}
|
||||
|
||||
function escape($s) {
|
||||
return htmlspecialchars($s,ENT_QUOTES,'UTF-8',false);
|
||||
return htmlspecialchars($s, ENT_QUOTES, 'UTF-8', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts special HTML entities back to characters.
|
||||
*
|
||||
* @param string $s
|
||||
* @return string
|
||||
*/
|
||||
static public function unescape($s) {
|
||||
return htmlspecialchars_decode($s,ENT_QUOTES);
|
||||
return htmlspecialchars_decode($s, ENT_QUOTES);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,9 @@ class NativeWikiPage {
|
|||
return array('content' => null, 'message' => 'Error reading wiki', 'success' => false);
|
||||
}
|
||||
|
||||
// backslashes won't work well in the javascript functions
|
||||
$name = str_replace('\\','',$name);
|
||||
|
||||
// create an empty activity
|
||||
|
||||
$arr = [];
|
||||
|
@ -351,6 +354,7 @@ class NativeWikiPage {
|
|||
// fetch the most recently saved revision.
|
||||
|
||||
$item = self::load_page($arr);
|
||||
|
||||
if(! $item) {
|
||||
return array('message' => t('Page not found'), 'success' => false);
|
||||
}
|
||||
|
|
|
@ -2,12 +2,36 @@
|
|||
|
||||
namespace Zotlabs\Lib;
|
||||
|
||||
use \Zotlabs\Access as Zaccess;
|
||||
use Zotlabs\Access\PermissionRoles;
|
||||
use Zotlabs\Access\Permissions;
|
||||
|
||||
/**
|
||||
* @brief Permission Categories. Permission rules for various classes of connections.
|
||||
*
|
||||
* Connection permissions answer the question "Can Joe view my photos?"
|
||||
*
|
||||
* Some permissions may be inherited from the channel's "privacy settings"
|
||||
* (@ref ::Zotlabs::Access::PermissionLimits "PermissionLimits") "Who can view my
|
||||
* photos (at all)?" which have higher priority than individual connection settings.
|
||||
* We evaluate permission limits first, and then fall through to connection
|
||||
* permissions if the permission limits didn't already make a definitive decision.
|
||||
*
|
||||
* After PermissionLimits and connection permissions are evaluated, individual
|
||||
* content ACLs are evaluated (@ref ::Zotlabs::Access::AccessList "AccessList").
|
||||
* These answer the question "Can Joe view *this* album/photo?".
|
||||
*/
|
||||
class Permcat {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $permcats = [];
|
||||
|
||||
/**
|
||||
* @brief Permcat constructor.
|
||||
*
|
||||
* @param int $channel_id
|
||||
*/
|
||||
public function __construct($channel_id) {
|
||||
|
||||
$perms = [];
|
||||
|
@ -16,16 +40,16 @@ class Permcat {
|
|||
|
||||
$role = get_pconfig($channel_id,'system','permissions_role');
|
||||
if($role) {
|
||||
$x = Zaccess\PermissionRoles::role_perms($role);
|
||||
$x = PermissionRoles::role_perms($role);
|
||||
if($x['perms_connect']) {
|
||||
$perms = Zaccess\Permissions::FilledPerms($x['perms_connect']);
|
||||
$perms = Permissions::FilledPerms($x['perms_connect']);
|
||||
}
|
||||
}
|
||||
|
||||
// if no role perms it may be a custom role, see if there any autoperms
|
||||
|
||||
if(! $perms) {
|
||||
$perms = Zaccess\Permissions::FilledAutoPerms($channel_id);
|
||||
$perms = Permissions::FilledAutoPerms($channel_id);
|
||||
}
|
||||
|
||||
// if no autoperms it may be a custom role with manual perms
|
||||
|
@ -50,13 +74,13 @@ class Permcat {
|
|||
// nothing was found - create a filled permission array where all permissions are 0
|
||||
|
||||
if(! $perms) {
|
||||
$perms = Zaccess\Permissions::FilledPerms([]);
|
||||
$perms = Permissions::FilledPerms([]);
|
||||
}
|
||||
|
||||
$this->permcats[] = [
|
||||
'name' => 'default',
|
||||
'localname' => t('default','permcat'),
|
||||
'perms' => Zaccess\Permissions::Operms($perms),
|
||||
'perms' => Permissions::Operms($perms),
|
||||
'system' => 1
|
||||
];
|
||||
|
||||
|
@ -67,26 +91,39 @@ class Permcat {
|
|||
$this->permcats[] = [
|
||||
'name' => $p[$x][0],
|
||||
'localname' => $p[$x][1],
|
||||
'perms' => Zaccess\Permissions::Operms(Zaccess\Permissions::FilledPerms($p[$x][2])),
|
||||
'perms' => Permissions::Operms(Permissions::FilledPerms($p[$x][2])),
|
||||
'system' => intval($p[$x][3])
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return array with permcats.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listing() {
|
||||
return $this->permcats;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param string $name
|
||||
* @return array
|
||||
* * \e array with permcats
|
||||
* * \e bool \b error if $name not found in permcats true
|
||||
*/
|
||||
public function fetch($name) {
|
||||
if($name && $this->permcats) {
|
||||
foreach($this->permcats as $permcat) {
|
||||
if(strcasecmp($permcat['name'],$name) === 0) {
|
||||
if(strcasecmp($permcat['name'], $name) === 0) {
|
||||
return $permcat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ['error' => true];
|
||||
}
|
||||
|
||||
|
@ -118,29 +155,32 @@ class Permcat {
|
|||
$permcats[] = [ $xv['k'], $xv['k'], $value, 0 ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
call_hooks('permcats',$permcats);
|
||||
/**
|
||||
* @hooks permcats
|
||||
* * \e array
|
||||
*/
|
||||
call_hooks('permcats', $permcats);
|
||||
|
||||
return $permcats;
|
||||
|
||||
}
|
||||
|
||||
static public function find_permcat($arr,$name) {
|
||||
static public function find_permcat($arr, $name) {
|
||||
if((! $arr) || (! $name))
|
||||
return false;
|
||||
|
||||
foreach($arr as $p)
|
||||
if($p['name'] == $name)
|
||||
return $p['value'];
|
||||
}
|
||||
|
||||
static public function update($channel_id, $name,$permarr) {
|
||||
PConfig::Set($channel_id,'permcat',$name,$permarr);
|
||||
static public function update($channel_id, $name, $permarr) {
|
||||
PConfig::Set($channel_id, 'permcat', $name, $permarr);
|
||||
}
|
||||
|
||||
static public function delete($channel_id,$name) {
|
||||
PConfig::Delete($channel_id,'permcat',$name);
|
||||
static public function delete($channel_id, $name) {
|
||||
PConfig::Delete($channel_id, 'permcat', $name);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -38,7 +38,7 @@ class ThreadItem {
|
|||
$this->toplevel = ($this->get_id() == $this->get_data_value('parent'));
|
||||
|
||||
// Prepare the children
|
||||
if(count($data['children'])) {
|
||||
if($data['children']) {
|
||||
foreach($data['children'] as $item) {
|
||||
|
||||
/*
|
||||
|
@ -105,7 +105,17 @@ class ThreadItem {
|
|||
|
||||
$mode = $conv->get_mode();
|
||||
|
||||
$edlink = (($item['item_type'] == ITEM_TYPE_CARD) ? 'card_edit' : 'editpost');
|
||||
switch($item['item_type']) {
|
||||
case ITEM_TYPE_CARD:
|
||||
$edlink = 'card_edit';
|
||||
break;
|
||||
case ITEM_TYPE_ARTICLE:
|
||||
$edlink = 'article_edit';
|
||||
break;
|
||||
default:
|
||||
$edlink = 'editpost';
|
||||
break;
|
||||
}
|
||||
|
||||
if(local_channel() && $observer['xchan_hash'] === $item['author_xchan'])
|
||||
$edpost = array(z_root() . '/' . $edlink . '/' . $item['id'], t('Edit'));
|
||||
|
@ -186,7 +196,7 @@ class ThreadItem {
|
|||
|
||||
$like_count = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid']] : '');
|
||||
$like_list = ((x($conv_responses['like'],$item['mid'])) ? $conv_responses['like'][$item['mid'] . '-l'] : '');
|
||||
if (count($like_list) > MAX_LIKERS) {
|
||||
if (($like_list) && (count($like_list) > MAX_LIKERS)) {
|
||||
$like_list_part = array_slice($like_list, 0, MAX_LIKERS);
|
||||
array_push($like_list_part, '<a class="dropdown-item" href="#" data-toggle="modal" data-target="#likeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
|
||||
} else {
|
||||
|
@ -198,7 +208,7 @@ class ThreadItem {
|
|||
$dislike_count = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid']] : '');
|
||||
$dislike_list = ((x($conv_responses['dislike'],$item['mid'])) ? $conv_responses['dislike'][$item['mid'] . '-l'] : '');
|
||||
$dislike_button_label = tt('Dislike','Dislikes',$dislike_count,'noun');
|
||||
if (count($dislike_list) > MAX_LIKERS) {
|
||||
if (($dislike_list) && (count($dislike_list) > MAX_LIKERS)) {
|
||||
$dislike_list_part = array_slice($dislike_list, 0, MAX_LIKERS);
|
||||
array_push($dislike_list_part, '<a class="dropdown-item" href="#" data-toggle="modal" data-target="#dislikeModal-' . $this->get_id() . '"><b>' . t('View all') . '</b></a>');
|
||||
} else {
|
||||
|
@ -303,7 +313,7 @@ class ThreadItem {
|
|||
$comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children );
|
||||
$list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : '');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -360,6 +370,7 @@ class ThreadItem {
|
|||
'unverified' => $unverified,
|
||||
'forged' => $forged,
|
||||
'location' => $location,
|
||||
'divider' => get_pconfig($conv->get_profile_owner(),'system','item_divider'),
|
||||
'attend_label' => t('Attend'),
|
||||
'attend_title' => t('Attendance Options'),
|
||||
'vote_label' => t('Vote'),
|
||||
|
|
|
@ -54,6 +54,14 @@ class ThreadStream {
|
|||
$this->profile_owner = local_channel();
|
||||
$this->writable = true;
|
||||
break;
|
||||
case 'pubstream':
|
||||
$this->profile_owner = local_channel();
|
||||
$this->writable = ((local_channel()) ? true : false);
|
||||
break;
|
||||
case 'hq':
|
||||
$this->profile_owner = local_channel();
|
||||
$this->writable = true;
|
||||
break;
|
||||
case 'channel':
|
||||
$this->profile_owner = \App::$profile['profile_uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
|
@ -63,6 +71,11 @@ class ThreadStream {
|
|||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
$this->reload = $_SESSION['return_url'];
|
||||
break;
|
||||
case 'articles':
|
||||
$this->profile_owner = \App::$profile['profile_uid'];
|
||||
$this->writable = perm_is_allowed($this->profile_owner,$ob_hash,'post_comments');
|
||||
$this->reload = $_SESSION['return_url'];
|
||||
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
|
||||
|
@ -179,6 +192,10 @@ class ThreadStream {
|
|||
$item->set_commentable(can_comment_on_post($ob_hash,$item->data));
|
||||
}
|
||||
}
|
||||
if($this->mode === 'pubstream' && (! local_channel())) {
|
||||
$item->set_commentable(false);
|
||||
}
|
||||
|
||||
require_once('include/channel.php');
|
||||
|
||||
$item->set_conversation($this);
|
||||
|
|
|
@ -1,36 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/*
|
||||
* ACL selector json backend
|
||||
require_once 'include/acl_selectors.php';
|
||||
require_once 'include/group.php';
|
||||
|
||||
/**
|
||||
* @brief ACL selector json backend.
|
||||
*
|
||||
* This module provides JSON lists of connections and local/remote channels
|
||||
* (xchans) to populate various tools such as the ACL (AccessControlList) popup
|
||||
* and various auto-complete functions (such as email recipients, search, and
|
||||
* and various auto-complete functions (such as email recipients, search, and
|
||||
* mention targets.
|
||||
*
|
||||
* There are two primary output structural formats. One for the ACL widget and
|
||||
* the other for auto-completion.
|
||||
* Many of the behaviour variations are triggered on the use of single character keys
|
||||
* however this functionality has grown in an ad-hoc manner and has gotten quite messy over time.
|
||||
*
|
||||
* Many of the behaviour variations are triggered on the use of single character
|
||||
* keys however this functionality has grown in an ad-hoc manner and has gotten
|
||||
* quite messy over time.
|
||||
*/
|
||||
|
||||
require_once("include/acl_selectors.php");
|
||||
require_once("include/group.php");
|
||||
|
||||
|
||||
class Acl extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
|
||||
logger('mod_acl: ' . print_r($_REQUEST,true));
|
||||
|
||||
|
||||
$start = (x($_REQUEST,'start') ? $_REQUEST['start'] : 0);
|
||||
$count = (x($_REQUEST,'count') ? $_REQUEST['count'] : 500);
|
||||
$search = (x($_REQUEST,'search') ? $_REQUEST['search'] : '');
|
||||
$type = (x($_REQUEST,'type') ? $_REQUEST['type'] : '');
|
||||
$noforums = (x($_REQUEST,'n') ? $_REQUEST['n'] : false);
|
||||
$noforums = (x($_REQUEST,'n') ? $_REQUEST['n'] : false);
|
||||
|
||||
|
||||
// $type =
|
||||
// $type =
|
||||
// '' => standard ACL request
|
||||
// 'g' => Groups only ACL request
|
||||
// 'f' => forums only ACL request
|
||||
|
@ -382,15 +385,13 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||
'count' => $count,
|
||||
'items' => $items,
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
echo json_encode($o);
|
||||
|
||||
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function navbar_complete(&$a) {
|
||||
|
||||
// logger('navbar_complete');
|
||||
|
@ -447,5 +448,5 @@ class Acl extends \Zotlabs\Web\Controller {
|
|||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -29,12 +29,14 @@ class Site {
|
|||
$maximagesize = ((x($_POST,'maximagesize')) ? intval(trim($_POST['maximagesize'])) : 0);
|
||||
|
||||
$register_policy = ((x($_POST,'register_policy')) ? intval(trim($_POST['register_policy'])) : 0);
|
||||
|
||||
$minimum_age = ((x($_POST,'minimum_age')) ? intval(trim($_POST['minimum_age'])) : 13);
|
||||
$access_policy = ((x($_POST,'access_policy')) ? intval(trim($_POST['access_policy'])) : 0);
|
||||
$invite_only = ((x($_POST,'invite_only')) ? True : False);
|
||||
$abandon_days = ((x($_POST,'abandon_days')) ? intval(trim($_POST['abandon_days'])) : 0);
|
||||
|
||||
$register_text = ((x($_POST,'register_text')) ? notags(trim($_POST['register_text'])) : '');
|
||||
$site_sellpage = ((x($_POST,'site_sellpage')) ? notags(trim($_POST['site_sellpage'])) : '');
|
||||
$site_location = ((x($_POST,'site_location')) ? notags(trim($_POST['site_location'])) : '');
|
||||
$frontpage = ((x($_POST,'frontpage')) ? notags(trim($_POST['frontpage'])) : '');
|
||||
$mirror_frontpage = ((x($_POST,'mirror_frontpage')) ? intval(trim($_POST['mirror_frontpage'])) : 0);
|
||||
$directory_server = ((x($_POST,'directory_server')) ? trim($_POST['directory_server']) : '');
|
||||
|
@ -76,6 +78,8 @@ class Site {
|
|||
set_config('system', 'poll_interval', $poll_interval);
|
||||
set_config('system', 'maxloadavg', $maxloadavg);
|
||||
set_config('system', 'frontpage', $frontpage);
|
||||
set_config('system', 'sellpage', $site_sellpage);
|
||||
set_config('system', 'site_location', $site_location);
|
||||
set_config('system', 'mirror_frontpage', $mirror_frontpage);
|
||||
set_config('system', 'sitename', $sitename);
|
||||
set_config('system', 'login_on_homepage', $login_on_homepage);
|
||||
|
@ -123,6 +127,7 @@ class Site {
|
|||
set_config('system','maximagesize', $maximagesize);
|
||||
|
||||
set_config('system','register_policy', $register_policy);
|
||||
set_config('system','minimum_age', $minimum_age);
|
||||
set_config('system','invitation_only', $invite_only);
|
||||
set_config('system','access_policy', $access_policy);
|
||||
set_config('system','account_abandon_days', $abandon_days);
|
||||
|
@ -251,6 +256,7 @@ class Site {
|
|||
);
|
||||
|
||||
$discover_tab = get_config('system','disable_discover_tab');
|
||||
|
||||
// $disable public streams by default
|
||||
if($discover_tab === false)
|
||||
$discover_tab = 1;
|
||||
|
@ -298,6 +304,7 @@ class Site {
|
|||
'$maximagesize' => array('maximagesize', t("Maximum image size"), intval(get_config('system','maximagesize')), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")),
|
||||
'$register_policy' => array('register_policy', t("Does this site allow new member registration?"), get_config('system','register_policy'), "", $register_choices),
|
||||
'$invite_only' => array('invite_only', t("Invitation only"), get_config('system','invitation_only'), t("Only allow new member registrations with an invitation code. Above register policy must be set to Yes.")),
|
||||
'$minimum_age' => array('minimum_age', t("Minimum age"), (x(get_config('system','minimum_age'))?get_config('system','minimum_age'):13), t("Minimum age (in years) for who may register on this site.")),
|
||||
'$access_policy' => array('access_policy', t("Which best describes the types of account offered by this hub?"), get_config('system','access_policy'), "This is displayed on the public server site list.", $access_choices),
|
||||
'$register_text' => array('register_text', t("Register text"), htmlspecialchars(get_config('system','register_text'), ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")),
|
||||
'$frontpage' => array('frontpage', t("Site homepage to show visitors (default: login box)"), get_config('system','frontpage'), t("example: 'public' to show public stream, 'page/sys/home' to show a system webpage called 'home' or 'include:home.html' to include a file.")),
|
||||
|
@ -327,6 +334,12 @@ class Site {
|
|||
'$thumbnail_security' => array('thumbnail_security', t("Allow SVG thumbnails in file browser"), get_config('system','thumbnail_security',0), t("WARNING: SVG images may contain malicious code.")),
|
||||
'$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
|
||||
'$default_expire_days' => array('default_expire_days', t('Expiration period in days for imported (grid/network) content'), intval(get_config('system','default_expire_days')), t('0 for no expiration of imported content')),
|
||||
|
||||
'$sellpage' => array('site_sellpage', t('Public servers: Optional landing (marketing) webpage for new registrants'), get_config('system','sellpage',''), sprintf( t('Create this page first. Default is %s/register'),z_root())),
|
||||
|
||||
'$location' => array('site_location', t('Optional: site location'), get_config('system','site_location',''), t('Region or country')),
|
||||
|
||||
|
||||
'$form_security_token' => get_form_security_token("admin_site"),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -39,10 +39,12 @@ class Api extends \Zotlabs\Web\Controller {
|
|||
|
||||
// get consumer/client from request token
|
||||
try {
|
||||
$request = OAuth1Request::from_request();
|
||||
$request = \OAuth1Request::from_request();
|
||||
}
|
||||
catch(\Exception $e) {
|
||||
echo "<pre>"; var_dump($e); killme();
|
||||
logger('OAuth exception: ' . print_r($e,true));
|
||||
// echo "<pre>"; var_dump($e);
|
||||
killme();
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,7 +54,7 @@ class Api extends \Zotlabs\Web\Controller {
|
|||
if (is_null($app))
|
||||
return "Invalid request. Unknown token.";
|
||||
|
||||
$consumer = new OAuth1Consumer($app['client_id'], $app['pw'], $app['redirect_uri']);
|
||||
$consumer = new \OAuth1Consumer($app['client_id'], $app['pw'], $app['redirect_uri']);
|
||||
|
||||
$verifier = md5($app['secret'] . local_channel());
|
||||
set_config('oauth', $verifier, local_channel());
|
||||
|
@ -63,7 +65,7 @@ class Api extends \Zotlabs\Web\Controller {
|
|||
$glue = '?';
|
||||
if(strstr($consumer->callback_url,$glue))
|
||||
$glue = '?';
|
||||
goaway($consumer->callback_url . $glue . "oauth_token=" . OAuth1Util::urlencode_rfc3986($params['oauth_token']) . "&oauth_verifier=" . OAuth1Util::urlencode_rfc3986($verifier));
|
||||
goaway($consumer->callback_url . $glue . "oauth_token=" . \OAuth1Util::urlencode_rfc3986($params['oauth_token']) . "&oauth_verifier=" . \OAuth1Util::urlencode_rfc3986($verifier));
|
||||
killme();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@ class Apps extends \Zotlabs\Web\Controller {
|
|||
if(local_channel()) {
|
||||
Zlib\Apps::import_system_apps();
|
||||
$syslist = array();
|
||||
$list = Zlib\Apps::app_list(local_channel(), (($mode == 'edit') ? true : false), $_GET['cat']);
|
||||
$cat = ((array_key_exists('cat',$_GET) && $_GET['cat']) ? [ escape_tags($_GET['cat']) ] : '');
|
||||
$list = Zlib\Apps::app_list(local_channel(), (($mode == 'edit') ? true : false), $cat);
|
||||
if($list) {
|
||||
foreach($list as $x) {
|
||||
$syslist[] = Zlib\Apps::app_encode($x);
|
||||
|
@ -43,7 +44,7 @@ class Apps extends \Zotlabs\Web\Controller {
|
|||
|
||||
return replace_macros(get_markup_template('myapps.tpl'), array(
|
||||
'$sitename' => get_config('system','sitename'),
|
||||
'$cat' => ((array_key_exists('cat',$_GET) && $_GET['cat']) ? escape_tags($_GET['cat']) : ''),
|
||||
'$cat' => $cat,
|
||||
'$title' => t('Apps'),
|
||||
'$apps' => $apps,
|
||||
'$authed' => ((local_channel()) ? true : false),
|
||||
|
|
138
Zotlabs/Module/Article_edit.php
Normal file
138
Zotlabs/Module/Article_edit.php
Normal file
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
require_once('include/conversation.php');
|
||||
|
||||
class Article_edit extends \Zotlabs\Web\Controller {
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
// Figure out which post we're editing
|
||||
$post_id = ((argc() > 1) ? intval(argv(1)) : 0);
|
||||
|
||||
if(! $post_id) {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$itm = q("SELECT * FROM item WHERE id = %d and item_type = %d LIMIT 1",
|
||||
intval($post_id),
|
||||
intval(ITEM_TYPE_ARTICLE)
|
||||
);
|
||||
if($itm) {
|
||||
$item_id = q("select * from iconfig where cat = 'system' and k = 'ARTICLE' and iid = %d limit 1",
|
||||
intval($itm[0]['id'])
|
||||
);
|
||||
if($item_id)
|
||||
$card_title = $item_id[0]['v'];
|
||||
}
|
||||
else {
|
||||
notice( t('Item not found') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$owner = $itm[0]['uid'];
|
||||
$uid = local_channel();
|
||||
|
||||
$observer = \App::get_observer();
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
if(! $channel) {
|
||||
notice( t('Channel not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner,$ob_hash,'write_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = (($uid && $uid == $owner) ? true : false);
|
||||
|
||||
$o = '';
|
||||
|
||||
|
||||
|
||||
$category = '';
|
||||
$catsenabled = ((feature_enabled($owner,'categories')) ? 'categories' : '');
|
||||
|
||||
if ($catsenabled){
|
||||
$itm = fetch_post_tags($itm);
|
||||
|
||||
$cats = get_terms_oftype($itm[0]['term'], TERM_CATEGORY);
|
||||
|
||||
foreach ($cats as $cat) {
|
||||
if (strlen($category))
|
||||
$category .= ', ';
|
||||
$category .= $cat['term'];
|
||||
}
|
||||
}
|
||||
|
||||
if($itm[0]['attach']) {
|
||||
$j = json_decode($itm[0]['attach'],true);
|
||||
if($j) {
|
||||
foreach($j as $jj) {
|
||||
$itm[0]['body'] .= "\n" . '[attachment]' . basename($jj['href']) . ',' . $jj['revision'] . '[/attachment]' . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$mimetype = $itm[0]['mimetype'];
|
||||
|
||||
$content = $itm[0]['body'];
|
||||
|
||||
|
||||
|
||||
$rp = 'articles/' . $channel['channel_address'];
|
||||
|
||||
$x = array(
|
||||
'nickname' => $channel['channel_address'],
|
||||
'bbco_autocomplete'=> 'bbcode',
|
||||
'return_path' => $rp,
|
||||
'webpage' => ITEM_TYPE_ARTICLE,
|
||||
'button' => t('Edit'),
|
||||
'writefiles' => perm_is_allowed($owner, get_observer_hash(), 'write_pages'),
|
||||
'weblink' => t('Insert web link'),
|
||||
'hide_voting' => false,
|
||||
'hide_future' => false,
|
||||
'hide_location' => false,
|
||||
'hide_expire' => false,
|
||||
'showacl' => true,
|
||||
'acl' => populate_acl($itm[0],false,\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')),
|
||||
'permissions' => $itm[0],
|
||||
'lockstate' => (($itm[0]['allow_cid'] || $itm[0]['allow_gid'] || $itm[0]['deny_cid'] || $itm[0]['deny_gid']) ? 'lock' : 'unlock'),
|
||||
'ptyp' => $itm[0]['type'],
|
||||
'mimeselect' => false,
|
||||
'mimetype' => $itm[0]['mimetype'],
|
||||
'body' => undo_post_tagging($content),
|
||||
'post_id' => $post_id,
|
||||
'visitor' => true,
|
||||
'title' => htmlspecialchars($itm[0]['title'],ENT_COMPAT,'UTF-8'),
|
||||
'placeholdertitle' => t('Title (optional)'),
|
||||
'pagetitle' => $card_title,
|
||||
'profile_uid' => (intval($channel['channel_id'])),
|
||||
'catsenabled' => $catsenabled,
|
||||
'category' => $category,
|
||||
'bbcode' => (($mimetype == 'text/bbcode') ? true : false)
|
||||
);
|
||||
|
||||
$editor = status_editor($a, $x);
|
||||
|
||||
$o .= replace_macros(get_markup_template('edpost_head.tpl'), array(
|
||||
'$title' => t('Edit Article'),
|
||||
'$delete' => ((($itm[0]['author_xchan'] === $ob_hash) || ($itm[0]['owner_xchan'] === $ob_hash)) ? t('Delete') : false),
|
||||
'$id' => $itm[0]['id'],
|
||||
'$editor' => $editor
|
||||
));
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
|
||||
}
|
188
Zotlabs/Module/Articles.php
Normal file
188
Zotlabs/Module/Articles.php
Normal file
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
require_once('include/channel.php');
|
||||
require_once('include/conversation.php');
|
||||
require_once('include/acl_selectors.php');
|
||||
|
||||
|
||||
class Articles extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
if(argc() > 1)
|
||||
$which = argv(1);
|
||||
else
|
||||
return;
|
||||
|
||||
profile_load($which);
|
||||
|
||||
}
|
||||
|
||||
function get($update = 0, $load = false) {
|
||||
|
||||
if(observer_prohibited(true)) {
|
||||
return login();
|
||||
}
|
||||
|
||||
if(! \App::$profile) {
|
||||
notice( t('Requested profile is not available.') . EOL );
|
||||
\App::$error = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
if(! feature_enabled(\App::$profile_uid,'articles')) {
|
||||
return;
|
||||
}
|
||||
|
||||
nav_set_selected(t('Articles'));
|
||||
|
||||
head_add_link([
|
||||
'rel' => 'alternate',
|
||||
'type' => 'application/json+oembed',
|
||||
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
|
||||
'title' => 'oembed'
|
||||
]);
|
||||
|
||||
|
||||
$category = (($_REQUEST['cat']) ? escape_tags(trim($_REQUEST['cat'])) : '');
|
||||
|
||||
if($category) {
|
||||
$sql_extra2 .= protect_sprintf(term_item_parent_query(\App::$profile['profile_uid'],'item', $category, TERM_CATEGORY));
|
||||
}
|
||||
|
||||
|
||||
$which = argv(1);
|
||||
|
||||
$selected_card = ((argc() > 2) ? argv(2) : '');
|
||||
|
||||
$_SESSION['return_url'] = \App::$query_string;
|
||||
|
||||
$uid = local_channel();
|
||||
$owner = \App::$profile_uid;
|
||||
$observer = \App::get_observer();
|
||||
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
if(! perm_is_allowed($owner,$ob_hash,'view_pages')) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$is_owner = ($uid && $uid == $owner);
|
||||
|
||||
$channel = channelx_by_n($owner);
|
||||
|
||||
if($channel) {
|
||||
$channel_acl = array(
|
||||
'allow_cid' => $channel['channel_allow_cid'],
|
||||
'allow_gid' => $channel['channel_allow_gid'],
|
||||
'deny_cid' => $channel['channel_deny_cid'],
|
||||
'deny_gid' => $channel['channel_deny_gid']
|
||||
);
|
||||
}
|
||||
else {
|
||||
$channel_acl = [ 'allow_cid' => '', 'allow_gid' => '', 'deny_cid' => '', 'deny_gid' => '' ];
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(perm_is_allowed($owner,$ob_hash,'write_pages')) {
|
||||
|
||||
$x = [
|
||||
'webpage' => ITEM_TYPE_ARTICLE,
|
||||
'is_owner' => true,
|
||||
'content_label' => t('Add Article'),
|
||||
'button' => t('Create'),
|
||||
'nickname' => $channel['channel_address'],
|
||||
'lockstate' => (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
|
||||
|| $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||
'acl' => (($is_owner) ? populate_acl($channel_acl, false,
|
||||
\Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_pages')) : ''),
|
||||
'permissions' => $channel_acl,
|
||||
'showacl' => (($is_owner) ? true : false),
|
||||
'visitor' => true,
|
||||
'body' => '[summary][/summary]',
|
||||
'hide_location' => false,
|
||||
'hide_voting' => false,
|
||||
'profile_uid' => intval($owner),
|
||||
'mimetype' => 'text/bbcode',
|
||||
'mimeselect' => false,
|
||||
'layoutselect' => false,
|
||||
'expanded' => false,
|
||||
'novoting' => false,
|
||||
'catsenabled' => feature_enabled($owner,'categories'),
|
||||
'bbco_autocomplete' => 'bbcode',
|
||||
'bbcode' => true
|
||||
];
|
||||
|
||||
if($_REQUEST['title'])
|
||||
$x['title'] = $_REQUEST['title'];
|
||||
if($_REQUEST['body'])
|
||||
$x['body'] = $_REQUEST['body'];
|
||||
$editor = status_editor($a,$x);
|
||||
|
||||
}
|
||||
else {
|
||||
$editor = '';
|
||||
}
|
||||
|
||||
|
||||
$sql_extra = item_permissions_sql($owner);
|
||||
|
||||
if($selected_card) {
|
||||
$r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.v = '%s' limit 1",
|
||||
dbesc($selected_card)
|
||||
);
|
||||
if($r) {
|
||||
$sql_extra .= "and item.id = " . intval($r[0]['iid']) . " ";
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("select * from item
|
||||
where item.uid = %d and item_type = %d
|
||||
$sql_extra order by item.created desc",
|
||||
intval($owner),
|
||||
intval(ITEM_TYPE_ARTICLE)
|
||||
);
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type in (0,7) and item.item_deleted = 0
|
||||
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 ";
|
||||
|
||||
if($r) {
|
||||
|
||||
$parents_str = ids_to_querystr($r,'id');
|
||||
|
||||
$items = q("SELECT item.*, item.id AS item_id
|
||||
FROM item
|
||||
WHERE item.uid = %d $item_normal
|
||||
AND item.parent IN ( %s )
|
||||
$sql_extra $sql_extra2 ",
|
||||
intval(\App::$profile['profile_uid']),
|
||||
dbesc($parents_str)
|
||||
);
|
||||
if($items) {
|
||||
xchan_query($items);
|
||||
$items = fetch_post_tags($items, true);
|
||||
$items = conv_sort($items,'updated');
|
||||
}
|
||||
else
|
||||
$items = [];
|
||||
}
|
||||
|
||||
$mode = 'articles';
|
||||
|
||||
$content = conversation($items,$mode,false,'traditional');
|
||||
|
||||
$o = replace_macros(get_markup_template('cards.tpl'), [
|
||||
'$title' => t('Articles'),
|
||||
'$editor' => $editor,
|
||||
'$content' => $content,
|
||||
'$pager' => alt_pager($a,count($items))
|
||||
]);
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
}
|
|
@ -39,7 +39,7 @@ class Cdav extends \Zotlabs\Web\Controller {
|
|||
|
||||
$sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER[$head]);
|
||||
if($sigblock) {
|
||||
$keyId = $sigblock['keyId'];
|
||||
$keyId = str_replace('acct:','',$sigblock['keyId']);
|
||||
if($keyId) {
|
||||
$r = q("select * from hubloc where hubloc_addr = '%s' limit 1",
|
||||
dbesc($keyId)
|
||||
|
@ -1250,7 +1250,7 @@ class Cdav extends \Zotlabs\Web\Controller {
|
|||
//create default addressbook
|
||||
$carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo);
|
||||
$properties = ['{DAV:}displayname' => t('Default Addressbook')];
|
||||
$carddavBackend->createAddressBook($uri, $default, $properties);
|
||||
$carddavBackend->createAddressBook($uri, 'default', $properties);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,10 @@ class Cloud extends \Zotlabs\Web\Controller {
|
|||
// $server->addPlugin(new \Zotlabs\Storage\\QuotaPlugin($auth));
|
||||
|
||||
|
||||
// over-ride the default XML output on thrown exceptions
|
||||
|
||||
$server->on('exception', [ $this, 'DAVException' ]);
|
||||
|
||||
// All we need to do now, is to fire up the server
|
||||
|
||||
$server->exec();
|
||||
|
@ -97,4 +101,24 @@ class Cloud extends \Zotlabs\Web\Controller {
|
|||
killme();
|
||||
}
|
||||
|
||||
|
||||
function DAVException($err) {
|
||||
|
||||
if($err instanceof \Sabre\DAV\Exception\NotFound) {
|
||||
notice( t('Not found') . EOL);
|
||||
}
|
||||
elseif($err instanceof \Sabre\DAV\Exception\Forbidden) {
|
||||
notice( t('Permission denied') . EOL);
|
||||
}
|
||||
else {
|
||||
notice( t('Unknown error') . EOL);
|
||||
}
|
||||
|
||||
construct_page();
|
||||
|
||||
killme();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -567,7 +567,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||
$contact_id = \App::$poi['abook_id'];
|
||||
$contact = \App::$poi;
|
||||
|
||||
$cn = q("SELECT abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 order by xchan_name",
|
||||
$cn = q("SELECT abook_id, xchan_name from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_self = 0 and xchan_deleted = 0 order by xchan_name",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
@ -866,7 +866,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
|||
$o .= replace_macros($tpl, [
|
||||
'$header' => (($self) ? t('Connection Default Permissions') : sprintf( t('Connection: %s'),$contact['xchan_name'])),
|
||||
'$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('Connection requests will be approved without your interaction'), $yes_no),
|
||||
'$permcat' => [ 'permcat', t('Permission role'), '', '',$permcats ],
|
||||
'$permcat' => [ 'permcat', t('Permission role'), '', '<span class="loading invisible">' . t('Loading') . '<span class="jumping-dots"><span class="dot-1">.</span><span class="dot-2">.</span><span class="dot-3">.</span></span></span>',$permcats ],
|
||||
'$permcat_new' => t('Add permission role'),
|
||||
'$permcat_enable' => feature_enabled(local_channel(),'permcats'),
|
||||
'$addr' => $contact['xchan_addr'],
|
||||
|
|
|
@ -48,7 +48,7 @@ class Dav extends \Zotlabs\Web\Controller {
|
|||
|
||||
$sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER[$head]);
|
||||
if($sigblock) {
|
||||
$keyId = $sigblock['keyId'];
|
||||
$keyId = str_replace('acct:','',$sigblock['keyId']);
|
||||
if($keyId) {
|
||||
$r = q("select * from hubloc where hubloc_addr = '%s' limit 1",
|
||||
dbesc($keyId)
|
||||
|
|
|
@ -237,7 +237,7 @@ class Defperms extends \Zotlabs\Web\Controller {
|
|||
$o .= replace_macros($tpl, [
|
||||
'$header' => t('Connection Default Permissions'),
|
||||
'$autoperms' => array('autoperms',t('Apply these permissions automatically'), ((get_pconfig(local_channel(),'system','autoperms')) ? 1 : 0), t('If enabled, connection requests will be approved without your interaction'), $yes_no),
|
||||
'$permcat' => [ 'permcat', t('Permission role'), '', '',$permcats ],
|
||||
'$permcat' => [ 'permcat', t('Permission role'), '', '<span class="loading invisible">' . t('Loading') . '<span class="jumping-dots"><span class="dot-1">.</span><span class="dot-2">.</span><span class="dot-3">.</span></span></span>',$permcats ],
|
||||
'$permcat_new' => t('Add permission role'),
|
||||
'$permcat_enable' => feature_enabled(local_channel(),'permcats'),
|
||||
'$section' => $section,
|
||||
|
|
|
@ -313,7 +313,7 @@ class Dirsearch extends \Zotlabs\Web\Controller {
|
|||
|
||||
$ret['results'] = $entries;
|
||||
if($kw) {
|
||||
$k = dir_tagadelic($kw);
|
||||
$k = dir_tagadelic($kw, $hub);
|
||||
if($k) {
|
||||
$ret['keywords'] = array();
|
||||
foreach($k as $kv) {
|
||||
|
|
|
@ -14,6 +14,7 @@ class Display extends \Zotlabs\Web\Controller {
|
|||
|
||||
$module_format = 'html';
|
||||
|
||||
|
||||
if(argc() > 1) {
|
||||
$module_format = substr(argv(1),strrpos(argv(1),'.') + 1);
|
||||
if(! in_array($module_format,['atom','zot','json']))
|
||||
|
@ -30,7 +31,7 @@ class Display extends \Zotlabs\Web\Controller {
|
|||
return;
|
||||
}
|
||||
|
||||
if(argc() > 1 && argv(1) !== 'load') {
|
||||
if(argc() > 1) {
|
||||
$item_hash = argv(1);
|
||||
if($module_format !== 'html') {
|
||||
$item_hash = substr($item_hash,0,strrpos($item_hash,'.'));
|
||||
|
@ -260,7 +261,7 @@ class Display extends \Zotlabs\Web\Controller {
|
|||
|
||||
elseif($update && !$load) {
|
||||
$r = null;
|
||||
|
||||
|
||||
require_once('include/channel.php');
|
||||
$sys = get_sys_channel();
|
||||
$sysid = $sys['channel_id'];
|
||||
|
@ -285,7 +286,6 @@ class Display extends \Zotlabs\Web\Controller {
|
|||
// make that content unsearchable by ensuring the owner_xchan can't match
|
||||
if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
|
||||
$sysid = 0;
|
||||
|
||||
$r = q("SELECT item.parent AS item_id from item
|
||||
WHERE parent_mid = '%s'
|
||||
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
|
||||
|
@ -315,7 +315,6 @@ class Display extends \Zotlabs\Web\Controller {
|
|||
WHERE parent in ( %s ) $item_normal ",
|
||||
dbesc($parents_str)
|
||||
);
|
||||
|
||||
xchan_query($items);
|
||||
$items = fetch_post_tags($items,true);
|
||||
$items = conv_sort($items,'created');
|
||||
|
|
|
@ -83,7 +83,7 @@ class Embedphotos extends \Zotlabs\Web\Controller {
|
|||
return '';
|
||||
|
||||
if($args['album'])
|
||||
$album = $args['album'];
|
||||
$album = (($args['album'] === '/') ? '' : $args['album']);
|
||||
if($args['title'])
|
||||
$title = $args['title'];
|
||||
|
||||
|
|
|
@ -16,12 +16,15 @@ class Feed extends \Zotlabs\Web\Controller {
|
|||
$params['type'] = ((stristr(argv(0),'json')) ? 'json' : 'xml');
|
||||
$params['pages'] = ((x($_REQUEST,'pages')) ? intval($_REQUEST['pages']) : 0);
|
||||
$params['top'] = ((x($_REQUEST,'top')) ? intval($_REQUEST['top']) : 0);
|
||||
$params['start'] = ((x($params,'start')) ? intval($params['start']) : 0);
|
||||
$params['records'] = ((x($params,'records')) ? intval($params['records']) : 40);
|
||||
$params['direction'] = ((x($params,'direction')) ? dbesc($params['direction']) : 'desc');
|
||||
$params['start'] = ((x($_REQUEST,'start')) ? intval($_REQUEST['start']) : 0);
|
||||
$params['records'] = ((x($_REQUEST,'records')) ? intval($_REQUEST['records']) : 40);
|
||||
$params['direction'] = ((x($_REQUEST,'direction')) ? dbesc($_REQUEST['direction']) : 'desc');
|
||||
$params['cat'] = ((x($_REQUEST,'cat')) ? escape_tags($_REQUEST['cat']) : '');
|
||||
$params['compat'] = ((x($_REQUEST,'compat')) ? intval($_REQUEST['compat']) : 0);
|
||||
|
||||
if(! in_array($params['direction'],['asc','desc'])) {
|
||||
$params['direction'] = 'desc';
|
||||
}
|
||||
|
||||
if(argc() > 1) {
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@ class File_upload extends \Zotlabs\Web\Controller {
|
|||
|
||||
function post() {
|
||||
|
||||
// logger('file upload: ' . print_r($_REQUEST,true));
|
||||
logger('file upload: ' . print_r($_REQUEST,true));
|
||||
logger('file upload: ' . print_r($_FILES,true));
|
||||
|
||||
$channel = (($_REQUEST['channick']) ? channelx_by_nick($_REQUEST['channick']) : null);
|
||||
|
||||
|
@ -30,8 +31,8 @@ class File_upload extends \Zotlabs\Web\Controller {
|
|||
|
||||
$_REQUEST['allow_cid'] = perms2str($_REQUEST['contact_allow']);
|
||||
$_REQUEST['allow_gid'] = perms2str($_REQUEST['group_allow']);
|
||||
$_REQUEST['deny_cid'] = perms2str($_REQUEST['contact_deny']);
|
||||
$_REQUEST['deny_gid'] = perms2str($_REQUEST['group_deny']);
|
||||
$_REQUEST['deny_cid'] = perms2str($_REQUEST['contact_deny']);
|
||||
$_REQUEST['deny_gid'] = perms2str($_REQUEST['group_deny']);
|
||||
|
||||
if($_REQUEST['filename']) {
|
||||
$r = attach_mkdir($channel, get_observer_hash(), $_REQUEST);
|
||||
|
@ -47,6 +48,51 @@ class File_upload extends \Zotlabs\Web\Controller {
|
|||
}
|
||||
}
|
||||
else {
|
||||
|
||||
$matches = [];
|
||||
$partial = false;
|
||||
|
||||
|
||||
|
||||
if(array_key_exists('HTTP_CONTENT_RANGE',$_SERVER)) {
|
||||
$pm = preg_match('/bytes (\d*)\-(\d*)\/(\d*)/',$_SERVER['HTTP_CONTENT_RANGE'],$matches);
|
||||
if($pm) {
|
||||
logger('Content-Range: ' . print_r($matches,true));
|
||||
$partial = true;
|
||||
}
|
||||
}
|
||||
|
||||
if($partial) {
|
||||
$x = save_chunk($channel,$matches[1],$matches[2],$matches[3]);
|
||||
|
||||
if($x['partial']) {
|
||||
header('Range: bytes=0-' . (($x['length']) ? $x['length'] - 1 : 0));
|
||||
json_return_and_die($result);
|
||||
}
|
||||
else {
|
||||
header('Range: bytes=0-' . (($x['size']) ? $x['size'] - 1 : 0));
|
||||
|
||||
$_FILES['userfile'] = [
|
||||
'name' => $x['name'],
|
||||
'type' => $x['type'],
|
||||
'tmp_name' => $x['tmp_name'],
|
||||
'error' => $x['error'],
|
||||
'size' => $x['size']
|
||||
];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(! array_key_exists('userfile',$_FILES)) {
|
||||
$_FILES['userfile'] = [
|
||||
'name' => $_FILES['files']['name'],
|
||||
'type' => $_FILES['files']['type'],
|
||||
'tmp_name' => $_FILES['files']['tmp_name'],
|
||||
'error' => $_FILES['files']['error'],
|
||||
'size' => $_FILES['files']['size']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$r = attach_store($channel, get_observer_hash(), '', $_REQUEST);
|
||||
if($r['success']) {
|
||||
$sync = attach_export_data($channel,$r['data']['hash']);
|
||||
|
|
|
@ -103,6 +103,11 @@ class Filestorage extends \Zotlabs\Web\Controller {
|
|||
|
||||
attach_delete($owner, $f['hash']);
|
||||
|
||||
$sync = attach_export_data($channel, $f['hash'], true);
|
||||
if($sync) {
|
||||
build_sync_packet($channel['channel_id'], array('file' => array($sync)));
|
||||
}
|
||||
|
||||
goaway(dirname($url));
|
||||
}
|
||||
|
||||
|
|
|
@ -28,17 +28,51 @@ class Getfile extends \Zotlabs\Web\Controller {
|
|||
|
||||
function post() {
|
||||
|
||||
logger('post: ' . print_r($_POST,true),LOGGER_DEBUG,LOG_INFO);
|
||||
|
||||
$header_verified = false;
|
||||
|
||||
$hash = $_POST['hash'];
|
||||
$time = $_POST['time'];
|
||||
$sig = $_POST['signature'];
|
||||
$resource = $_POST['resource'];
|
||||
$revision = intval($_POST['revision']);
|
||||
$resolution = (-1);
|
||||
|
||||
|
||||
if(! $hash)
|
||||
killme();
|
||||
|
||||
foreach([ 'REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION' ] as $head) {
|
||||
if(array_key_exists($head,$_SERVER) && substr(trim($_SERVER[$head]),0,9) === 'Signature') {
|
||||
if($head !== 'HTTP_AUTHORIZATION') {
|
||||
$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER[$head];
|
||||
continue;
|
||||
}
|
||||
|
||||
$sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER[$head]);
|
||||
if($sigblock) {
|
||||
$keyId = $sigblock['keyId'];
|
||||
|
||||
if($keyId) {
|
||||
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
|
||||
where hubloc_addr = '%s' limit 1",
|
||||
dbesc(str_replace('acct:','',$keyId))
|
||||
);
|
||||
if($r) {
|
||||
$hubloc = $r[0];
|
||||
$verified = \Zotlabs\Web\HTTPSig::verify('',$hubloc['xchan_pubkey']);
|
||||
if($verified && $verified['header_signed'] && $verified['header_valid'] && $hash == $hubloc['hubloc_hash']) {
|
||||
$header_verified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
logger('post: ' . print_r($_POST,true),LOGGER_DEBUG,LOG_INFO);
|
||||
if($header_verified) {
|
||||
logger('HTTPSig verified');
|
||||
}
|
||||
|
||||
$channel = channelx_by_hash($hash);
|
||||
|
||||
|
@ -59,16 +93,17 @@ class Getfile extends \Zotlabs\Web\Controller {
|
|||
$d1 = datetime_convert('UTC','UTC',"now + $slop minutes");
|
||||
$d2 = datetime_convert('UTC','UTC',"now - $slop minutes");
|
||||
|
||||
if(($time > $d1) || ($time < $d2)) {
|
||||
logger('time outside allowable range');
|
||||
killme();
|
||||
}
|
||||
if(! $header_verified) {
|
||||
if(($time > $d1) || ($time < $d2)) {
|
||||
logger('time outside allowable range');
|
||||
killme();
|
||||
}
|
||||
|
||||
if(! rsa_verify($hash . '.' . $time,base64url_decode($sig),$channel['channel_pubkey'])) {
|
||||
logger('verify failed.');
|
||||
killme();
|
||||
if(! rsa_verify($hash . '.' . $time,base64url_decode($sig),$channel['channel_pubkey'])) {
|
||||
logger('verify failed.');
|
||||
killme();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($resolution > 0) {
|
||||
$r = q("select * from photo where resource_id = '%s' and uid = %d limit 1",
|
||||
|
|
|
@ -10,6 +10,13 @@ require_once('include/items.php');
|
|||
|
||||
class Hq extends \Zotlabs\Web\Controller {
|
||||
|
||||
function init() {
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
\App::$profile_uid = local_channel();
|
||||
}
|
||||
|
||||
function post() {
|
||||
|
||||
if(!local_channel())
|
||||
|
@ -43,33 +50,59 @@ class Hq extends \Zotlabs\Web\Controller {
|
|||
$item_normal_update = item_normal_update();
|
||||
|
||||
if(! $item_hash) {
|
||||
|
||||
$r = q("SELECT mid FROM item
|
||||
WHERE uid = %d
|
||||
AND item_thread_top = 1
|
||||
ORDER BY created DESC
|
||||
limit 1",
|
||||
WHERE uid = %d
|
||||
AND mid = parent_mid
|
||||
ORDER BY created DESC LIMIT 1",
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if(!$r[0]['mid']) {
|
||||
\App::$error = 404;
|
||||
notice( t('Item not found.') . EOL);
|
||||
return;
|
||||
if($r[0]['mid']) {
|
||||
$item_hash = 'b64.' . base64url_encode($r[0]['mid']);
|
||||
}
|
||||
|
||||
$item_hash = 'b64.' . base64url_encode($r[0]['mid']);
|
||||
}
|
||||
|
||||
if(strpos($item_hash,'b64.') === 0)
|
||||
$decoded = @base64url_decode(substr($item_hash,4));
|
||||
if($decoded)
|
||||
$item_hash = $decoded;
|
||||
|
||||
$updateable = false;
|
||||
if($item_hash) {
|
||||
|
||||
if(! $update) {
|
||||
if(strpos($item_hash,'b64.') === 0)
|
||||
$decoded = @base64url_decode(substr($item_hash,4));
|
||||
|
||||
if($decoded)
|
||||
$item_hash = $decoded;
|
||||
|
||||
$target_item = null;
|
||||
|
||||
$r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid like '%s' limit 1",
|
||||
dbesc($item_hash . '%')
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$target_item = $r[0];
|
||||
}
|
||||
|
||||
//if the item is to be moderated redirect to /moderate
|
||||
if($target_item['item_blocked'] == ITEM_MODERATED) {
|
||||
goaway(z_root() . '/moderate/' . $target_item['id']);
|
||||
}
|
||||
|
||||
$static = ((array_key_exists('static',$_REQUEST)) ? intval($_REQUEST['static']) : 0);
|
||||
|
||||
$simple_update = (($update) ? " AND item_unseen = 1 " : '');
|
||||
|
||||
if($update && $_SESSION['loadtime'])
|
||||
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
|
||||
|
||||
if($static && $simple_update)
|
||||
$simple_update .= " and item_thread_top = 0 and author_xchan = '" . protect_sprintf(get_observer_hash()) . "' ";
|
||||
|
||||
$sys = get_sys_channel();
|
||||
$sql_extra = item_permissions_sql($sys['channel_id']);
|
||||
|
||||
$sys_item = false;
|
||||
|
||||
}
|
||||
|
||||
if(! $update) {
|
||||
$channel = \App::get_channel();
|
||||
|
||||
$channel_acl = [
|
||||
|
@ -91,66 +124,50 @@ class Hq extends \Zotlabs\Web\Controller {
|
|||
'bang' => '',
|
||||
'visitor' => true,
|
||||
'profile_uid' => local_channel(),
|
||||
'return_path' => 'channel/' . $channel['channel_address'],
|
||||
'return_path' => 'hq',
|
||||
'expanded' => true,
|
||||
'editor_autocomplete' => true,
|
||||
'bbco_autocomplete' => 'bbcode',
|
||||
'bbcode' => true,
|
||||
'jotnets' => true
|
||||
];
|
||||
|
||||
$o = '<div id="jot-popup">';
|
||||
$o .= status_editor($a,$x);
|
||||
$o .= '</div>';
|
||||
}
|
||||
|
||||
$target_item = null;
|
||||
|
||||
$r = q("select id, uid, mid, parent_mid, thr_parent, verb, item_type, item_deleted, item_blocked from item where mid like '%s' limit 1",
|
||||
dbesc($item_hash . '%')
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$target_item = $r[0];
|
||||
$o = replace_macros(get_markup_template("hq.tpl"),
|
||||
[
|
||||
'$no_messages' => (($target_item) ? false : true),
|
||||
'$no_messages_label' => [ t('Welcome to Hubzilla!'), t('You have got no unseen posts...') ],
|
||||
'$editor' => status_editor($a,$x)
|
||||
]
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
//if the item is to be moderated redirect to /moderate
|
||||
if($target_item['item_blocked'] == ITEM_MODERATED) {
|
||||
goaway(z_root() . '/moderate/' . $target_item['id']);
|
||||
}
|
||||
|
||||
$static = ((array_key_exists('static',$_REQUEST)) ? intval($_REQUEST['static']) : 0);
|
||||
|
||||
$simple_update = (($update) ? " AND item_unseen = 1 " : '');
|
||||
|
||||
if($update && $_SESSION['loadtime'])
|
||||
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
|
||||
if($load)
|
||||
$simple_update = '';
|
||||
|
||||
if($static && $simple_update)
|
||||
$simple_update .= " and item_thread_top = 0 and author_xchan = '" . protect_sprintf(get_observer_hash()) . "' ";
|
||||
|
||||
if(! $update && ! $load) {
|
||||
|
||||
nav_set_selected('HQ');
|
||||
|
||||
$static = ((local_channel()) ? channel_manual_conv_update(local_channel()) : 1);
|
||||
|
||||
// if the target item is not a post (eg a like) we want to address its thread parent
|
||||
if($target_item) {
|
||||
// if the target item is not a post (eg a like) we want to address its thread parent
|
||||
$mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']);
|
||||
|
||||
$mid = ((($target_item['verb'] == ACTIVITY_LIKE) || ($target_item['verb'] == ACTIVITY_DISLIKE)) ? $target_item['thr_parent'] : $target_item['mid']);
|
||||
// if we got a decoded hash we must encode it again before handing to javascript
|
||||
if($decoded)
|
||||
$mid = 'b64.' . base64url_encode($mid);
|
||||
}
|
||||
else {
|
||||
$mid = '';
|
||||
}
|
||||
|
||||
// if we got a decoded hash we must encode it again before handing to javascript
|
||||
if($decoded)
|
||||
$mid = 'b64.' . base64url_encode($mid);
|
||||
|
||||
$o .= '<div id="live-display"></div>' . "\r\n";
|
||||
$o .= '<div id="live-hq"></div>' . "\r\n";
|
||||
$o .= "<script> var profile_uid = " . local_channel()
|
||||
. "; var netargs = '?f='; var profile_page = " . \App::$pager['page'] . "; </script>\r\n";
|
||||
. "; var netargs = '?f='; var profile_page = " . \App::$pager['page'] . ";</script>\r\n";
|
||||
|
||||
\App::$page['htmlhead'] .= replace_macros(get_markup_template("build_query.tpl"),[
|
||||
'$baseurl' => z_root(),
|
||||
'$pgtype' => 'display',
|
||||
'$uid' => '0',
|
||||
'$pgtype' => 'hq',
|
||||
'$uid' => local_channel(),
|
||||
'$gid' => '0',
|
||||
'$cid' => '0',
|
||||
'$cmin' => '0',
|
||||
|
@ -177,71 +194,94 @@ class Hq extends \Zotlabs\Web\Controller {
|
|||
'$net' => '',
|
||||
'$mid' => $mid
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
if($load) {
|
||||
$updateable = false;
|
||||
|
||||
if($load && $target_item) {
|
||||
$r = null;
|
||||
|
||||
$r = q("SELECT item.id as item_id from item
|
||||
$r = q("SELECT item.id AS item_id FROM item
|
||||
WHERE uid = %d
|
||||
and mid = '%s'
|
||||
AND mid = '%s'
|
||||
$item_normal
|
||||
limit 1",
|
||||
LIMIT 1",
|
||||
intval(local_channel()),
|
||||
dbesc($target_item['parent_mid'])
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$updateable = true;
|
||||
}
|
||||
|
||||
if(!$r) {
|
||||
$sys_item = true;
|
||||
|
||||
$r = q("SELECT item.id AS item_id FROM item
|
||||
LEFT JOIN abook ON item.author_xchan = abook.abook_xchan
|
||||
WHERE mid = '%s' AND item.uid = %d $item_normal
|
||||
AND (abook.abook_blocked = 0 or abook.abook_flags is null)
|
||||
$sql_extra LIMIT 1",
|
||||
dbesc($target_item['parent_mid']),
|
||||
intval($sys['channel_id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
elseif($update) {
|
||||
elseif($update && $target_item) {
|
||||
$r = null;
|
||||
|
||||
$r = q("SELECT item.parent AS item_id from item
|
||||
$r = q("SELECT item.parent AS item_id FROM item
|
||||
WHERE uid = %d
|
||||
and parent_mid = '%s'
|
||||
AND parent_mid = '%s'
|
||||
$item_normal_update
|
||||
$simple_update
|
||||
limit 1",
|
||||
LIMIT 1",
|
||||
intval(local_channel()),
|
||||
dbesc($target_item['parent_mid'])
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$updateable = true;
|
||||
}
|
||||
|
||||
if(!$r) {
|
||||
$sys_item = true;
|
||||
|
||||
$r = q("SELECT item.parent AS item_id FROM item
|
||||
LEFT JOIN abook ON item.author_xchan = abook.abook_xchan
|
||||
WHERE mid = '%s' AND item.uid = %d $item_normal_update $simple_update
|
||||
AND (abook.abook_blocked = 0 or abook.abook_flags is null)
|
||||
$sql_extra LIMIT 1",
|
||||
dbesc($target_item['parent_mid']),
|
||||
intval($sys['channel_id'])
|
||||
);
|
||||
}
|
||||
|
||||
$_SESSION['loadtime'] = datetime_convert();
|
||||
}
|
||||
|
||||
else {
|
||||
$r = [];
|
||||
}
|
||||
|
||||
if($r) {
|
||||
$parents_str = ids_to_querystr($r,'item_id');
|
||||
if($parents_str) {
|
||||
$items = q("SELECT item.*, item.id AS item_id
|
||||
FROM item
|
||||
WHERE parent in ( %s ) $item_normal ",
|
||||
dbesc($parents_str)
|
||||
);
|
||||
$items = q("SELECT item.*, item.id AS item_id
|
||||
FROM item
|
||||
WHERE parent = '%s' $item_normal ",
|
||||
dbesc($r[0]['item_id'])
|
||||
);
|
||||
|
||||
xchan_query($items);
|
||||
$items = fetch_post_tags($items,true);
|
||||
$items = conv_sort($items,'created');
|
||||
}
|
||||
xchan_query($items,true,(($sys_item) ? local_channel() : 0));
|
||||
$items = fetch_post_tags($items,true);
|
||||
$items = conv_sort($items,'created');
|
||||
}
|
||||
else {
|
||||
$items = [];
|
||||
}
|
||||
|
||||
$o .= conversation($items, 'display', $update, 'client');
|
||||
|
||||
$o .= conversation($items, 'hq', $update, 'client');
|
||||
|
||||
if($updateable) {
|
||||
$x = q("UPDATE item SET item_unseen = 0 where item_unseen = 1 AND uid = %d and parent = %d ",
|
||||
$x = q("UPDATE item SET item_unseen = 0 WHERE item_unseen = 1 AND uid = %d AND parent = %d ",
|
||||
intval(local_channel()),
|
||||
intval($r[0]['item_id'])
|
||||
);
|
||||
|
@ -249,10 +289,6 @@ class Hq extends \Zotlabs\Web\Controller {
|
|||
|
||||
$o .= '<div id="content-complete"></div>';
|
||||
|
||||
if(($update && $load) && (! $items)) {
|
||||
notice( t('Something went wrong.') . EOL );
|
||||
}
|
||||
|
||||
return $o;
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ class Impel extends \Zotlabs\Web\Controller {
|
|||
if(! $j)
|
||||
json_return_and_die($ret);
|
||||
|
||||
// logger('element: ' . print_r($j,true));
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
$arr = array();
|
||||
|
|
|
@ -59,6 +59,7 @@ class Item extends \Zotlabs\Web\Controller {
|
|||
|
||||
$profile_uid = ((x($_REQUEST,'profile_uid')) ? intval($_REQUEST['profile_uid']) : 0);
|
||||
require_once('include/channel.php');
|
||||
|
||||
$sys = get_sys_channel();
|
||||
if($sys && $profile_uid && ($sys['channel_id'] == $profile_uid) && is_site_admin()) {
|
||||
$uid = intval($sys['channel_id']);
|
||||
|
@ -155,7 +156,7 @@ class Item extends \Zotlabs\Web\Controller {
|
|||
if(! x($_REQUEST,'type'))
|
||||
$_REQUEST['type'] = 'net-comment';
|
||||
|
||||
if($obj_type == ACTIVITY_OBJ_POST)
|
||||
if($obj_type == ACTIVITY_OBJ_NOTE)
|
||||
$obj_type = ACTIVITY_OBJ_COMMENT;
|
||||
|
||||
if($parent) {
|
||||
|
@ -171,7 +172,7 @@ class Item extends \Zotlabs\Web\Controller {
|
|||
);
|
||||
}
|
||||
// if this isn't the real parent of the conversation, find it
|
||||
if($r !== false && count($r)) {
|
||||
if($r) {
|
||||
$parid = $r[0]['parent'];
|
||||
$parent_mid = $r[0]['mid'];
|
||||
if($r[0]['id'] != $r[0]['parent']) {
|
||||
|
@ -179,9 +180,16 @@ class Item extends \Zotlabs\Web\Controller {
|
|||
intval($parid)
|
||||
);
|
||||
}
|
||||
|
||||
// if interacting with a pubstream item,
|
||||
// create a copy of the parent in your stream
|
||||
|
||||
if($r[0]['uid'] === $sys['channel_id'] && local_channel()) {
|
||||
$r = [ copy_of_pubitem(\App::get_channel(), $r[0]['mid']) ];
|
||||
}
|
||||
}
|
||||
|
||||
if(($r === false) || (! count($r))) {
|
||||
|
||||
if(! $r) {
|
||||
notice( t('Unable to locate original post.') . EOL);
|
||||
if($api_source)
|
||||
return ( [ 'success' => false, 'message' => 'invalid post id' ] );
|
||||
|
@ -189,15 +197,12 @@ class Item extends \Zotlabs\Web\Controller {
|
|||
goaway(z_root() . "/" . $return_path );
|
||||
killme();
|
||||
}
|
||||
|
||||
// can_comment_on_post() needs info from the following xchan_query
|
||||
// This may be from the discover tab which means we need to correct the effective uid
|
||||
|
||||
xchan_query($r,true,(($r[0]['uid'] == local_channel()) ? 0 : local_channel()));
|
||||
|
||||
xchan_query($r,true);
|
||||
|
||||
$parent_item = $r[0];
|
||||
$parent = $r[0]['id'];
|
||||
|
||||
|
||||
// multi-level threading - preserve the info but re-parent to our single level threading
|
||||
|
||||
$thr_parent = $parent_mid;
|
||||
|
@ -499,7 +504,12 @@ class Item extends \Zotlabs\Web\Controller {
|
|||
$body = z_input_filter($body,$mimetype,$execflag);
|
||||
}
|
||||
|
||||
// Verify ability to use html or php!!!
|
||||
|
||||
$arr = [ 'profile_uid' => $profile_uid, 'content' => $body, 'mimetype' => $mimetype ];
|
||||
call_hooks('post_content',$arr);
|
||||
$body = $arr['content'];
|
||||
$mimetype = $arr['mimetype'];
|
||||
|
||||
|
||||
$gacl = $acl->get();
|
||||
$str_contact_allow = $gacl['allow_cid'];
|
||||
|
@ -511,13 +521,6 @@ class Item extends \Zotlabs\Web\Controller {
|
|||
|
||||
require_once('include/text.php');
|
||||
|
||||
if($uid && $uid == $profile_uid && feature_enabled($uid,'markdown')) {
|
||||
require_once('include/markdown.php');
|
||||
$body = preg_replace_callback('/\[share(.*?)\]/ism','\share_shield',$body);
|
||||
$body = markdown_to_bb($body,true,['preserve_lf' => true]);
|
||||
$body = preg_replace_callback('/\[share(.*?)\]/ism','\share_unshield',$body);
|
||||
|
||||
}
|
||||
|
||||
// BBCODE alert: the following functions assume bbcode input
|
||||
// and will require alternatives for alternative content-types (text/html, text/markdown, text/plain, etc.)
|
||||
|
@ -629,6 +632,9 @@ class Item extends \Zotlabs\Web\Controller {
|
|||
if($webpage == ITEM_TYPE_CARD) {
|
||||
$catlink = z_root() . '/cards/' . $channel['channel_address'] . '?f=&cat=' . urlencode(trim($cat));
|
||||
}
|
||||
elseif($webpage == ITEM_TYPE_ARTICLE) {
|
||||
$catlink = z_root() . '/articles/' . $channel['channel_address'] . '?f=&cat=' . urlencode(trim($cat));
|
||||
}
|
||||
else {
|
||||
$catlink = $owner_xchan['xchan_url'] . '?f=&cat=' . urlencode(trim($cat));
|
||||
}
|
||||
|
@ -733,6 +739,18 @@ class Item extends \Zotlabs\Web\Controller {
|
|||
}
|
||||
}
|
||||
|
||||
if($webpage == ITEM_TYPE_ARTICLE) {
|
||||
$plink = z_root() . '/articles/' . $channel['channel_address'] . '/' . (($pagetitle) ? $pagetitle : substr($mid,0,16));
|
||||
}
|
||||
if(($parent_item) && ($parent_item['item_type'] == ITEM_TYPE_ARTICLE)) {
|
||||
$r = q("select v from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.iid = %d limit 1",
|
||||
intval($parent_item['id'])
|
||||
);
|
||||
if($r) {
|
||||
$plink = z_root() . '/articles/' . $channel['channel_address'] . '/' . $r[0]['v'];
|
||||
}
|
||||
}
|
||||
|
||||
if ((! $plink) && ($item_thread_top)) {
|
||||
$plink = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $mid;
|
||||
}
|
||||
|
@ -1119,7 +1137,29 @@ class Item extends \Zotlabs\Web\Controller {
|
|||
$ret['message'] = t('Unable to obtain post information from database.');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
// auto-upgrade beginner (techlevel 0) accounts - if they have at least two friends and ten posts
|
||||
// and have uploaded something (like a profile photo), promote them to level 1.
|
||||
|
||||
$a = q("select account_id, account_level from account where account_id = (select channel_account_id from channel where channel_id = %d limit 1)",
|
||||
intval($channel_id)
|
||||
);
|
||||
if((! intval($a[0]['account_level'])) && intval($r[0]['total']) > 10) {
|
||||
$x = q("select count(abook_id) as total from abook where abook_channel = %d",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($x && intval($x[0]['total']) > 2) {
|
||||
$y = q("select count(id) as total from attach where uid = %d",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($y && intval($y[0]['total']) > 1) {
|
||||
q("update account set account_level = 1 where account_id = %d limit 1",
|
||||
intval($a[0]['account_id'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$iswebpage) {
|
||||
$max = engr_units_to_bytes(service_class_fetch($channel_id,'total_items'));
|
||||
if(! service_class_allows($channel_id,'total_items',$r[0]['total'])) {
|
||||
|
|
|
@ -162,12 +162,12 @@ class Layouts extends \Zotlabs\Web\Controller {
|
|||
'created' => $rr['created'],
|
||||
'edited' => $rr['edited'],
|
||||
'mimetype' => $rr['mimetype'],
|
||||
'pagetitle' => $rr['sid'],
|
||||
'pagetitle' => urldecode($rr['v']),
|
||||
'mid' => $rr['mid']
|
||||
);
|
||||
$pages[$rr['iid']][] = array(
|
||||
'url' => $rr['iid'],
|
||||
'title' => $rr['v'],
|
||||
'title' => urldecode($rr['v']),
|
||||
'descr' => $rr['title'],
|
||||
'mid' => $rr['mid'],
|
||||
'created' => $rr['created'],
|
||||
|
|
|
@ -258,20 +258,27 @@ class Like extends \Zotlabs\Web\Controller {
|
|||
// get the item. Allow linked photos (which are normally hidden) to be liked
|
||||
|
||||
$r = q("SELECT * FROM item WHERE id = %d
|
||||
and (item_type = 0 or item_type = 6) and item_deleted = 0 and item_unpublished = 0
|
||||
and item_type in (0,6,7) and item_deleted = 0 and item_unpublished = 0
|
||||
and item_delayed = 0 and item_pending_remove = 0 and item_blocked = 0 LIMIT 1",
|
||||
intval($item_id)
|
||||
);
|
||||
|
||||
// if interacting with a pubstream item,
|
||||
// create a copy of the parent in your stream. If not the conversation
|
||||
// parent, copy that as well.
|
||||
|
||||
if($r) {
|
||||
if($r[0]['uid'] === $sys_channel['channel_id'] && local_channel()) {
|
||||
$r = [ copy_of_pubitem(\App::get_channel(), $r[0]['mid']) ];
|
||||
}
|
||||
}
|
||||
|
||||
if(! $item_id || (! $r)) {
|
||||
logger('like: no item ' . $item_id);
|
||||
killme();
|
||||
}
|
||||
|
||||
// Use the $effective_uid option of xchan_query to sort out comment permission
|
||||
// for public stream items
|
||||
|
||||
xchan_query($r,true,(($r[0]['uid'] == $sys_channel_id) ? local_channel() : 0));
|
||||
xchan_query($r,true);
|
||||
|
||||
$item = $r[0];
|
||||
|
||||
|
|
|
@ -35,9 +35,12 @@ class Network extends \Zotlabs\Web\Controller {
|
|||
return login(false);
|
||||
}
|
||||
|
||||
if($load)
|
||||
$o = '';
|
||||
|
||||
if($load) {
|
||||
$_SESSION['loadtime'] = datetime_convert();
|
||||
|
||||
}
|
||||
|
||||
$arr = array('query' => \App::$query_string);
|
||||
|
||||
call_hooks('network_content_init', $arr);
|
||||
|
@ -104,8 +107,10 @@ class Network extends \Zotlabs\Web\Controller {
|
|||
$def_acl = array('allow_gid' => '<' . $r[0]['hash'] . '>');
|
||||
}
|
||||
|
||||
$o = '';
|
||||
|
||||
$default_cmin = ((feature_enabled(local_channel(),'affinity')) ? get_pconfig(local_channel(),'affinity','cmin',0) : 0);
|
||||
$default_cmax = ((feature_enabled(local_channel(),'affinity')) ? get_pconfig(local_channel(),'affinity','cmax',99) : 99);
|
||||
|
||||
|
||||
// if no tabs are selected, defaults to comments
|
||||
|
||||
|
@ -115,8 +120,8 @@ class Network extends \Zotlabs\Web\Controller {
|
|||
$liked = ((x($_GET,'liked')) ? intval($_GET['liked']) : 0);
|
||||
$conv = ((x($_GET,'conv')) ? intval($_GET['conv']) : 0);
|
||||
$spam = ((x($_GET,'spam')) ? intval($_GET['spam']) : 0);
|
||||
$cmin = ((x($_GET,'cmin')) ? intval($_GET['cmin']) : 0);
|
||||
$cmax = ((x($_GET,'cmax')) ? intval($_GET['cmax']) : 99);
|
||||
$cmin = ((array_key_exists('cmin',$_GET)) ? intval($_GET['cmin']) : $default_cmin);
|
||||
$cmax = ((array_key_exists('cmax',$_GET)) ? intval($_GET['cmax']) : $default_cmax);
|
||||
$file = ((x($_GET,'file')) ? $_GET['file'] : '');
|
||||
$xchan = ((x($_GET,'xchan')) ? $_GET['xchan'] : '');
|
||||
$net = ((x($_GET,'net')) ? $_GET['net'] : '');
|
||||
|
@ -404,7 +409,6 @@ class Network extends \Zotlabs\Web\Controller {
|
|||
if($cmax == 99)
|
||||
$sql_nets .= " OR abook.abook_closeness IS NULL ) ";
|
||||
|
||||
|
||||
}
|
||||
|
||||
$net_query = (($net) ? " left join xchan on xchan_hash = author_xchan " : '');
|
||||
|
@ -473,7 +477,6 @@ class Network extends \Zotlabs\Web\Controller {
|
|||
if($load) {
|
||||
|
||||
// Fetch a page full of parent items for this page
|
||||
|
||||
$r = q("SELECT distinct item.id AS item_id, $ordering FROM item
|
||||
left join abook on ( item.owner_xchan = abook.abook_xchan $abook_uids )
|
||||
$net_query
|
||||
|
@ -484,7 +487,6 @@ class Network extends \Zotlabs\Web\Controller {
|
|||
$net_query2
|
||||
ORDER BY $ordering DESC $pager_sql "
|
||||
);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ class Oep extends \Zotlabs\Web\Controller {
|
|||
$arr = $this->oep_profile_reply($_REQUEST);
|
||||
elseif(fnmatch('*/cards/*',$url))
|
||||
$arr = $this->oep_cards_reply($_REQUEST);
|
||||
elseif(fnmatch('*/articles/*',$url))
|
||||
$arr = $this->oep_articles_reply($_REQUEST);
|
||||
|
||||
if($arr) {
|
||||
if($html) {
|
||||
|
@ -232,6 +234,89 @@ class Oep extends \Zotlabs\Web\Controller {
|
|||
|
||||
}
|
||||
|
||||
function oep_articles_reply($args) {
|
||||
|
||||
$ret = [];
|
||||
$url = $args['url'];
|
||||
$maxwidth = intval($args['maxwidth']);
|
||||
$maxheight = intval($args['maxheight']);
|
||||
|
||||
if(preg_match('#//(.*?)/articles/(.*?)/(.*?)(&|\?|$)#',$url,$matches)) {
|
||||
$nick = $matches[2];
|
||||
$res = $matches[3];
|
||||
}
|
||||
if(! ($nick && $res))
|
||||
return $ret;
|
||||
|
||||
$channel = channelx_by_nick($nick);
|
||||
|
||||
if(! $channel)
|
||||
return $ret;
|
||||
|
||||
|
||||
if(! perm_is_allowed($channel['channel_id'],get_observer_hash(),'view_pages'))
|
||||
return $ret;
|
||||
|
||||
$sql_extra = item_permissions_sql($channel['channel_id'],get_observer_hash());
|
||||
|
||||
$r = q("select * from iconfig where iconfig.cat = 'system' and iconfig.k = 'ARTICLE' and iconfig.v = '%s' limit 1",
|
||||
dbesc($res)
|
||||
);
|
||||
if($r) {
|
||||
$sql_extra = "and item.id = " . intval($r[0]['iid']) . " ";
|
||||
}
|
||||
else {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$r = q("select * from item
|
||||
where item.uid = %d and item_type = %d
|
||||
$sql_extra order by item.created desc",
|
||||
intval($channel['channel_id']),
|
||||
intval(ITEM_TYPE_ARTICLE)
|
||||
);
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type in (0,7) and item.item_deleted = 0
|
||||
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 ";
|
||||
|
||||
if($r) {
|
||||
xchan_query($r);
|
||||
$p = fetch_post_tags($r, true);
|
||||
}
|
||||
|
||||
$x = '2eGriplW^*Jmf4';
|
||||
|
||||
|
||||
$o = "[share author='".urlencode($p[0]['author']['xchan_name']).
|
||||
"' profile='".$p[0]['author']['xchan_url'] .
|
||||
"' avatar='".$p[0]['author']['xchan_photo_s'].
|
||||
"' link='".$p[0]['plink'].
|
||||
"' posted='".$p[0]['created'].
|
||||
"' message_id='".$p[0]['mid']."']";
|
||||
if($p[0]['title'])
|
||||
$o .= '[b]'.$p[0]['title'].'[/b]'."\r\n";
|
||||
|
||||
$o .= $x;
|
||||
$o .= "[/share]";
|
||||
$o = bbcode($o);
|
||||
|
||||
$o = str_replace($x,bbcode($p[0]['body']),$o);
|
||||
|
||||
$ret['type'] = 'rich';
|
||||
|
||||
$w = (($maxwidth) ? $maxwidth : 640);
|
||||
$h = (($maxheight) ? $maxheight : intval($w * 2 / 3));
|
||||
|
||||
$ret['html'] = '<div style="width: ' . $w . '; height: ' . $h . '; font-family: sans-serif,arial,freesans;" >' . $o . '</div>';
|
||||
|
||||
$ret['width'] = $w;
|
||||
$ret['height'] = $h;
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function oep_mid_reply($args) {
|
||||
|
||||
|
|
|
@ -17,12 +17,15 @@ class Ofeed extends \Zotlabs\Web\Controller {
|
|||
$params['type'] = ((stristr(argv(0),'json')) ? 'json' : 'xml');
|
||||
$params['pages'] = ((x($_REQUEST,'pages')) ? intval($_REQUEST['pages']) : 0);
|
||||
$params['top'] = ((x($_REQUEST,'top')) ? intval($_REQUEST['top']) : 0);
|
||||
$params['start'] = ((x($params,'start')) ? intval($params['start']) : 0);
|
||||
$params['records'] = ((x($params,'records')) ? intval($params['records']) : 10);
|
||||
$params['direction'] = ((x($params,'direction')) ? dbesc($params['direction']) : 'desc');
|
||||
$params['start'] = ((x($_REQUEST,'start')) ? intval($_REQUEST['start']) : 0);
|
||||
$params['records'] = ((x($_REQUEST,'records')) ? intval($_REQUEST['records']) : 10);
|
||||
$params['direction'] = ((x($_REQUEST,'direction')) ? dbesc($_REQUEST['direction']) : 'desc');
|
||||
$params['cat'] = ((x($_REQUEST,'cat')) ? escape_tags($_REQUEST['cat']) : '');
|
||||
$params['compat'] = ((x($_REQUEST,'compat')) ? intval($_REQUEST['compat']) : 1);
|
||||
|
||||
if(! in_array($params['direction'],['asc','desc'])) {
|
||||
$params['direction'] = 'desc';
|
||||
}
|
||||
|
||||
if(argc() > 1) {
|
||||
|
||||
|
|
|
@ -31,19 +31,26 @@ class Owa extends \Zotlabs\Web\Controller {
|
|||
|
||||
if($keyId) {
|
||||
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
|
||||
where hubloc_addr = '%s' limit 1",
|
||||
where hubloc_addr = '%s' ",
|
||||
dbesc(str_replace('acct:','',$keyId))
|
||||
);
|
||||
if($r) {
|
||||
$hubloc = $r[0];
|
||||
$verified = \Zotlabs\Web\HTTPSig::verify('',$hubloc['xchan_pubkey']);
|
||||
if($verified && $verified['header_signed'] && $verified['header_valid']) {
|
||||
$ret['success'] = true;
|
||||
$token = random_string(32);
|
||||
\Zotlabs\Zot\Verify::create('owt',0,$token,$r[0]['hubloc_addr']);
|
||||
$result = '';
|
||||
openssl_public_encrypt($token,$result,$hubloc['xchan_pubkey']);
|
||||
$ret['encrypted_token'] = base64url_encode($result);
|
||||
foreach($r as $hubloc) {
|
||||
$verified = \Zotlabs\Web\HTTPSig::verify('',$hubloc['xchan_pubkey']);
|
||||
if($verified && $verified['header_signed'] && $verified['header_valid']) {
|
||||
logger('OWA header: ' . print_r($verified,true),LOGGER_DATA);
|
||||
logger('OWA success: ' . $hubloc['hubloc_addr'],LOGGER_DATA);
|
||||
$ret['success'] = true;
|
||||
$token = random_string(32);
|
||||
\Zotlabs\Zot\Verify::create('owt',0,$token,$hubloc['hubloc_addr']);
|
||||
$result = '';
|
||||
openssl_public_encrypt($token,$result,$hubloc['xchan_pubkey']);
|
||||
$ret['encrypted_token'] = base64url_encode($result);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_addr']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -202,6 +202,11 @@ class Photos extends \Zotlabs\Web\Controller {
|
|||
);
|
||||
if(($m) && ($m[0]['folder'] != $_POST['move_to_album'])) {
|
||||
attach_move($page_owner_uid,argv(2),$_POST['move_to_album']);
|
||||
|
||||
$sync = attach_export_data(\App::$data['channel'],argv(2),true);
|
||||
if($sync)
|
||||
build_sync_packet($page_owner_uid,array('file' => array($sync)));
|
||||
|
||||
if(! ($_POST['desc'] && $_POST['newtag']))
|
||||
goaway(z_root() . '/' . $_SESSION['photo_return']);
|
||||
}
|
||||
|
@ -465,6 +470,51 @@ class Photos extends \Zotlabs\Web\Controller {
|
|||
$_REQUEST['group_deny'] = expand_acl($channel['channel_deny_gid']);
|
||||
}
|
||||
|
||||
|
||||
$matches = [];
|
||||
$partial = false;
|
||||
|
||||
|
||||
|
||||
if(array_key_exists('HTTP_CONTENT_RANGE',$_SERVER)) {
|
||||
$pm = preg_match('/bytes (\d*)\-(\d*)\/(\d*)/',$_SERVER['HTTP_CONTENT_RANGE'],$matches);
|
||||
if($pm) {
|
||||
logger('Content-Range: ' . print_r($matches,true));
|
||||
$partial = true;
|
||||
}
|
||||
}
|
||||
|
||||
if($partial) {
|
||||
$x = save_chunk($channel,$matches[1],$matches[2],$matches[3]);
|
||||
|
||||
if($x['partial']) {
|
||||
header('Range: bytes=0-' . (($x['length']) ? $x['length'] - 1 : 0));
|
||||
json_return_and_die($result);
|
||||
}
|
||||
else {
|
||||
header('Range: bytes=0-' . (($x['size']) ? $x['size'] - 1 : 0));
|
||||
|
||||
$_FILES['userfile'] = [
|
||||
'name' => $x['name'],
|
||||
'type' => $x['type'],
|
||||
'tmp_name' => $x['tmp_name'],
|
||||
'error' => $x['error'],
|
||||
'size' => $x['size']
|
||||
];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(! array_key_exists('userfile',$_FILES)) {
|
||||
$_FILES['userfile'] = [
|
||||
'name' => $_FILES['files']['name'],
|
||||
'type' => $_FILES['files']['type'],
|
||||
'tmp_name' => $_FILES['files']['tmp_name'],
|
||||
'error' => $_FILES['files']['error'],
|
||||
'size' => $_FILES['files']['size']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$r = attach_store($channel,get_observer_hash(), '', $_REQUEST);
|
||||
|
||||
if(! $r['success']) {
|
||||
|
@ -557,8 +607,11 @@ class Photos extends \Zotlabs\Web\Controller {
|
|||
|
||||
nav_set_selected('Photos');
|
||||
|
||||
$o = "";
|
||||
|
||||
$o = '<script src="library/blueimp_upload/js/vendor/jquery.ui.widget.js"></script>
|
||||
<script src="library/blueimp_upload/js/jquery.iframe-transport.js"></script>
|
||||
<script src="library/blueimp_upload/js/jquery.fileupload.js"></script>';
|
||||
|
||||
|
||||
$o .= "<script> var profile_uid = " . \App::$profile['profile_uid']
|
||||
. "; var netargs = '?f='; var profile_page = " . \App::$pager['page'] . "; </script>\r\n";
|
||||
|
||||
|
@ -656,7 +709,7 @@ class Photos extends \Zotlabs\Web\Controller {
|
|||
'$uploader' => $ret['addon_text'],
|
||||
'$default' => (($ret['default_upload']) ? true : false),
|
||||
'$uploadurl' => $ret['post_url'],
|
||||
'$submit' => t('Submit')
|
||||
'$submit' => t('Upload')
|
||||
|
||||
));
|
||||
|
||||
|
@ -1052,7 +1105,7 @@ class Photos extends \Zotlabs\Web\Controller {
|
|||
}
|
||||
|
||||
$comments = '';
|
||||
if(! count($r)) {
|
||||
if(! $r) {
|
||||
if($observer && ($can_post || $can_comment)) {
|
||||
$commentbox = replace_macros($cmnt_tpl,array(
|
||||
'$return_path' => '',
|
||||
|
|
|
@ -140,7 +140,7 @@ class Ping extends \Zotlabs\Web\Controller {
|
|||
db_utcnow(), db_quoteinterval('3 MINUTE')
|
||||
);
|
||||
|
||||
$discover_tab_on = ((get_config('system','disable_discover_tab') != 1) ? true : false);
|
||||
$discover_tab_on = ((get_config('system','disable_discover_tab') || get_config('system','disable_discover_tab') === false) ? false : true);
|
||||
$notify_pubs = ((local_channel()) ? ($vnotify & VNOTIFY_PUBS) && $discover_tab_on : $discover_tab_on);
|
||||
|
||||
if($notify_pubs) {
|
||||
|
@ -279,8 +279,8 @@ class Ping extends \Zotlabs\Web\Controller {
|
|||
'photo' => $tt['photo'],
|
||||
'when' => relative_date($tt['created']),
|
||||
'hclass' => (($tt['seen']) ? 'notify-seen' : 'notify-unseen'),
|
||||
'b64mid' => $b64mid,
|
||||
'notify_id' => (($tt['otype'] == 'item') ? $tt['id'] : ''),
|
||||
'b64mid' => (($tt['otype'] == 'item') ? $b64mid : 'undefined'),
|
||||
'notify_id' => (($tt['otype'] == 'item') ? $tt['id'] : 'undefined'),
|
||||
'message' => $message
|
||||
);
|
||||
}
|
||||
|
@ -496,7 +496,7 @@ class Ping extends \Zotlabs\Web\Controller {
|
|||
$r = q("SELECT id, item_wall FROM item
|
||||
WHERE item_unseen = 1 and uid = %d
|
||||
$item_normal
|
||||
AND author_xchan != '%s' $sql_extra ",
|
||||
AND author_xchan != '%s'",
|
||||
intval(local_channel()),
|
||||
dbesc($ob_hash)
|
||||
);
|
||||
|
|
|
@ -109,7 +109,7 @@ class Profile extends \Zotlabs\Web\Controller {
|
|||
'title' => 'oembed'
|
||||
]);
|
||||
|
||||
$o .= advanced_profile($a);
|
||||
$o .= advanced_profile();
|
||||
call_hooks('profile_advanced',$o);
|
||||
return $o;
|
||||
|
||||
|
|
|
@ -179,7 +179,10 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||
);
|
||||
}
|
||||
|
||||
profiles_build_sync(local_channel());
|
||||
// set $send to false in profiles_build_sync() to return the data
|
||||
// so that we only send one sync packet.
|
||||
|
||||
$sync_profiles = profiles_build_sync(local_channel(),false);
|
||||
|
||||
// We'll set the updated profile-photo timestamp even if it isn't the default profile,
|
||||
// so that browsers will do a cache update unconditionally
|
||||
|
@ -201,7 +204,7 @@ class Profile_photo extends \Zotlabs\Web\Controller {
|
|||
|
||||
$sync = attach_export_data($channel,$base_image['resource_id']);
|
||||
if($sync)
|
||||
build_sync_packet($channel['channel_id'],array('file' => array($sync)));
|
||||
build_sync_packet($channel['channel_id'],array('file' => array($sync), 'profile' => $sync_profiles));
|
||||
|
||||
|
||||
// Similarly, tell the nav bar to bypass the cache and update the avatar image.
|
||||
|
|
|
@ -162,18 +162,16 @@ class Pubstream extends \Zotlabs\Web\Controller {
|
|||
$net_query2 = (($net) ? " and xchan_network = '" . protect_sprintf(dbesc($net)) . "' " : '');
|
||||
|
||||
|
||||
$simple_update = (($update) ? " and item.item_unseen = 1 " : '');
|
||||
$simple_update = (($_SESSION['loadtime']) ? " AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' " : '');
|
||||
|
||||
if($update && $_SESSION['loadtime'])
|
||||
$simple_update = " AND (( item_unseen = 1 AND item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) OR item.changed > '" . datetime_convert('UTC','UTC',$_SESSION['loadtime']) . "' ) ";
|
||||
if($load)
|
||||
$simple_update = '';
|
||||
|
||||
if($static && $simple_update)
|
||||
$simple_update .= " and item_thread_top = 0 and author_xchan = '" . protect_sprintf(get_observer_hash()) . "' ";
|
||||
$simple_update .= " and author_xchan = '" . protect_sprintf(get_observer_hash()) . "' ";
|
||||
|
||||
//logger('update: ' . $update . ' load: ' . $load);
|
||||
|
||||
|
||||
if($update) {
|
||||
|
||||
$ordering = "commented";
|
||||
|
@ -214,17 +212,18 @@ class Pubstream extends \Zotlabs\Web\Controller {
|
|||
);
|
||||
}
|
||||
else {
|
||||
$r = q("SELECT distinct item.id AS item_id, $ordering FROM item
|
||||
$r = q("SELECT distinct parent AS item_id, $ordering FROM item
|
||||
left join abook on item.author_xchan = abook.abook_xchan
|
||||
$net_query
|
||||
WHERE true $uids $item_normal_update
|
||||
AND item.parent = item.id $simple_update
|
||||
$simple_update
|
||||
and (abook.abook_blocked = 0 or abook.abook_flags is null)
|
||||
$sql_extra3 $sql_extra $sql_nets $net_query2"
|
||||
);
|
||||
}
|
||||
$_SESSION['loadtime'] = datetime_convert();
|
||||
}
|
||||
|
||||
// Then fetch all the children of the parents that are on this page
|
||||
$parents_str = '';
|
||||
$update_unseen = '';
|
||||
|
@ -254,7 +253,7 @@ class Pubstream extends \Zotlabs\Web\Controller {
|
|||
}
|
||||
|
||||
// fake it
|
||||
$mode = ('network');
|
||||
$mode = ('pubstream');
|
||||
|
||||
$o .= conversation($items,$mode,$update,$page_mode);
|
||||
|
||||
|
|
|
@ -6,15 +6,21 @@ namespace Zotlabs\Module;
|
|||
class React extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
if(! local_channel())
|
||||
return;
|
||||
|
||||
$sys = get_sys_channel();
|
||||
$channel = \App::get_channel();
|
||||
|
||||
$postid = $_REQUEST['postid'];
|
||||
|
||||
if(! $postid)
|
||||
return;
|
||||
|
||||
$emoji = $_REQUEST['emoji'];
|
||||
|
||||
|
||||
if($_REQUEST['emoji']) {
|
||||
|
||||
$i = q("select * from item where id = %d and uid = %d",
|
||||
|
@ -22,10 +28,22 @@ class React extends \Zotlabs\Web\Controller {
|
|||
intval(local_channel())
|
||||
);
|
||||
|
||||
if(! $i)
|
||||
return;
|
||||
if(! $i) {
|
||||
$i = q("select * from item where id = %d and uid = %d",
|
||||
intval($postid),
|
||||
intval($sys['channel_id'])
|
||||
);
|
||||
|
||||
if($i) {
|
||||
$i = [ copy_of_pubitem($channel, $i[0]['mid']) ];
|
||||
$postid = (($i) ? $i[0]['id'] : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if(! $i) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = \App::get_channel();
|
||||
|
||||
$n = array();
|
||||
$n['aid'] = $channel['channel_account_id'];
|
||||
|
@ -40,8 +58,7 @@ class React extends \Zotlabs\Web\Controller {
|
|||
|
||||
$x = item_store($n);
|
||||
|
||||
if(local_channel())
|
||||
retain_item($postid);
|
||||
retain_item($postid);
|
||||
|
||||
if($x['success']) {
|
||||
$nid = $x['item_id'];
|
||||
|
|
|
@ -234,7 +234,11 @@ class Register extends \Zotlabs\Web\Controller {
|
|||
if(get_config('system','no_age_restriction'))
|
||||
$label_tos = sprintf( t('I accept the %s for this website'), $toslink);
|
||||
else
|
||||
$label_tos = sprintf( t('I am over 13 years of age and accept the %s for this website'), $toslink);
|
||||
$age = get_config('system','minimum_age');
|
||||
if(!$age) {
|
||||
$age = 13;
|
||||
}
|
||||
$label_tos = sprintf( t('I am over %s years of age and accept the %s for this website'), $age, $toslink);
|
||||
|
||||
$enable_tos = 1 - intval(get_config('system','no_termsofservice'));
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Zotlabs\Module\Settings;
|
||||
|
||||
require_once('include/selectors.php');
|
||||
|
||||
|
||||
class Channel {
|
||||
|
||||
|
@ -148,7 +150,8 @@ class Channel {
|
|||
$defpermcat = ((x($_POST,'defpermcat')) ? notags(trim($_POST['defpermcat'])) : 'default');
|
||||
|
||||
$cal_first_day = (((x($_POST,'first_day')) && (intval($_POST['first_day']) == 1)) ? 1: 0);
|
||||
$mailhost = ((array_key_exists('mailhost',$_POST)) ? notags(trim($_POST['mailhost'])) : '');
|
||||
$mailhost = ((array_key_exists('mailhost',$_POST)) ? notags(trim($_POST['mailhost'])) : '');
|
||||
$profile_assign = ((x($_POST,'profile_assign')) ? notags(trim($_POST['profile_assign'])) : '');
|
||||
|
||||
|
||||
$pageflags = $channel['channel_pageflags'];
|
||||
|
@ -203,7 +206,7 @@ class Channel {
|
|||
$vnotify += intval($_POST['vnotify11']);
|
||||
if(x($_POST,'vnotify12'))
|
||||
$vnotify += intval($_POST['vnotify12']);
|
||||
if(x($_POST,'vnotify13') && (get_config('system', 'disable_discover_tab') != 1))
|
||||
if(x($_POST,'vnotify13'))
|
||||
$vnotify += intval($_POST['vnotify13']);
|
||||
|
||||
$always_show_in_notices = x($_POST,'always_show_in_notices') ? 1 : 0;
|
||||
|
@ -242,6 +245,7 @@ class Channel {
|
|||
set_pconfig(local_channel(),'system','cal_first_day',$cal_first_day);
|
||||
set_pconfig(local_channel(),'system','default_permcat',$defpermcat);
|
||||
set_pconfig(local_channel(),'system','email_notify_host',$mailhost);
|
||||
set_pconfig(local_channel(),'system','profile_assign',$profile_assign);
|
||||
|
||||
$r = q("update channel set channel_name = '%s', channel_pageflags = %d, channel_timezone = '%s', channel_location = '%s', channel_notifyflags = %d, channel_max_anon_mail = %d, channel_max_friend_req = %d, channel_expire_days = %d $set_perms where channel_id = %d",
|
||||
dbesc($username),
|
||||
|
@ -477,6 +481,8 @@ class Channel {
|
|||
$plugin = [ 'basic' => '', 'security' => '', 'notify' => '', 'misc' => '' ];
|
||||
call_hooks('channel_settings',$plugin);
|
||||
|
||||
$disable_discover_tab = get_config('system','disable_discover_tab') || get_config('system','disable_discover_tab') === false;
|
||||
|
||||
$o .= replace_macros($stpl,array(
|
||||
'$ptitle' => t('Channel Settings'),
|
||||
|
||||
|
@ -515,6 +521,9 @@ class Channel {
|
|||
'$permissions' => t('Default Privacy Group'),
|
||||
'$permdesc' => t("\x28click to open/close\x29"),
|
||||
'$aclselect' => populate_acl($perm_defaults, false, \Zotlabs\Lib\PermissionDescription::fromDescription(t('Use my default audience setting for the type of object published'))),
|
||||
'$profseltxt' => t('Profile to assign new connections'),
|
||||
'$profselect' => ((feature_enabled(local_channel(),'multi_profiles')) ? contact_profile_assign(get_pconfig(local_channel(),'system','profile_assign','')) : ''),
|
||||
|
||||
'$allow_cid' => acl2json($perm_defaults['allow_cid']),
|
||||
'$allow_gid' => acl2json($perm_defaults['allow_gid']),
|
||||
'$deny_cid' => acl2json($perm_defaults['deny_cid']),
|
||||
|
@ -563,7 +572,7 @@ class Channel {
|
|||
'$vnotify10' => array('vnotify10', t('New connections'), ($vnotify & VNOTIFY_INTRO), VNOTIFY_INTRO, t('Recommended'), $yes_no),
|
||||
'$vnotify11' => array('vnotify11', t('System Registrations'), ($vnotify & VNOTIFY_REGISTER), VNOTIFY_REGISTER, '', $yes_no),
|
||||
'$vnotify12' => array('vnotify12', t('Unseen shared files'), ($vnotify & VNOTIFY_FILES), VNOTIFY_FILES, '', $yes_no),
|
||||
'$vnotify13' => ((get_config('system', 'disable_discover_tab') != 1) ? array('vnotify13', t('Unseen public activity'), ($vnotify & VNOTIFY_PUBS), VNOTIFY_PUBS, '', $yes_no) : array()),
|
||||
'$vnotify13' => (($disable_discover_tab) ? array() : array('vnotify13', t('Unseen public activity'), ($vnotify & VNOTIFY_PUBS), VNOTIFY_PUBS, '', $yes_no)),
|
||||
'$mailhost' => [ 'mailhost', t('Email notification hub (hostname)'), get_pconfig(local_channel(),'system','email_notify_host',\App::get_hostname()), sprintf( t('If your channel is mirrored to multiple hubs, set this to your preferred location. This will prevent duplicate email notifications. Example: %s'),\App::get_hostname()) ],
|
||||
'$always_show_in_notices' => array('always_show_in_notices', t('Also show new wall posts, private messages and connections under Notices'), $always_show_in_notices, 1, '', $yes_no),
|
||||
|
||||
|
|
|
@ -11,15 +11,17 @@ class Featured {
|
|||
call_hooks('feature_settings_post', $_POST);
|
||||
|
||||
if($_POST['affinity_slider-submit']) {
|
||||
if(intval($_POST['affinity_cmax'])) {
|
||||
set_pconfig(local_channel(),'affinity','cmax',intval($_POST['affinity_cmax']));
|
||||
}
|
||||
if(intval($_POST['affinity_cmin'])) {
|
||||
set_pconfig(local_channel(),'affinity','cmin',intval($_POST['affinity_cmin']));
|
||||
}
|
||||
if(intval($_POST['affinity_cmax']) || intval($_POST['affinity_cmin'])) {
|
||||
info( t('Affinity Slider settings updated.') . EOL);
|
||||
}
|
||||
$cmax = intval($_POST['affinity_cmax']);
|
||||
if($cmax < 0 || $cmax > 99)
|
||||
$cmax = 99;
|
||||
$cmin = intval($_POST['affinity_cmin']);
|
||||
if($cmin < 0 || $cmin > 99)
|
||||
$cmin = 0;
|
||||
set_pconfig(local_channel(),'affinity','cmin',$cmin);
|
||||
set_pconfig(local_channel(),'affinity','cmax',$cmax);
|
||||
|
||||
info( t('Affinity Slider settings updated.') . EOL);
|
||||
|
||||
}
|
||||
|
||||
build_sync_packet();
|
||||
|
@ -40,12 +42,12 @@ class Featured {
|
|||
$cmax = intval(get_pconfig(local_channel(),'affinity','cmax'));
|
||||
$cmax = (($cmax) ? $cmax : 99);
|
||||
$setting_fields .= replace_macros(get_markup_template('field_input.tpl'), array(
|
||||
'$field' => array('affinity_cmax', t('Default maximum affinity level'), $cmax, '')
|
||||
'$field' => array('affinity_cmax', t('Default maximum affinity level'), $cmax, t('0-99 default 99'))
|
||||
));
|
||||
$cmin = intval(get_pconfig(local_channel(),'affinity','cmin'));
|
||||
$cmin = (($cmin) ? $cmin : 0);
|
||||
$setting_fields .= replace_macros(get_markup_template('field_input.tpl'), array(
|
||||
'$field' => array('affinity_cmin', t('Default minimum affinity level'), $cmin, '')
|
||||
'$field' => array('affinity_cmin', t('Default minimum affinity level'), $cmin, t('0-99 - default 0'))
|
||||
));
|
||||
|
||||
$settings_addons .= replace_macros(get_markup_template('generic_addon_settings.tpl'), array(
|
||||
|
|
|
@ -11,10 +11,13 @@ class Subthread extends \Zotlabs\Web\Controller {
|
|||
|
||||
function get() {
|
||||
|
||||
if((! local_channel()) && (! remote_channel())) {
|
||||
if(! local_channel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sys = get_sys_channel();
|
||||
$channel = \App::get_channel();
|
||||
|
||||
$item_id = ((argc() > 2) ? notags(trim(argv(2))) : 0);
|
||||
|
||||
if(argv(1) === 'sub')
|
||||
|
@ -23,10 +26,31 @@ class Subthread extends \Zotlabs\Web\Controller {
|
|||
$activity = ACTIVITY_UNFOLLOW;
|
||||
|
||||
|
||||
$r = q("SELECT parent FROM item WHERE id = '%s'",
|
||||
dbesc($item_id)
|
||||
$i = q("select * from item where id = %d and uid = %d",
|
||||
intval($item_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
||||
if(! $i) {
|
||||
$i = q("select * from item where id = %d and uid = %d",
|
||||
intval($postid),
|
||||
intval($sys['channel_id'])
|
||||
);
|
||||
|
||||
if($i) {
|
||||
$i = [ copy_of_pubitem($channel, $i[0]['mid']) ];
|
||||
$item_id = (($i) ? $i[0]['id'] : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if(! $i) {
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("SELECT parent FROM item WHERE id = %d",
|
||||
intval($item_id)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$r = q("select * from item where id = parent and id = %d limit 1",
|
||||
dbesc($r[0]['parent'])
|
||||
|
|
|
@ -11,10 +11,12 @@ class Tagger extends \Zotlabs\Web\Controller {
|
|||
|
||||
function get() {
|
||||
|
||||
if(! local_channel() && ! remote_channel()) {
|
||||
if(! local_channel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sys = get_sys_channel();
|
||||
|
||||
$observer_hash = get_observer_hash();
|
||||
//strip html-tags
|
||||
$term = notags(trim($_GET['term']));
|
||||
|
@ -26,9 +28,29 @@ class Tagger extends \Zotlabs\Web\Controller {
|
|||
|
||||
logger('tagger: tag ' . $term . ' item ' . $item_id);
|
||||
|
||||
|
||||
$r = q("SELECT * FROM item left join xchan on xchan_hash = author_xchan WHERE id = '%s' and uid = %d LIMIT 1",
|
||||
dbesc($item_id),
|
||||
$r = q("select * from item where id = %d and uid = %d limit 1",
|
||||
intval($item_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
$r = q("select * from item where id = %d and uid = %d limit 1",
|
||||
intval($item_id),
|
||||
intval($sys['channel_id'])
|
||||
);
|
||||
if($r) {
|
||||
$r = [ copy_of_pubitem($channel, $i[0]['mid']) ];
|
||||
$item_id = (($r) ? $r[0]['id'] : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if(! $r) {
|
||||
notice( t('Post not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM item left join xchan on xchan_hash = author_xchan WHERE id = %d and uid = %d LIMIT 1",
|
||||
intval($item_id),
|
||||
intval(local_channel())
|
||||
);
|
||||
|
||||
|
|
43
Zotlabs/Module/Update.php
Normal file
43
Zotlabs/Module/Update.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
|
||||
class Update extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$profile_uid = intval($_GET['p']);
|
||||
|
||||
// it's probably safe to do this for all modules and not just a limited subset,
|
||||
// but it needs to be verified.
|
||||
|
||||
if((! $profile_uid) && in_array(argv(1),['display','search','pubstream','home']))
|
||||
$profile_uid = (-1);
|
||||
|
||||
if(argc() < 2) {
|
||||
killme();
|
||||
}
|
||||
|
||||
// These modules don't have a completely working liveUpdate implementation currently
|
||||
|
||||
if(in_array(strtolower(argv(1)),['articles','cards']))
|
||||
killme();
|
||||
|
||||
$module = "\\Zotlabs\\Module\\" . ucfirst(argv(1));
|
||||
$load = (((argc() > 2) && (argv(2) == 'load')) ? 1 : 0);
|
||||
|
||||
$mod = new $module;
|
||||
|
||||
header("Content-type: text/html");
|
||||
|
||||
\App::$argv = [ argv(1) ];
|
||||
\App::$argc = 1;
|
||||
|
||||
echo "<!DOCTYPE html><html><body><section>\r\n";
|
||||
echo $mod->get($profile_uid, $load);
|
||||
echo "</section></body></html>\r\n";
|
||||
|
||||
killme();
|
||||
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/**
|
||||
* Module: update_profile
|
||||
* Purpose: AJAX synchronisation of profile page
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class Update_cards extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$profile_uid = intval($_GET['p']);
|
||||
$load = (((argc() > 1) && (argv(1) == 'load')) ? 1 : 0);
|
||||
|
||||
header("Content-type: text/html");
|
||||
echo "<!DOCTYPE html><html><body><section></section></body></html>\r\n";
|
||||
|
||||
killme();
|
||||
|
||||
|
||||
$mod = new Cards();
|
||||
|
||||
$text = $mod->get($profile_uid,$load);
|
||||
|
||||
/**
|
||||
* reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well
|
||||
*/
|
||||
|
||||
echo str_replace("\t",' ',$text);
|
||||
echo (($_GET['msie'] == 1) ? '</div>' : '</section>');
|
||||
echo "</body></html>\r\n";
|
||||
killme();
|
||||
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/**
|
||||
* Module: update_profile
|
||||
* Purpose: AJAX synchronisation of profile page
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class Update_channel extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$profile_uid = intval($_GET['p']);
|
||||
$load = (((argc() > 1) && (argv(1) == 'load')) ? 1 : 0);
|
||||
|
||||
header("Content-type: text/html");
|
||||
echo "<!DOCTYPE html><html><body>\r\n";
|
||||
|
||||
/**
|
||||
* We can remove this hack once Internet Explorer recognises HTML5 natively
|
||||
*/
|
||||
|
||||
echo (($_GET['msie'] == 1) ? '<div>' : '<section>');
|
||||
|
||||
/**
|
||||
*
|
||||
* Grab the page inner contents by calling the content function from the profile module directly,
|
||||
* but move any image src attributes to another attribute name. This is because
|
||||
* some browsers will prefetch all the images for the page even if we don't need them.
|
||||
* The only ones we need to fetch are those for new page additions, which we'll discover
|
||||
* on the client side and then swap the image back.
|
||||
*
|
||||
*/
|
||||
|
||||
$mod = new Channel();
|
||||
|
||||
$text = $mod->get($profile_uid,$load);
|
||||
|
||||
$pattern = "/<img([^>]*) src=\"([^\"]*)\"/";
|
||||
$replace = "<img\${1} dst=\"\${2}\"";
|
||||
// $text = preg_replace($pattern, $replace, $text);
|
||||
|
||||
/*
|
||||
if(! $load) {
|
||||
$replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />';
|
||||
$pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well
|
||||
*/
|
||||
|
||||
echo str_replace("\t",' ',$text);
|
||||
echo (($_GET['msie'] == 1) ? '</div>' : '</section>');
|
||||
echo "</body></html>\r\n";
|
||||
killme();
|
||||
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
// See update_profile.php for documentation
|
||||
|
||||
require_once('include/group.php');
|
||||
|
||||
|
||||
class Update_display extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$profile_uid = intval($_GET['p']);
|
||||
if(! $profile_uid)
|
||||
$profile_uid = (-1);
|
||||
$load = (((argc() > 1) && (argv(1) == 'load')) ? 1 : 0);
|
||||
header("Content-type: text/html");
|
||||
echo "<!DOCTYPE html><html><body>\r\n";
|
||||
echo (($_GET['msie'] == 1) ? '<div>' : '<section>');
|
||||
|
||||
$mod = new Display();
|
||||
$text = $mod->get($profile_uid, $load);
|
||||
|
||||
echo str_replace("\t",' ',$text);
|
||||
echo (($_GET['msie'] == 1) ? '</div>' : '</section>');
|
||||
echo "</body></html>\r\n";
|
||||
|
||||
killme();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
// See update_profile.php for documentation
|
||||
|
||||
class Update_home extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$profile_uid = ((intval($_GET['p'])) ? intval($_GET['p']) : (-1));
|
||||
$load = (((argc() > 1) && (argv(1) == 'load')) ? 1 : 0);
|
||||
header("Content-type: text/html");
|
||||
echo "<!DOCTYPE html><html><body>\r\n";
|
||||
echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '<div>' : '<section>');
|
||||
|
||||
$mod = new Home();
|
||||
$text = $mod->get($profile_uid, $load);
|
||||
|
||||
$pattern = "/<img([^>]*) src=\"([^\"]*)\"/";
|
||||
$replace = "<img\${1} dst=\"\${2}\"";
|
||||
// $text = preg_replace($pattern, $replace, $text);
|
||||
/*
|
||||
if(! $load) {
|
||||
$replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />';
|
||||
$pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
}
|
||||
*/
|
||||
echo str_replace("\t",' ',$text);
|
||||
echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '</div>' : '</section>');
|
||||
echo "</body></html>\r\n";
|
||||
// logger('update_home: ' . $text);
|
||||
killme();
|
||||
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
// See update_profile.php for documentation
|
||||
|
||||
require_once('include/group.php');
|
||||
|
||||
class Update_network extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$profile_uid = intval($_GET['p']);
|
||||
$load = (((argc() > 1) && (argv(1) == 'load')) ? 1 : 0);
|
||||
header("Content-type: text/html");
|
||||
echo "<!DOCTYPE html><html><body>\r\n";
|
||||
echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '<div>' : '<section>');
|
||||
|
||||
$mod = new Network();
|
||||
$text = $mod->get($profile_uid, $load);
|
||||
|
||||
$pattern = "/<img([^>]*) src=\"([^\"]*)\"/";
|
||||
$replace = "<img\${1} dst=\"\${2}\"";
|
||||
// $text = preg_replace($pattern, $replace, $text);
|
||||
/*
|
||||
if(! $load) {
|
||||
$replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />';
|
||||
$pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
}
|
||||
*/
|
||||
echo str_replace("\t",' ',$text);
|
||||
echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '</div>' : '</section>');
|
||||
echo "</body></html>\r\n";
|
||||
// logger('update_network: ' . $text);
|
||||
killme();
|
||||
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
// See update_profile.php for documentation
|
||||
|
||||
|
||||
class Update_pubstream extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$profile_uid = ((intval($_GET['p'])) ? intval($_GET['p']) : (-1));
|
||||
$load = (((argc() > 1) && (argv(1) == 'load')) ? 1 : 0);
|
||||
header("Content-type: text/html");
|
||||
echo "<!DOCTYPE html><html><body>\r\n";
|
||||
echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '<div>' : '<section>');
|
||||
|
||||
$mod = new Pubstream();
|
||||
$text = $mod->get($profile_uid, $load);
|
||||
|
||||
$pattern = "/<img([^>]*) src=\"([^\"]*)\"/";
|
||||
$replace = "<img\${1} dst=\"\${2}\"";
|
||||
// $text = preg_replace($pattern, $replace, $text);
|
||||
/*
|
||||
if(! $load) {
|
||||
$replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />';
|
||||
$pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
}
|
||||
*/
|
||||
echo str_replace("\t",' ',$text);
|
||||
echo ((array_key_exists('msie',$_GET) && $_GET['msie'] == 1) ? '</div>' : '</section>');
|
||||
echo "</body></html>\r\n";
|
||||
killme();
|
||||
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
/**
|
||||
* Module: update_profile
|
||||
* Purpose: AJAX synchronisation of search page
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class Update_search extends \Zotlabs\Web\Controller {
|
||||
|
||||
function get() {
|
||||
|
||||
$profile_uid = intval($_GET['p']);
|
||||
if(! $profile_uid)
|
||||
$profile_uid = (-1);
|
||||
|
||||
$load = (((argc() > 1) && (argv(1) == 'load')) ? 1 : 0);
|
||||
|
||||
header("Content-type: text/html");
|
||||
echo "<!DOCTYPE html><html><body>\r\n";
|
||||
|
||||
/**
|
||||
* We can remove this hack once Internet Explorer recognises HTML5 natively
|
||||
*/
|
||||
|
||||
echo (($_GET['msie'] == 1) ? '<div>' : '<section>');
|
||||
|
||||
/**
|
||||
*
|
||||
* Grab the page inner contents by calling the content function from the profile module directly,
|
||||
* but move any image src attributes to another attribute name. This is because
|
||||
* some browsers will prefetch all the images for the page even if we don't need them.
|
||||
* The only ones we need to fetch are those for new page additions, which we'll discover
|
||||
* on the client side and then swap the image back.
|
||||
*
|
||||
*/
|
||||
|
||||
$mod = new Search();
|
||||
$text = $mod->get($profile_uid,$load);
|
||||
|
||||
$pattern = "/<img([^>]*) src=\"([^\"]*)\"/";
|
||||
$replace = "<img\${1} dst=\"\${2}\"";
|
||||
// $text = preg_replace($pattern, $replace, $text);
|
||||
/*
|
||||
if(! $load) {
|
||||
$replace = '<br />' . t('[Embedded content - reload page to view]') . '<br />';
|
||||
$pattern = "/<\s*audio[^>]*>(.*?)<\s*\/\s*audio>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*video[^>]*>(.*?)<\s*\/\s*video>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*embed[^>]*>(.*?)<\s*\/\s*embed>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
$pattern = "/<\s*iframe[^>]*>(.*?)<\s*\/\s*iframe>/i";
|
||||
$text = preg_replace($pattern, $replace, $text);
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* reportedly some versions of MSIE don't handle tabs in XMLHttpRequest documents very well
|
||||
*/
|
||||
|
||||
echo str_replace("\t",' ',$text);
|
||||
echo (($_GET['msie'] == 1) ? '</div>' : '</section>');
|
||||
echo "</body></html>\r\n";
|
||||
killme();
|
||||
|
||||
}
|
||||
}
|
|
@ -41,10 +41,12 @@ class Wall_attach extends \Zotlabs\Web\Controller {
|
|||
$matches = [];
|
||||
$partial = false;
|
||||
|
||||
$x = preg_match('/bytes (\d*)\-(\d*)\/(\d*)/',$_SERVER['HTTP_CONTENT_RANGE'],$matches);
|
||||
if($x) {
|
||||
// logger('Content-Range: ' . print_r($matches,true));
|
||||
$partial = true;
|
||||
if(array_key_exists('HTTP_CONTENT_RANGE',$_SERVER)) {
|
||||
$pm = preg_match('/bytes (\d*)\-(\d*)\/(\d*)/',$_SERVER['HTTP_CONTENT_RANGE'],$matches);
|
||||
if($pm) {
|
||||
// logger('Content-Range: ' . print_r($matches,true));
|
||||
$partial = true;
|
||||
}
|
||||
}
|
||||
|
||||
if($partial) {
|
||||
|
|
|
@ -293,31 +293,43 @@ class Wiki extends \Zotlabs\Web\Controller {
|
|||
$p = Zlib\NativeWikiPage::get_page_content(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName));
|
||||
}
|
||||
if(! ($p && $p['success'])) {
|
||||
$x = new \Zotlabs\Widget\Wiki_pages();
|
||||
|
||||
$html = $x->create_missing_page([
|
||||
'resource_id' => $resource_id,
|
||||
'channel_id' => $owner['channel_id'],
|
||||
'channel_address' => $owner['channel_address'],
|
||||
'refresh' => true
|
||||
]);
|
||||
//json_return_and_die(array('pages' => $page_list_html, 'message' => '', 'success' => true));
|
||||
notice( t('Error retrieving page content') . EOL);
|
||||
goaway(z_root() . '/' . argv(0) . '/' . argv(1) );
|
||||
//goaway(z_root() . '/' . argv(0) . '/' . argv(1) );
|
||||
$renderedContent = Zlib\NativeWikiPage::convert_links($html, argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
|
||||
$showPageControls = $wiki_editor;
|
||||
}
|
||||
else {
|
||||
$mimeType = $p['pageMimeType'];
|
||||
|
||||
$mimeType = $p['pageMimeType'];
|
||||
$sampleContent = (($mimeType == 'text/bbcode') ? '[h3]' . t('New page') . '[/h3]' : '### ' . t('New page'));
|
||||
if($mimeType === 'text/plain')
|
||||
$sampleContent = t('New page');
|
||||
|
||||
$sampleContent = (($mimeType == 'text/bbcode') ? '[h3]' . t('New page') . '[/h3]' : '### ' . t('New page'));
|
||||
if($mimeType === 'text/plain')
|
||||
$sampleContent = t('New page');
|
||||
|
||||
$content = (($p['content'] == '') ? $sampleContent : $p['content']);
|
||||
|
||||
// Render the Markdown-formatted page content in HTML
|
||||
if($mimeType == 'text/bbcode') {
|
||||
$renderedContent = Zlib\NativeWikiPage::convert_links(zidify_links(smilies(bbcode($content))), argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
|
||||
}
|
||||
elseif($mimeType === 'text/plain') {
|
||||
$renderedContent = str_replace(["\n",' ',"\t"],[EOL,' ',' '],htmlentities($content,ENT_COMPAT,'UTF-8',false));
|
||||
}
|
||||
elseif($mimeType === 'text/markdown') {
|
||||
$content = Zlib\MarkdownSoap::unescape($content);
|
||||
$html = Zlib\NativeWikiPage::generate_toc(zidify_text(MarkdownExtra::defaultTransform(Zlib\NativeWikiPage::bbcode($content))));
|
||||
$renderedContent = Zlib\NativeWikiPage::convert_links($html, argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
|
||||
}
|
||||
$showPageControls = $wiki_editor;
|
||||
$content = (($p['content'] == '') ? $sampleContent : $p['content']);
|
||||
|
||||
// Render the Markdown-formatted page content in HTML
|
||||
if($mimeType == 'text/bbcode') {
|
||||
$renderedContent = Zlib\NativeWikiPage::convert_links(zidify_links(smilies(bbcode($content))), argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
|
||||
}
|
||||
elseif($mimeType === 'text/plain') {
|
||||
$renderedContent = str_replace(["\n",' ',"\t"],[EOL,' ',' '],htmlentities($content,ENT_COMPAT,'UTF-8',false));
|
||||
}
|
||||
elseif($mimeType === 'text/markdown') {
|
||||
$content = Zlib\MarkdownSoap::unescape($content);
|
||||
$html = Zlib\NativeWikiPage::generate_toc(zidify_text(MarkdownExtra::defaultTransform(Zlib\NativeWikiPage::bbcode($content))));
|
||||
$renderedContent = Zlib\NativeWikiPage::convert_links($html, argv(0) . '/' . argv(1) . '/' . $wikiUrlName);
|
||||
}
|
||||
$showPageControls = $wiki_editor;
|
||||
}
|
||||
break;
|
||||
// default: // Strip the extraneous URL components
|
||||
// goaway('/' . argv(0) . '/' . argv(1) . '/' . $wikiUrlName . '/' . $pageUrlName);
|
||||
|
@ -430,11 +442,15 @@ class Wiki extends \Zotlabs\Web\Controller {
|
|||
goaway('/' . argv(0) . '/' . $nick . '/');
|
||||
}
|
||||
$wiki = array();
|
||||
|
||||
// backslashes won't work well in the javascript functions
|
||||
$name = str_replace('\\','',$_POST['wikiName']);
|
||||
|
||||
// Generate new wiki info from input name
|
||||
$wiki['postVisible'] = ((intval($_POST['postVisible'])) ? 1 : 0);
|
||||
$wiki['rawName'] = $_POST['wikiName'];
|
||||
$wiki['htmlName'] = escape_tags($_POST['wikiName']);
|
||||
$wiki['urlName'] = urlencode(urlencode($_POST['wikiName']));
|
||||
$wiki['rawName'] = $name;
|
||||
$wiki['htmlName'] = escape_tags($name);
|
||||
$wiki['urlName'] = urlencode(urlencode($name));
|
||||
$wiki['mimeType'] = $_POST['mimeType'];
|
||||
$wiki['typelock'] = $_POST['typelock'];
|
||||
|
||||
|
@ -555,9 +571,14 @@ class Wiki extends \Zotlabs\Web\Controller {
|
|||
}
|
||||
|
||||
$name = $_POST['pageName']; //Get new page name
|
||||
if(urlencode(escape_tags($_POST['pageName'])) === '') {
|
||||
json_return_and_die(array('message' => 'Error creating page. Invalid name.', 'success' => false));
|
||||
|
||||
// backslashes won't work well in the javascript functions
|
||||
$name = str_replace('\\','',$name);
|
||||
|
||||
if(urlencode(escape_tags($name)) === '') {
|
||||
json_return_and_die(array('message' => 'Error creating page. Invalid name (' . print_r($_POST,true) . ').', 'success' => false));
|
||||
}
|
||||
|
||||
$page = Zlib\NativeWikiPage::create_page($owner['channel_id'],$observer_hash, $name, $resource_id, $mimetype);
|
||||
|
||||
if($page['item_id']) {
|
||||
|
@ -626,7 +647,7 @@ class Wiki extends \Zotlabs\Web\Controller {
|
|||
logger('Wiki write permission denied. ' . EOL);
|
||||
json_return_and_die(array('success' => false));
|
||||
}
|
||||
|
||||
|
||||
$saved = Zlib\NativeWikiPage::save_page(array('channel_id' => $owner['channel_id'], 'observer_hash' => $observer_hash, 'resource_id' => $resource_id, 'pageUrlName' => $pageUrlName, 'content' => $content));
|
||||
|
||||
if($saved['success']) {
|
||||
|
@ -758,7 +779,7 @@ class Wiki extends \Zotlabs\Web\Controller {
|
|||
if ((argc() === 4) && (argv(2) === 'rename') && (argv(3) === 'page')) {
|
||||
$resource_id = $_POST['resource_id'];
|
||||
$pageUrlName = $_POST['oldName'];
|
||||
$pageNewName = $_POST['newName'];
|
||||
$pageNewName = str_replace('\\','',$_POST['newName']);
|
||||
if ($pageUrlName === 'Home') {
|
||||
json_return_and_die(array('message' => 'Cannot rename Home','success' => false));
|
||||
}
|
||||
|
|
|
@ -534,7 +534,12 @@ class Comanche {
|
|||
require_once('widget/' . $clsname . '/' . $clsname . '.php');
|
||||
elseif(file_exists('Zotlabs/Widget/' . $clsname . '.php'))
|
||||
require_once('Zotlabs/Widget/' . $clsname . '.php');
|
||||
|
||||
else {
|
||||
$pth = theme_include($clsname . '.php');
|
||||
if($pth) {
|
||||
require_once($pth);
|
||||
}
|
||||
}
|
||||
if(class_exists($nsname)) {
|
||||
$x = new $nsname;
|
||||
$f = 'widget';
|
||||
|
@ -550,11 +555,13 @@ class Comanche {
|
|||
require_once('widget/' . trim($name) . '.php');
|
||||
elseif(file_exists('widget/' . trim($name) . '/' . trim($name) . '.php'))
|
||||
require_once('widget/' . trim($name) . '/' . trim($name) . '.php');
|
||||
}
|
||||
else {
|
||||
$theme_widget = $func . '.php';
|
||||
if((! function_exists($func)) && theme_include($theme_widget))
|
||||
require_once(theme_include($theme_widget));
|
||||
|
||||
if(! function_exists($func)) {
|
||||
$theme_widget = $func . '.php';
|
||||
if(theme_include($theme_widget)) {
|
||||
require_once(theme_include($theme_widget));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(function_exists($func))
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace Zotlabs\Render;
|
||||
|
||||
require_once('library/Smarty/libs/Smarty.class.php');
|
||||
|
||||
class SmartyInterface extends \Smarty {
|
||||
|
||||
public $filename;
|
||||
|
|
|
@ -12,7 +12,7 @@ use Sabre\DAV;
|
|||
*
|
||||
* @extends \\Sabre\\DAV\\Browser\\Plugin
|
||||
*
|
||||
* @link http://github.com/friendica/red
|
||||
* @link http://github.com/redmatrix/hubzilla
|
||||
* @license http://opensource.org/licenses/mit-license.php The MIT License (MIT)
|
||||
*/
|
||||
class Browser extends DAV\Browser\Plugin {
|
||||
|
@ -373,8 +373,6 @@ class Browser extends DAV\Browser\Plugin {
|
|||
if(strpos($path,$special) === 0)
|
||||
$path = trim(substr($path,$count),'/');
|
||||
|
||||
$info = t('Please use DAV to upload large (video, audio) files.<br>See <a class="zrl" href="help/member/member_guide#Cloud_Desktop_Clients">Cloud Desktop Clients</a>');
|
||||
|
||||
|
||||
$output .= replace_macros(get_markup_template('cloud_actionspanel.tpl'), array(
|
||||
'$folder_header' => t('Create new folder'),
|
||||
|
@ -382,7 +380,6 @@ class Browser extends DAV\Browser\Plugin {
|
|||
'$upload_header' => t('Upload file'),
|
||||
'$upload_submit' => t('Upload'),
|
||||
'$quota' => $quota,
|
||||
'$info' => $info,
|
||||
'$channick' => $this->auth->owner_nick,
|
||||
'$aclselect' => $aclselect,
|
||||
'$allow_cid' => acl2json($channel_acl['allow_cid']),
|
||||
|
|
|
@ -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 Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMoveTarget {
|
||||
|
||||
/**
|
||||
* @brief The path inside /cloud
|
||||
|
@ -457,6 +457,22 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function moveInto($targetName,$sourcePath, DAV\INode $sourceNode) {
|
||||
|
||||
if(! $this->auth->owner_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(! ($sourceNode->data && $sourceNode->data->hash)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return attach_move($this->auth->owner_id, $sourceNode->data->hash, $this->folder_hash);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo add description of what this function does.
|
||||
*
|
||||
|
@ -675,7 +691,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
|||
}
|
||||
|
||||
$prefix = '';
|
||||
$suffix = '';
|
||||
$suffix = ' order by is_dir desc, filename asc ';
|
||||
|
||||
$r = q("select $prefix id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, created, edited from attach where folder = '%s' and uid = %d $perms $suffix",
|
||||
dbesc($folder),
|
||||
|
|
|
@ -2,36 +2,54 @@
|
|||
|
||||
namespace Zotlabs\Thumbs;
|
||||
|
||||
require_once('library/epub-meta/epub.php');
|
||||
require_once 'library/epub-meta/epub.php';
|
||||
|
||||
/**
|
||||
* @brief Thumbnail creation for epub files.
|
||||
*
|
||||
*/
|
||||
class Epubthumb {
|
||||
|
||||
/**
|
||||
* @brief Match for application/epub+zip.
|
||||
*
|
||||
* @param string $type MimeType
|
||||
* @return boolean
|
||||
*/
|
||||
function Match($type) {
|
||||
return(($type === 'application/epub+zip') ? true : false );
|
||||
}
|
||||
|
||||
function Thumb($attach,$preview_style,$height = 300, $width = 300) {
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param array $attach
|
||||
* @param number $preview_style unused
|
||||
* @param number $height (optional) default 300
|
||||
* @param number $width (optional) default 300
|
||||
*/
|
||||
function Thumb($attach, $preview_style, $height = 300, $width = 300) {
|
||||
|
||||
$photo = false;
|
||||
|
||||
$ep = new \Epub(dbunescbin($attach['content']));
|
||||
$ep = new \EPub(dbunescbin($attach['content']));
|
||||
$data = $ep->Cover();
|
||||
|
||||
if($data['found']) {
|
||||
$photo = $data['data'];
|
||||
}
|
||||
|
||||
if($photo) {
|
||||
if($photo) {
|
||||
$image = imagecreatefromstring($photo);
|
||||
$dest = imagecreatetruecolor( $width, $height );
|
||||
$srcwidth = imagesx($image);
|
||||
$srcheight = imagesy($image);
|
||||
$dest = imagecreatetruecolor($width, $height);
|
||||
$srcwidth = imagesx($image);
|
||||
$srcheight = imagesy($image);
|
||||
|
||||
imagealphablending($dest, false);
|
||||
imagealphablending($dest, false);
|
||||
imagesavealpha($dest, true);
|
||||
imagecopyresampled($dest, $image, 0, 0, 0, 0, $width, $height, $srcwidth, $srcheight);
|
||||
imagedestroy($image);
|
||||
imagejpeg($dest,dbunescbin($attach['content']) . '.thumb');
|
||||
imagecopyresampled($dest, $image, 0, 0, 0, 0, $width, $height, $srcwidth, $srcheight);
|
||||
imagedestroy($image);
|
||||
imagejpeg($dest, dbunescbin($attach['content']) . '.thumb');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,12 +32,25 @@ class Video {
|
|||
fclose($ostream);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: imagick convert may try to call 'ffmpeg' (or other conversion utilities) under
|
||||
* the covers for this particular operation. If this is not installed or not in the path
|
||||
* for the web server user, errors may be reported in the web server logs.
|
||||
*/
|
||||
|
||||
|
||||
$ffmpeg = trim(shell_exec('which ffmpeg'));
|
||||
if($ffmpeg) {
|
||||
logger('ffmpeg not found in path. Video thumbnails may fail.');
|
||||
}
|
||||
|
||||
$imagick_path = get_config('system','imagick_convert_path');
|
||||
if($imagick_path && @file_exists($imagick_path)) {
|
||||
$cmd = $imagick_path . ' ' . escapeshellarg(PROJECT_BASE . '/' . $tmpfile . '[0]') . ' -thumbnail ' . $width . 'x' . $height . ' ' . escapeshellarg(PROJECT_BASE . '/' . $outfile);
|
||||
// logger('imagick thumbnail command: ' . $cmd);
|
||||
|
||||
exec($cmd);
|
||||
/** @scrutinizer ignore-unhandled */
|
||||
@exec($cmd);
|
||||
|
||||
if(! file_exists($outfile)) {
|
||||
logger('imagick scale failed.');
|
||||
|
@ -46,7 +59,7 @@ class Video {
|
|||
@rename($outfile,$file . '.thumb');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@unlink($tmpfile);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ class HTTPSig {
|
|||
|
||||
logger('verified: ' . $x, LOGGER_DEBUG);
|
||||
|
||||
if($x === false)
|
||||
if(! $x)
|
||||
return $result;
|
||||
|
||||
if(! $spoofable)
|
||||
|
@ -237,7 +237,7 @@ class HTTPSig {
|
|||
$fields = '(request-target)';
|
||||
}
|
||||
|
||||
if(head) {
|
||||
if($head) {
|
||||
foreach($head as $k => $v) {
|
||||
$headers .= strtolower($k) . ': ' . trim($v) . "\n";
|
||||
if($fields)
|
||||
|
|
|
@ -265,7 +265,7 @@ class Router {
|
|||
if(! \App::$error) {
|
||||
$arr = array('content' => \App::$page['content'], 'replace' => false);
|
||||
call_hooks(\App::$module . '_mod_content', $arr);
|
||||
\App::$page['content'] = $arr['content'];
|
||||
|
||||
if(! $arr['replace']) {
|
||||
if($this->controller && method_exists($this->controller,'get')) {
|
||||
$arr = array('content' => $this->controller->get());
|
||||
|
@ -276,8 +276,8 @@ class Router {
|
|||
}
|
||||
}
|
||||
call_hooks(\App::$module . '_mod_aftercontent', $arr);
|
||||
\App::$page['content'] .= $arr['content'];
|
||||
\App::$page['content'] = (($arr['replace']) ? $arr['content'] : \App::$page['content'] . $arr['content']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,15 +9,11 @@ class Affinity {
|
|||
if(! local_channel())
|
||||
return '';
|
||||
|
||||
// Get default cmin value from pconfig, but allow GET parameter to override
|
||||
$cmin = intval(get_pconfig(local_channel(),'affinity','cmin'));
|
||||
$cmin = (($cmin) ? $cmin : 0);
|
||||
$cmin = ((x($_REQUEST,'cmin')) ? intval($_REQUEST['cmin']) : $cmin);
|
||||
|
||||
// Get default cmax value from pconfig, but allow GET parameter to override
|
||||
$cmax = intval(get_pconfig(local_channel(),'affinity','cmax'));
|
||||
$cmax = (($cmax) ? $cmax : 99);
|
||||
$cmax = ((x($_REQUEST,'cmax')) ? intval($_REQUEST['cmax']) : $cmax);
|
||||
$default_cmin = ((feature_enabled(local_channel(),'affinity')) ? get_pconfig(local_channel(),'affinity','cmin',0) : 0);
|
||||
$default_cmax = ((feature_enabled(local_channel(),'affinity')) ? get_pconfig(local_channel(),'affinity','cmax',99) : 99);
|
||||
|
||||
$cmin = ((x($_REQUEST,'cmin')) ? intval($_REQUEST['cmin']) : $default_cmin);
|
||||
$cmax = ((x($_REQUEST,'cmax')) ? intval($_REQUEST['cmax']) : $default_cmax);
|
||||
|
||||
|
||||
if(feature_enabled(local_channel(),'affinity')) {
|
||||
|
|
|
@ -13,8 +13,14 @@ class Categories {
|
|||
if(($cards) && (! feature_enabled(\App::$profile['profile_uid'],'cards')))
|
||||
return '';
|
||||
|
||||
$articles = ((array_key_exists('articles',$arr) && $arr['articles']) ? true : false);
|
||||
|
||||
if(($articles) && (! feature_enabled(\App::$profile['profile_uid'],'articles')))
|
||||
return '';
|
||||
|
||||
|
||||
if((! \App::$profile['profile_uid'])
|
||||
|| (! perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(),(($cards) ? 'view_pages' : 'view_stream')))) {
|
||||
|| (! perm_is_allowed(\App::$profile['profile_uid'],get_observer_hash(),(($cards || $articles) ? 'view_pages' : 'view_stream')))) {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -25,6 +31,8 @@ class Categories {
|
|||
|
||||
if($cards)
|
||||
return cardcategories_widget($srchurl, $cat);
|
||||
elseif($articles)
|
||||
return articlecategories_widget($srchurl, $cat);
|
||||
else
|
||||
return categories_widget($srchurl, $cat);
|
||||
|
||||
|
|
|
@ -63,9 +63,10 @@ class Cdav {
|
|||
|
||||
$sharees = [];
|
||||
$share_displayname = [];
|
||||
|
||||
foreach($invites as $invite) {
|
||||
if(strpos($invite->href, 'mailto:') !== false) {
|
||||
$sharee = channelx_by_hash(substr($invite->href, 7));
|
||||
$sharee = channelx_by_nick(substr($invite->principal, 11));
|
||||
$sharees[] = [
|
||||
'name' => $sharee['channel_name'],
|
||||
'access' => (($invite->access == 3) ? ' (RW)' : ' (R)'),
|
||||
|
@ -173,4 +174,4 @@ class Cdav {
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ class Forums {
|
|||
|
||||
$o = '';
|
||||
|
||||
if(is_array($arr) && array_key_exists('limit',$arr))
|
||||
$limit = " limit " . intval($limit) . " ";
|
||||
if(is_array($arr) && array_key_exists('limit',$arr) && intval($arr['limit']) >= 0)
|
||||
$limit = " limit " . intval($arr['limit']) . " ";
|
||||
else
|
||||
$limit = '';
|
||||
|
||||
|
|
26
Zotlabs/Widget/Hq_controls.php
Normal file
26
Zotlabs/Widget/Hq_controls.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
class Hq_controls {
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
if (! local_channel())
|
||||
return;
|
||||
|
||||
return replace_macros(get_markup_template('hq_controls.tpl'),
|
||||
[
|
||||
'$title' => t('HQ Control Panel'),
|
||||
'$menu' => [
|
||||
'create' => [
|
||||
'label' => t('Create a new post'),
|
||||
'id' => 'jot-toggle',
|
||||
'href' => '#',
|
||||
'class' => ''
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -20,8 +20,10 @@ class Notifications {
|
|||
'label' => t('View your network activity')
|
||||
],
|
||||
'markall' => [
|
||||
'url' => '#',
|
||||
'label' => t('Mark all notifications read')
|
||||
],
|
||||
'filter' => [
|
||||
'label' => t('Show new posts only')
|
||||
]
|
||||
];
|
||||
|
||||
|
@ -36,8 +38,10 @@ class Notifications {
|
|||
'label' => t('View your home activity')
|
||||
],
|
||||
'markall' => [
|
||||
'url' => '#',
|
||||
'label' => t('Mark all notifications seen')
|
||||
],
|
||||
'filter' => [
|
||||
'label' => t('Show new posts only')
|
||||
]
|
||||
];
|
||||
|
||||
|
@ -52,7 +56,6 @@ class Notifications {
|
|||
'label' => t('View your private mails')
|
||||
],
|
||||
'markall' => [
|
||||
'url' => '#',
|
||||
'label' => t('Mark all messages seen')
|
||||
]
|
||||
];
|
||||
|
@ -68,7 +71,6 @@ class Notifications {
|
|||
'label' => t('View events')
|
||||
],
|
||||
'markall' => [
|
||||
'url' => '#',
|
||||
'label' => t('Mark all events seen')
|
||||
]
|
||||
];
|
||||
|
@ -104,7 +106,6 @@ class Notifications {
|
|||
'label' => t('View all notices')
|
||||
],
|
||||
'markall' => [
|
||||
'url' => '#',
|
||||
'label' => t('Mark all notices seen')
|
||||
]
|
||||
];
|
||||
|
@ -132,8 +133,10 @@ class Notifications {
|
|||
'label' => t('View the public stream')
|
||||
],
|
||||
'markall' => [
|
||||
'url' => '#',
|
||||
'label' => t('Mark all notifications seen')
|
||||
],
|
||||
'filter' => [
|
||||
'label' => t('Show new posts only')
|
||||
]
|
||||
];
|
||||
}
|
||||
|
@ -141,7 +144,8 @@ class Notifications {
|
|||
$o = replace_macros(get_markup_template('notifications_widget.tpl'), array(
|
||||
'$module' => \App::$module,
|
||||
'$notifications' => $notifications,
|
||||
'$loading' => t('Loading...')
|
||||
'$no_notifications' => t('Sorry, you have got no notifications at the moment'),
|
||||
'$loading' => t('Loading')
|
||||
));
|
||||
|
||||
return $o;
|
||||
|
|
|
@ -5,6 +5,42 @@ namespace Zotlabs\Widget;
|
|||
|
||||
class Wiki_pages {
|
||||
|
||||
function create_missing_page($arr) {
|
||||
if(argc() < 4)
|
||||
return;
|
||||
|
||||
$c = channelx_by_nick(argv(1));
|
||||
$w = \Zotlabs\Lib\NativeWiki::exists_by_name($c['channel_id'],urldecode(argv(2)));
|
||||
$arr = array(
|
||||
'resource_id' => $w['resource_id'],
|
||||
'channel_id' => $c['channel_id'],
|
||||
'channel_address' => $c['channel_address'],
|
||||
'refresh' => false
|
||||
);
|
||||
|
||||
$can_create = perm_is_allowed(\App::$profile['uid'],get_observer_hash(),'write_wiki');
|
||||
|
||||
$can_delete = ((local_channel() && (local_channel() == \App::$profile['uid'])) ? true : false);
|
||||
$pageName = addslashes(escape_tags(urldecode(argv(3))));
|
||||
|
||||
return replace_macros(get_markup_template('wiki_page_not_found.tpl'), array(
|
||||
'$resource_id' => $arr['resource_id'],
|
||||
'$channel_address' => $arr['channel_address'],
|
||||
'$wikiname' => $wikiname,
|
||||
'$canadd' => $can_create,
|
||||
'$candel' => $can_delete,
|
||||
'$addnew' => t('Add new page'),
|
||||
'$typelock' => $typelock,
|
||||
'$lockedtype' => $w['mimeType'],
|
||||
'$mimetype' => mimetype_select(0,$w['mimeType'],
|
||||
[ 'text/markdown' => t('Markdown'), 'text/bbcode' => t('BBcode'), 'text/plain' => t('Text') ]),
|
||||
'$pageName' => array('missingPageName', 'Create Page' , $pageName),
|
||||
'$refresh' => $arr['refresh'],
|
||||
'$options' => t('Options'),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
}
|
||||
|
||||
function widget($arr) {
|
||||
|
||||
if(argc() < 3)
|
||||
|
|
6
app/articles.apd
Normal file
6
app/articles.apd
Normal file
|
@ -0,0 +1,6 @@
|
|||
version: 1.2
|
||||
url: $baseurl/articles/$nick
|
||||
name: Articles
|
||||
requires: local_channel, articles
|
||||
photo: icon:file-text-o
|
||||
categories: nav_featured_app, Productivity
|
|
@ -3,4 +3,4 @@ url: $baseurl/cards/$nick
|
|||
name: Cards
|
||||
requires: local_channel, cards
|
||||
photo: icon:list
|
||||
categories: Productivity
|
||||
categories: nav_featured_app, Productivity
|
||||
|
|
|
@ -3,4 +3,4 @@ url: $baseurl/webpages/$nick
|
|||
requires: local_channel, webpages
|
||||
name: Webpages
|
||||
photo: icon:newspaper-o
|
||||
categories: Productivity
|
||||
categories: nav_featured_app, Productivity
|
||||
|
|
|
@ -3,4 +3,4 @@ url: $baseurl/wiki/$nick
|
|||
requires: local_channel, wiki
|
||||
name: Wiki
|
||||
photo: icon:pencil-square-o
|
||||
categories: Productivity
|
||||
categories: nav_featured_app, Productivity
|
||||
|
|
10
boot.php
10
boot.php
|
@ -48,9 +48,10 @@ require_once('include/zid.php');
|
|||
require_once('include/xchan.php');
|
||||
require_once('include/hubloc.php');
|
||||
require_once('include/attach.php');
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
define ( 'PLATFORM_NAME', 'hubzilla' );
|
||||
define ( 'STD_VERSION', '2.9.1' );
|
||||
define ( 'STD_VERSION', '3.1.1' );
|
||||
define ( 'ZOT_REVISION', '1.3' );
|
||||
|
||||
define ( 'DB_UPDATE_VERSION', 1198 );
|
||||
|
@ -560,6 +561,7 @@ define ( 'ITEM_BUG', 0x0400); // Is a bug, can be used by the internal bug tr
|
|||
define ( 'ITEM_PENDING_REMOVE', 0x0800); // deleted, notification period has lapsed
|
||||
define ( 'ITEM_DOC', 0x1000); // hubzilla only, define here so that item import does the right thing
|
||||
define ( 'ITEM_CARD', 0x2000);
|
||||
define ( 'ITEM_ARTICLE', 0x4000);
|
||||
|
||||
|
||||
define ( 'ITEM_TYPE_POST', 0 );
|
||||
|
@ -569,6 +571,7 @@ define ( 'ITEM_TYPE_WEBPAGE', 3 );
|
|||
define ( 'ITEM_TYPE_BUG', 4 );
|
||||
define ( 'ITEM_TYPE_DOC', 5 );
|
||||
define ( 'ITEM_TYPE_CARD', 6 );
|
||||
define ( 'ITEM_TYPE_ARTICLE', 7 );
|
||||
|
||||
define ( 'ITEM_IS_STICKY', 1000 );
|
||||
|
||||
|
@ -2007,7 +2010,7 @@ function build_querystring($params, $name = null) {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* @brief Much better way of dealing with c-style args.
|
||||
*/
|
||||
function argc() {
|
||||
|
@ -2028,6 +2031,8 @@ function dba_timer() {
|
|||
/**
|
||||
* @brief Returns xchan_hash from the observer.
|
||||
*
|
||||
* Observer can be a local or remote channel.
|
||||
*
|
||||
* @return string xchan_hash from observer, otherwise empty string if no observer
|
||||
*/
|
||||
function get_observer_hash() {
|
||||
|
@ -2038,7 +2043,6 @@ function get_observer_hash() {
|
|||
return '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns the complete URL of the current page, e.g.: http(s)://something.com/network
|
||||
*
|
||||
|
|
|
@ -36,15 +36,17 @@
|
|||
"league/html-to-markdown": "^4.4",
|
||||
"pear/text_languagedetect": "^1.0",
|
||||
"commerceguys/intl": "~0.7",
|
||||
"lukasreschke/id3parser": "^0.0.1"
|
||||
"lukasreschke/id3parser": "^0.0.1",
|
||||
"smarty/smarty": "~3.1"
|
||||
},
|
||||
"require-dev" : {
|
||||
"php" : ">=7.0",
|
||||
"phpunit/phpunit" : "^6.1",
|
||||
"phpunit/phpunit" : "~6.4.4",
|
||||
"behat/behat" : "@stable",
|
||||
"behat/mink-extension": "@stable",
|
||||
"behat/mink-goutte-driver": "@stable",
|
||||
"php-mock/php-mock-phpunit": "^2.0"
|
||||
"php-mock/php-mock-phpunit": "^2.0",
|
||||
"phpunit/dbunit": "^3.0"
|
||||
},
|
||||
"autoload" : {
|
||||
"psr-4" : {
|
||||
|
|
618
composer.lock
generated
618
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -168,21 +168,19 @@ any time that the documentation is updated :
|
|||
util/importdoc
|
||||
|
||||
### Automated installation via the .homeinstall shell script
|
||||
There is a shell script in (``.homeinstall/hubzilla-setup.sh``) that will install $Projectname and its dependencies on a fresh installation of Debian 8.3 stable (Jessie). It should work on similar Linux systems but your results may vary.
|
||||
There is a shell script in (``.homeinstall/hubzilla-setup.sh``) that will install $Projectname and its dependencies on a fresh installation of Debian 9 stable (Stetch). It should work on similar Linux systems but your results may vary.
|
||||
|
||||
#### Requirements
|
||||
The installation script was originally designed for a small hardware server behind your home router. However, it has been tested on several systems running Debian 8.3:
|
||||
The installation script was originally designed for a small hardware server behind your home router. However, it has been tested on several systems running Debian 9:
|
||||
|
||||
* Home-PC (Debian-8.3.0-amd64)
|
||||
* Home-PC (Debian-9.2-amd64) and Rapberry-Pi 3 (Rasbian = Debian 9.3)
|
||||
|
||||
* Internet connection and router at home
|
||||
* Mini-pc connected to your router
|
||||
* Mini-PC / Raspi connected to your router
|
||||
* USB drive for backups
|
||||
* Fresh installation of Debian on your mini-pc
|
||||
* Router with open ports 80 and 443 for your Debian
|
||||
|
||||
* DigitalOcean droplet (Debian 8.3 x64 / 512 MB Memory / 20 GB Disk / NYC3)
|
||||
|
||||
#### Overview of installation steps
|
||||
1. `apt-get install git`
|
||||
1. `mkdir -p /var/www/html`
|
||||
|
@ -191,8 +189,6 @@ The installation script was originally designed for a small hardware server behi
|
|||
1. `nano .homeinstall/hubzilla-config.txt`
|
||||
1. `cd .homeinstall/`
|
||||
1. `./hubzilla-setup.sh`
|
||||
1. `sed -i "s/^upload_max_filesize =.*/upload_max_filesize = 100M/g" /etc/php5/apache2/php.ini`
|
||||
1. `sed -i "s/^post_max_size =.*/post_max_size = 100M/g" /etc/php5/apache2/php.ini`
|
||||
1. `service apache2 reload`
|
||||
1. Open your domain with a browser and step throught the initial configuration of $Projectname.
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
[h3]Zot API[/h3]
|
||||
|
||||
Many existing social applications and tools can interface directly using the Twitter/StatusNet API, which is available using the 'twitter_api' addon.
|
||||
|
||||
This document describes the native API; which allows direct programmatic access to several internal data structures and libraries extending beyond the basic social interface.
|
||||
|
||||
The API endpoints detailed below are relative to [code]api/z/1.0[/code], meaning that if an API is listed as [code]channel/stream[/code] the full API URL is [code][baseurl]/api/z/1.0/channel/stream[/code].
|
||||
|
||||
[h3]channel/export/basic[/h3]
|
||||
|
|
|
@ -52,6 +52,7 @@ function api_login(&$a){
|
|||
/* Signature authentication */
|
||||
|
||||
if(array_key_exists($head,$_SERVER) && substr(trim($_SERVER[$head]),0,9) === 'Signature') {
|
||||
|
||||
if($head !== 'HTTP_AUTHORIZATION') {
|
||||
$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER[$head];
|
||||
continue;
|
||||
|
@ -59,7 +60,7 @@ function api_login(&$a){
|
|||
|
||||
$sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER[$head]);
|
||||
if($sigblock) {
|
||||
$keyId = $sigblock['keyId'];
|
||||
$keyId = str_replace('acct:','',$sigblock['keyId']);
|
||||
if($keyId) {
|
||||
$r = q("select * from hubloc where hubloc_addr = '%s' limit 1",
|
||||
dbesc($keyId)
|
||||
|
|
|
@ -150,7 +150,11 @@
|
|||
$start = ((array_key_exists('start',$_REQUEST)) ? intval($_REQUEST['start']) : 0);
|
||||
$records = ((array_key_exists('records',$_REQUEST)) ? intval($_REQUEST['records']) : 0);
|
||||
|
||||
$x = attach_list_files(api_user(),get_observer_hash(),$hash,$filename,$filetype,'created asc',$start,$records);
|
||||
$since = ((array_key_exists('since',$_REQUEST)) ? datetime_convert(date_default_timezone_get(),'UTC',$_REQUEST['since']) : NULL_DATE);
|
||||
$until = ((array_key_exists('until',$_REQUEST)) ? datetime_convert(date_default_timezone_get(),'UTC',$_REQUEST['until']) : datetime_convert());
|
||||
|
||||
$x = attach_list_files(api_user(),get_observer_hash(),$hash,$filename,$filetype,'created asc',$start,$records, $since, $until);
|
||||
|
||||
if($start || $records) {
|
||||
$x['start'] = $start;
|
||||
$x['records'] = count($x['results']);
|
||||
|
@ -226,7 +230,10 @@
|
|||
if(! $_REQUEST['file_id'])
|
||||
return false;
|
||||
|
||||
$ret = attach_export_data(api_user(),$_REQUEST['file_id']);
|
||||
$channel = channelx_by_n(api_user());
|
||||
|
||||
$ret = attach_export_data($channel,$_REQUEST['file_id']);
|
||||
|
||||
if($ret) {
|
||||
json_return_and_die($ret);
|
||||
}
|
||||
|
|
|
@ -189,7 +189,7 @@ function attach_count_files($channel_id, $observer, $hash = '', $filename = '',
|
|||
* * \e array|boolean \b results array with results, or false
|
||||
* * \e string \b message with error messages if any
|
||||
*/
|
||||
function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $filetype = '', $orderby = 'created desc', $start = 0, $entries = 0) {
|
||||
function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $filetype = '', $orderby = 'created desc', $start = 0, $entries = 0, $since = '', $until = '') {
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
|
@ -198,6 +198,7 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $
|
|||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
require_once('include/security.php');
|
||||
$sql_extra = permissions_sql($channel_id);
|
||||
|
||||
|
@ -213,14 +214,22 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $
|
|||
if($entries)
|
||||
$limit = " limit " . intval($start) . ", " . intval($entries) . " ";
|
||||
|
||||
// Retrieve all columns except 'data'
|
||||
if(! $since)
|
||||
$since = NULL_DATE;
|
||||
|
||||
if(! $until)
|
||||
$until = datetime_convert();
|
||||
|
||||
$sql_extra .= " and created >= '" . dbesc($since) . "' and created <= '" . dbesc($until) . "' ";
|
||||
|
||||
// Retrieve all columns except 'content'
|
||||
|
||||
$r = q("select id, aid, uid, hash, filename, filetype, filesize, revision, folder, os_path, display_path, os_storage, is_dir, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d $sql_extra ORDER BY $orderby $limit",
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
$ret['success'] = ((is_array($r)) ? true : false);
|
||||
$ret['results'] = ((is_array($r)) ? $r : false);
|
||||
$ret['results'] = ((is_array($r)) ? $r : []);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
@ -276,6 +285,8 @@ function attach_by_hash($hash, $observer_hash, $rev = 0) {
|
|||
return $ret;
|
||||
}
|
||||
|
||||
$r[0]['content'] = dbunescbin($r[0]['content']);
|
||||
|
||||
if($r[0]['folder']) {
|
||||
$x = attach_can_view_folder($r[0]['uid'],$observer_hash,$r[0]['folder']);
|
||||
if(! $x) {
|
||||
|
@ -297,6 +308,11 @@ function attach_can_view_folder($uid,$ob_hash,$folder_hash) {
|
|||
$hash = $folder_hash;
|
||||
$result = false;
|
||||
|
||||
if(! $folder_hash) {
|
||||
return perm_is_allowed($uid,$ob_hash,'view_storage');
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
$r = q("select folder from attach where hash = '%s' and uid = %d $sql_extra",
|
||||
dbesc($hash),
|
||||
|
@ -534,6 +550,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
|||
$type = $f['type'];
|
||||
} else {
|
||||
if(! x($_FILES,'userfile')) {
|
||||
logger('No source file');
|
||||
$ret['message'] = t('No source file.');
|
||||
return $ret;
|
||||
}
|
||||
|
@ -574,6 +591,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
|||
intval($channel_id)
|
||||
);
|
||||
if(! $x) {
|
||||
logger('update file source not found');
|
||||
$ret['message'] = t('Cannot locate file to revise/update');
|
||||
return $ret;
|
||||
}
|
||||
|
@ -715,6 +733,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
|||
$maxfilesize = get_config('system','maxfilesize');
|
||||
|
||||
if(($maxfilesize) && ($filesize > $maxfilesize)) {
|
||||
logger('quota_exceeded');
|
||||
$ret['message'] = sprintf( t('File exceeds size limit of %d'), $maxfilesize);
|
||||
if($remove_when_processed)
|
||||
@unlink($src);
|
||||
|
@ -735,6 +754,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
|||
intval($channel['channel_account_id'])
|
||||
);
|
||||
if(($r) && (($r[0]['total'] + $filesize) > ($limit - $existing_size))) {
|
||||
logger('service_class limit exceeded');
|
||||
$ret['message'] = upgrade_message(true) . sprintf(t("You have reached your limit of %1$.0f Mbytes attachment storage."), $limit / 1024000);
|
||||
if($remove_when_processed)
|
||||
@unlink($src);
|
||||
|
@ -767,8 +787,15 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
|||
$os_path = $os_relpath;
|
||||
$display_path = ltrim($pathname . '/' . $filename,'/');
|
||||
|
||||
if($src)
|
||||
@file_put_contents($os_basepath . $os_relpath,@file_get_contents($src));
|
||||
if($src) {
|
||||
$istream = @fopen($src,'rb');
|
||||
$ostream = @fopen($os_basepath . $os_relpath,'wb');
|
||||
if($istream && $ostream) {
|
||||
pipe_streams($istream,$ostream,65535);
|
||||
fclose($istream);
|
||||
fclose($ostream);
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists('created', $arr))
|
||||
$created = $arr['created'];
|
||||
|
@ -1639,7 +1666,7 @@ function find_filename_by_hash($channel_id, $attachHash) {
|
|||
* @param int $bufsize size of chunk, default 16384
|
||||
* @return number with the size
|
||||
*/
|
||||
function pipe_streams($in, $out, $bufize = 16384) {
|
||||
function pipe_streams($in, $out, $bufsize = 16384) {
|
||||
$size = 0;
|
||||
while (!feof($in))
|
||||
$size += fwrite($out, fread($in, $bufsize));
|
||||
|
@ -2037,6 +2064,7 @@ function attach_export_data($channel, $resource_id, $deleted = false) {
|
|||
if($hash_ptr === $resource_id) {
|
||||
$attach_ptr = $r[0];
|
||||
}
|
||||
$r[0]['content'] = dbunescbin($r[0]['content']);
|
||||
|
||||
$hash_ptr = $r[0]['folder'];
|
||||
$paths[] = $r[0];
|
||||
|
@ -2049,6 +2077,9 @@ function attach_export_data($channel, $resource_id, $deleted = false) {
|
|||
|
||||
|
||||
if($attach_ptr['is_photo']) {
|
||||
|
||||
// This query could potentially result in a few megabytes of data use.
|
||||
|
||||
$r = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale asc",
|
||||
dbesc($resource_id),
|
||||
intval($channel['channel_id'])
|
||||
|
@ -2060,6 +2091,17 @@ function attach_export_data($channel, $resource_id, $deleted = false) {
|
|||
$ret['photo'] = $r;
|
||||
}
|
||||
|
||||
// This query can be used instead in memory starved environments. There will be a corresponding
|
||||
// performance hit during sync because the data will need to be fetched over the network.
|
||||
// $r = q("select aid,uid,xchan,resource_id,created,edited,title,description,album,filename,mimetype,height,width,filesize,imgscale,photo_usage,profile,is_nsfw,os_storage,display_path,photo_flags,allow_cid,allow_gid,deny_cid,deny_gid from photo where resource_id = '%s' and uid = %d order by imgscale asc",
|
||||
// dbesc($resource_id),
|
||||
// intval($channel['channel_id'])
|
||||
// );
|
||||
|
||||
// if($r) {
|
||||
// $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'])
|
||||
|
@ -2222,7 +2264,6 @@ function copy_folder_to_cloudfiles($channel, $observer_hash, $srcpath, $cloudpat
|
|||
* the attach.hash of the new parent folder, which must already exist. If $new_folder_hash is blank or empty,
|
||||
* the file is relocated to the root of the channel's storage area.
|
||||
*
|
||||
* @fixme: this operation is currently not synced to clones !!
|
||||
*
|
||||
* @param int $channel_id
|
||||
* @param int $resource_id
|
||||
|
@ -2232,7 +2273,7 @@ function copy_folder_to_cloudfiles($channel, $observer_hash, $srcpath, $cloudpat
|
|||
function attach_move($channel_id, $resource_id, $new_folder_hash) {
|
||||
|
||||
$c = channelx_by_n($channel_id);
|
||||
if(! $c)
|
||||
if(! ($c && $resource_id))
|
||||
return false;
|
||||
|
||||
$r = q("select * from attach where hash = '%s' and uid = %d limit 1",
|
||||
|
@ -2244,13 +2285,32 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
|
|||
|
||||
$oldstorepath = dbunescbin($r[0]['content']);
|
||||
|
||||
if($r[0]['is_dir']) {
|
||||
$move_success = true;
|
||||
$x = q("select hash from attach where folder = '%s' and uid = %d",
|
||||
dbesc($r[0]['hash']),
|
||||
intval($channel_id)
|
||||
);
|
||||
if($x) {
|
||||
foreach($x as $xv) {
|
||||
$rs = attach_move($channel_id,$xv['hash'],$r[0]['hash']);
|
||||
if(! $rs) {
|
||||
$move_success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $move_success;
|
||||
}
|
||||
|
||||
|
||||
if($new_folder_hash) {
|
||||
$n = q("select * from attach where hash = '%s' and uid = %d limit 1",
|
||||
$n = q("select * from attach where hash = '%s' and uid = %d and is_dir = 1 limit 1",
|
||||
dbesc($new_folder_hash),
|
||||
intval($channel_id)
|
||||
);
|
||||
if(! $n)
|
||||
return;
|
||||
return false;
|
||||
|
||||
$newdirname = $n[0]['filename'];
|
||||
$newstorepath = dbunescbin($n[0]['content']) . '/' . $resource_id;
|
||||
|
@ -2506,7 +2566,7 @@ function save_chunk($channel,$start,$end,$len) {
|
|||
}
|
||||
if(($len - 1) == $end) {
|
||||
unlink($tmp_path);
|
||||
$result['name'] = $_FILES['files']['tmp_name'];
|
||||
$result['name'] = $_FILES['files']['name'];
|
||||
$result['type'] = $_FILES['files']['type'];
|
||||
$result['tmp_name'] = $new_path;
|
||||
$result['error'] = 0;
|
||||
|
|
|
@ -246,8 +246,8 @@ function bb_parse_element($match) {
|
|||
$j = json_decode(base64url_decode($match[1]),true);
|
||||
|
||||
if ($j && local_channel()) {
|
||||
$text = sprintf( t('Install %s element: '), translate_design_element($j['type'])) . $j['pagetitle'];
|
||||
$o = EOL . '<a href="#" onclick="importElement(\'' . $match[1] . '\'); return false;" >' . $text . '</a>' . EOL;
|
||||
$text = sprintf( t('Install %1$s element %2$s'), translate_design_element($j['type']), $j['pagetitle']);
|
||||
$o = EOL . '<button class="btn btn-primary" onclick="importElement(\'' . $match[1] . '\'); return false;" >' . $text . '</button>' . EOL;
|
||||
}
|
||||
else {
|
||||
$text = sprintf( t('This post contains an installable %s element, however you lack permissions to install it on this site.' ), translate_design_element($j['type'])) . $j['pagetitle'];
|
||||
|
@ -329,6 +329,8 @@ function bb_ShareAttributes($match) {
|
|||
|
||||
if(strpos($link,'/cards/'))
|
||||
$type = t('card');
|
||||
elseif(strpos($link,'/articles/'))
|
||||
$type = t('article');
|
||||
else
|
||||
$type = t('post');
|
||||
|
||||
|
@ -426,6 +428,16 @@ function bb_spoilertag($match) {
|
|||
return '<div onclick="openClose(\'opendiv-' . $rnd . '\'); return false;" class="fakelink">' . $openclose . '</div><blockquote id="opendiv-' . $rnd . '" style="display: none;">' . $text . '</blockquote>';
|
||||
}
|
||||
|
||||
function bb_summary($match) {
|
||||
$rnd1 = mt_rand();
|
||||
$rnd2 = mt_rand();
|
||||
$rnd3 = mt_rand();
|
||||
$rnd4 = mt_rand();
|
||||
|
||||
return $match[1] . '<div style="display: block;" id="opendiv-' . $rnd2 . '">' . $match[2] . '</div><div style="display: block;" id="opendiv-' . $rnd3 . '" onclick="openClose(\'opendiv-' . $rnd1 . '\'); openClose(\'opendiv-' . $rnd2 . '\'); openClose(\'opendiv-' . $rnd3 . '\'); openClose(\'opendiv-' . $rnd4 . '\'); return false;" class="fakelink">' . t('View article') . '</div><div style="display: none;" id="opendiv-' . $rnd4 . '" onclick="openClose(\'opendiv-' . $rnd1 . '\'); openClose(\'opendiv-' . $rnd2 . '\'); openClose(\'opendiv-' . $rnd3 . '\'); openClose(\'opendiv-' . $rnd4 . '\'); return false;" class="fakelink">' . t('View summary') . '</div><div id="opendiv-' . $rnd1 . '" style="display: none;">' . $match[3] . '</div>';
|
||||
}
|
||||
|
||||
|
||||
function bb_definitionList($match) {
|
||||
// $match[1] is the markup styles for the "terms" in the definition list.
|
||||
// $match[2] is the content between the [dl]...[/dl] tags
|
||||
|
@ -705,10 +717,12 @@ function parseIdentityAwareHTML($Text) {
|
|||
return $Text;
|
||||
}
|
||||
|
||||
// BBcode 2 HTML was written by WAY2WEB.net
|
||||
// extended to work with Mistpark/Friendica/Redmatrix/Hubzilla - Mike Macgirvin
|
||||
|
||||
function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false) {
|
||||
function bbcode($Text, $options = []) {
|
||||
|
||||
$preserve_nl = ((array_key_exists('preserve_nl',$options)) ? $options['preserve_nl'] : false);
|
||||
$tryoembed = ((array_key_exists('tryoembed',$options)) ? $options['tryoembed'] : true);
|
||||
$cache = ((array_key_exists('cache',$options)) ? $options['cache'] : false);
|
||||
|
||||
|
||||
call_hooks('bbcode_filter', $Text);
|
||||
|
@ -937,27 +951,34 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
|
|||
// Check for h1
|
||||
if (strpos($Text,'[h1]') !== false) {
|
||||
$Text = preg_replace("(\[h1\](.*?)\[\/h1\])ism",'<h1>$1</h1>',$Text);
|
||||
$Text = str_replace('</h1><br />', '</h1>', $Text);
|
||||
}
|
||||
// Check for h2
|
||||
if (strpos($Text,'[h2]') !== false) {
|
||||
$Text = preg_replace("(\[h2\](.*?)\[\/h2\])ism",'<h2>$1</h2>',$Text);
|
||||
$Text = str_replace('</h2><br />', '</h2>', $Text);
|
||||
}
|
||||
// Check for h3
|
||||
if (strpos($Text,'[h3]') !== false) {
|
||||
$Text = preg_replace("(\[h3\](.*?)\[\/h3\])ism",'<h3>$1</h3>',$Text);
|
||||
$Text = str_replace('</h3><br />', '</h3>', $Text);
|
||||
}
|
||||
// Check for h4
|
||||
if (strpos($Text,'[h4]') !== false) {
|
||||
$Text = preg_replace("(\[h4\](.*?)\[\/h4\])ism",'<h4>$1</h4>',$Text);
|
||||
$Text = str_replace('</h4><br />', '</h4>', $Text);
|
||||
}
|
||||
// Check for h5
|
||||
if (strpos($Text,'[h5]') !== false) {
|
||||
$Text = preg_replace("(\[h5\](.*?)\[\/h5\])ism",'<h5>$1</h5>',$Text);
|
||||
$Text = str_replace('</h5><br />', '</h5>', $Text);
|
||||
}
|
||||
// Check for h6
|
||||
if (strpos($Text,'[h6]') !== false) {
|
||||
$Text = preg_replace("(\[h6\](.*?)\[\/h6\])ism",'<h6>$1</h6>',$Text);
|
||||
$Text = str_replace('</h6><br />', '</h6>', $Text);
|
||||
}
|
||||
|
||||
// Check for table of content without params
|
||||
while(strpos($Text,'[toc]') !== false) {
|
||||
$toc_id = 'toc-' . random_string(10);
|
||||
|
@ -1051,6 +1072,11 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
|
|||
$Text = preg_replace_callback("/\[code(.*?)\](.*?)\[\/code\]/ism", 'bb_code_options', $Text);
|
||||
}
|
||||
|
||||
|
||||
if(strpos($Text,'[/summary]') !== false) {
|
||||
$Text = preg_replace_callback("/^(.*?)\[summary\](.*?)\[\/summary\](.*?)$/ism", 'bb_summary', $Text);
|
||||
}
|
||||
|
||||
// Check for [spoiler] text
|
||||
$endlessloop = 0;
|
||||
while ((strpos($Text, "[/spoiler]")!== false) and (strpos($Text, "[spoiler]") !== false) and (++$endlessloop < 20)) {
|
||||
|
|
|
@ -325,7 +325,7 @@ function create_identity($arr) {
|
|||
'hubloc_guid_sig' => $sig,
|
||||
'hubloc_hash' => $hash,
|
||||
'hubloc_addr' => channel_reddress($ret['channel']),
|
||||
'hubloc_primary' => $primary,
|
||||
'hubloc_primary' => intval($primary),
|
||||
'hubloc_url' => z_root(),
|
||||
'hubloc_url_sig' => base64url_encode(rsa_sign(z_root(),$ret['channel']['channel_prvkey'])),
|
||||
'hubloc_host' => App::get_hostname(),
|
||||
|
@ -1490,7 +1490,7 @@ function gender_icon($gender) {
|
|||
}
|
||||
|
||||
|
||||
function advanced_profile(&$a) {
|
||||
function advanced_profile() {
|
||||
require_once('include/text.php');
|
||||
if(! perm_is_allowed(App::$profile['profile_uid'],get_observer_hash(),'view_profile'))
|
||||
return '';
|
||||
|
@ -1982,12 +1982,17 @@ function get_channel_default_perms($uid) {
|
|||
}
|
||||
|
||||
|
||||
function profiles_build_sync($channel_id) {
|
||||
function profiles_build_sync($channel_id,$send = true) {
|
||||
$r = q("select * from profile where uid = %d",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($r) {
|
||||
build_sync_packet($channel_id,array('profile' => $r));
|
||||
if($send) {
|
||||
build_sync_packet($channel_id,array('profile' => $r));
|
||||
}
|
||||
else {
|
||||
return $r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,21 +72,22 @@ function categories_widget($baseurl,$selected = '') {
|
|||
$item_normal = item_normal();
|
||||
|
||||
$terms = array();
|
||||
$r = q("select distinct(term.term)
|
||||
from term join item on term.oid = item.id
|
||||
where item.uid = %d
|
||||
and term.uid = item.uid
|
||||
and term.ttype = %d
|
||||
and term.otype = %d
|
||||
and item.owner_xchan = '%s'
|
||||
and item.item_wall = 1
|
||||
$item_normal
|
||||
$sql_extra
|
||||
order by term.term asc",
|
||||
$r = q("select distinct(term.term) from term join item on term.oid = item.id
|
||||
where item.uid = %d
|
||||
and term.uid = item.uid
|
||||
and term.ttype = %d
|
||||
and term.otype = %d
|
||||
and item.owner_xchan = '%s'
|
||||
and item.item_wall = 1
|
||||
and item.verb != '%s'
|
||||
$item_normal
|
||||
$sql_extra
|
||||
order by term.term asc",
|
||||
intval(App::$profile['profile_uid']),
|
||||
intval(TERM_CATEGORY),
|
||||
intval(TERM_OBJ_POST),
|
||||
dbesc(App::$profile['channel_hash'])
|
||||
intval(TERM_CATEGORY),
|
||||
intval(TERM_OBJ_POST),
|
||||
dbesc(App::$profile['channel_hash']),
|
||||
dbesc(ACTIVITY_UPDATE)
|
||||
);
|
||||
if($r && count($r)) {
|
||||
foreach($r as $rr)
|
||||
|
@ -118,19 +119,19 @@ function cardcategories_widget($baseurl,$selected = '') {
|
|||
|
||||
$terms = array();
|
||||
$r = q("select distinct(term.term)
|
||||
from term join item on term.oid = item.id
|
||||
where item.uid = %d
|
||||
and term.uid = item.uid
|
||||
and term.ttype = %d
|
||||
from term join item on term.oid = item.id
|
||||
where item.uid = %d
|
||||
and term.uid = item.uid
|
||||
and term.ttype = %d
|
||||
and term.otype = %d
|
||||
and item.owner_xchan = '%s'
|
||||
and item.owner_xchan = '%s'
|
||||
$item_normal
|
||||
$sql_extra
|
||||
order by term.term asc",
|
||||
order by term.term asc",
|
||||
intval(App::$profile['profile_uid']),
|
||||
intval(TERM_CATEGORY),
|
||||
intval(TERM_CATEGORY),
|
||||
intval(TERM_OBJ_POST),
|
||||
dbesc(App::$profile['channel_hash'])
|
||||
dbesc(App::$profile['channel_hash'])
|
||||
);
|
||||
if($r && count($r)) {
|
||||
foreach($r as $rr)
|
||||
|
@ -150,6 +151,54 @@ function cardcategories_widget($baseurl,$selected = '') {
|
|||
}
|
||||
|
||||
|
||||
function articlecategories_widget($baseurl,$selected = '') {
|
||||
|
||||
if(! feature_enabled(App::$profile['profile_uid'],'categories'))
|
||||
return '';
|
||||
|
||||
$sql_extra = item_permissions_sql(App::$profile['profile_uid']);
|
||||
|
||||
$item_normal = "and item.item_hidden = 0 and item.item_type = 7 and item.item_deleted = 0
|
||||
and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_pending_remove = 0
|
||||
and item.item_blocked = 0 ";
|
||||
|
||||
$terms = array();
|
||||
$r = q("select distinct(term.term)
|
||||
from term join item on term.oid = item.id
|
||||
where item.uid = %d
|
||||
and term.uid = item.uid
|
||||
and term.ttype = %d
|
||||
and term.otype = %d
|
||||
and item.owner_xchan = '%s'
|
||||
$item_normal
|
||||
$sql_extra
|
||||
order by term.term asc",
|
||||
intval(App::$profile['profile_uid']),
|
||||
intval(TERM_CATEGORY),
|
||||
intval(TERM_OBJ_POST),
|
||||
dbesc(App::$profile['channel_hash'])
|
||||
);
|
||||
if($r && count($r)) {
|
||||
foreach($r as $rr)
|
||||
$terms[] = array('name' => $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : ''));
|
||||
|
||||
return replace_macros(get_markup_template('categories_widget.tpl'),array(
|
||||
'$title' => t('Categories'),
|
||||
'$desc' => '',
|
||||
'$sel_all' => (($selected == '') ? 'selected' : ''),
|
||||
'$all' => t('Everything'),
|
||||
'$terms' => $terms,
|
||||
'$base' => $baseurl,
|
||||
|
||||
));
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function common_friends_visitor_widget($profile_uid,$cnt = 25) {
|
||||
|
||||
|
|
|
@ -482,10 +482,10 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
$previewing = (($preview) ? ' preview ' : '');
|
||||
$preview_lbl = t('This is an unsaved preview');
|
||||
|
||||
if ($mode === 'network') {
|
||||
if (in_array($mode, [ 'network', 'pubstream'])) {
|
||||
|
||||
$profile_owner = local_channel();
|
||||
$page_writeable = true;
|
||||
$page_writeable = ((local_channel()) ? true : false);
|
||||
|
||||
if (!$update) {
|
||||
// The special div is needed for liveUpdate to kick in for this page.
|
||||
|
@ -513,6 +513,12 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
}
|
||||
}
|
||||
|
||||
elseif ($mode === 'hq') {
|
||||
$profile_owner = local_channel();
|
||||
$page_writeable = true;
|
||||
$live_update_div = '<div id="live-hq"></div>' . "\r\n";
|
||||
}
|
||||
|
||||
elseif ($mode === 'channel') {
|
||||
$profile_owner = App::$profile['profile_uid'];
|
||||
$page_writeable = ($profile_owner == local_channel());
|
||||
|
@ -539,6 +545,15 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
$jsreload = $_SESSION['return_url'];
|
||||
}
|
||||
|
||||
elseif ($mode === 'articles') {
|
||||
$profile_owner = App::$profile['profile_uid'];
|
||||
$page_writeable = ($profile_owner == local_channel());
|
||||
$live_update_div = '<div id="live-articles"></div>' . "\r\n"
|
||||
. "<script> var profile_uid = " . App::$profile['profile_uid']
|
||||
. "; var netargs = '?f='; var profile_page = " . App::$pager['page'] . "; </script>\r\n";
|
||||
$jsreload = $_SESSION['return_url'];
|
||||
}
|
||||
|
||||
|
||||
elseif ($mode === 'display') {
|
||||
$profile_owner = local_channel();
|
||||
|
@ -619,13 +634,14 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
// "New Item View" on network page or search page results
|
||||
// - just loop through the items and format them minimally for display
|
||||
|
||||
|
||||
//$tpl = get_markup_template('search_item.tpl');
|
||||
$tpl = 'search_item.tpl';
|
||||
|
||||
foreach($items as $item) {
|
||||
|
||||
$x = [ 'mode' => $mode, 'item' => $item ];
|
||||
$x = [
|
||||
'mode' => $mode,
|
||||
'item' => $item
|
||||
];
|
||||
call_hooks('stream_item',$x);
|
||||
|
||||
if($x['item']['blocked'])
|
||||
|
@ -646,14 +662,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
if(((activity_match($item['verb'],ACTIVITY_LIKE)) || (activity_match($item['verb'],ACTIVITY_DISLIKE)))
|
||||
&& ($item['id'] != $item['parent']))
|
||||
continue;
|
||||
// $nickname = $item['nickname'];
|
||||
}
|
||||
// else
|
||||
// $nickname = App::$user['nickname'];
|
||||
|
||||
// $profile_name = ((strlen($item['author-name'])) ? $item['author-name'] : $item['name']);
|
||||
// if($item['author-link'] && (! $item['author-name']))
|
||||
// $profile_name = $item['author-link'];
|
||||
|
||||
$sp = false;
|
||||
$profile_link = best_link_url($item,$sp);
|
||||
|
@ -662,8 +671,6 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
else
|
||||
$profile_link = zid($profile_link);
|
||||
|
||||
// $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']);
|
||||
|
||||
$profile_name = $item['author']['xchan_name'];
|
||||
$profile_link = $item['author']['xchan_url'];
|
||||
$profile_avatar = $item['author']['xchan_photo_m'];
|
||||
|
@ -714,7 +721,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
|
||||
$conv_link_mid = (($mode == 'moderate') ? $item['parent_mid'] : $item['mid']);
|
||||
|
||||
$conv_link = (($item['item_type'] == ITEM_TYPE_CARD) ? $item['plink'] : z_root() . '/display/' . gen_link_id($conv_link_mid));
|
||||
$conv_link = ((in_array($item['item_type'],[ ITEM_TYPE_CARD, ITEM_TYPE_ARTICLE] )) ? $item['plink'] : z_root() . '/display/' . gen_link_id($conv_link_mid));
|
||||
|
||||
|
||||
$tmp_item = array(
|
||||
|
@ -748,8 +755,8 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
'forged' => $forged,
|
||||
'txt_cats' => t('Categories:'),
|
||||
'txt_folders' => t('Filed under:'),
|
||||
'has_cats' => ((count($body['categories'])) ? 'true' : ''),
|
||||
'has_folders' => ((count($body['folders'])) ? 'true' : ''),
|
||||
'has_cats' => (($body['categories']) ? 'true' : ''),
|
||||
'has_folders' => (($body['folders']) ? 'true' : ''),
|
||||
'text' => strip_tags($body['html']),
|
||||
'ago' => relative_date($item['created']),
|
||||
'app' => $item['app'],
|
||||
|
@ -759,6 +766,7 @@ function conversation($items, $mode, $update, $page_mode = 'traditional', $prepa
|
|||
'editedtime' => (($item['edited'] != $item['created']) ? sprintf( t('last edited: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['edited'], 'r')) : ''),
|
||||
'expiretime' => (($item['expires'] > NULL_DATE) ? sprintf( t('Expires: %s'), datetime_convert('UTC', date_default_timezone_get(), $item['expires'], 'r')):''),
|
||||
'location' => $location,
|
||||
'divider' => false,
|
||||
'indent' => '',
|
||||
'owner_name' => $owner_name,
|
||||
'owner_url' => $owner_url,
|
||||
|
@ -1465,7 +1473,7 @@ function sort_item_children($items) {
|
|||
$result = $items;
|
||||
usort($result,'sort_thr_created_rev');
|
||||
foreach($result as $k => $i) {
|
||||
if(count($result[$k]['children'])) {
|
||||
if($result[$k]['children']) {
|
||||
$result[$k]['children'] = sort_item_children($result[$k]['children']);
|
||||
}
|
||||
}
|
||||
|
@ -1475,7 +1483,7 @@ function sort_item_children($items) {
|
|||
function add_children_to_list($children, &$arr) {
|
||||
foreach($children as $y) {
|
||||
$arr[] = $y;
|
||||
if(count($y['children']))
|
||||
if($y['children'])
|
||||
add_children_to_list($y['children'], $arr);
|
||||
}
|
||||
}
|
||||
|
@ -1887,6 +1895,17 @@ function profile_tabs($a, $is_owner = false, $nickname = null){
|
|||
'icon' => 'list'
|
||||
);
|
||||
}
|
||||
|
||||
if(feature_enabled($uid,'articles')) {
|
||||
$tabs[] = array(
|
||||
'label' => t('articles'),
|
||||
'url' => z_root() . '/articles/' . $nickname,
|
||||
'sel' => ((argv(0) == 'articles') ? 'active' : ''),
|
||||
'title' => t('View Articles'),
|
||||
'id' => 'articles-tab',
|
||||
'icon' => 'file-text-o'
|
||||
);
|
||||
}
|
||||
|
||||
if($has_webpages && feature_enabled($uid,'webpages')) {
|
||||
$tabs[] = array(
|
||||
|
|
|
@ -22,13 +22,13 @@ function rsa_verify($data,$sig,$key,$alg = 'sha256') {
|
|||
$alg = OPENSSL_ALGO_SHA256;
|
||||
$verify = @openssl_verify($data,$sig,$key,$alg);
|
||||
|
||||
if(! $verify) {
|
||||
if($verify === (-1)) {
|
||||
while($msg = openssl_error_string())
|
||||
logger('openssl_verify: ' . $msg,LOGGER_NORMAL,LOG_ERR);
|
||||
btlogger('openssl_verify: key: ' . $key, LOGGER_DEBUG, LOG_ERR);
|
||||
}
|
||||
|
||||
return $verify;
|
||||
return (($verify > 0) ? true : false);
|
||||
}
|
||||
|
||||
function pkcs5_pad ($text, $blocksize)
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
use Sabre\VObject;
|
||||
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
/**
|
||||
* @brief Returns an event as HTML.
|
||||
*
|
||||
|
@ -14,7 +16,6 @@ use Sabre\VObject;
|
|||
*/
|
||||
function format_event_html($ev) {
|
||||
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
if(! ((is_array($ev)) && count($ev)))
|
||||
return '';
|
||||
|
@ -192,7 +193,7 @@ function format_todo_ical($ev) {
|
|||
|
||||
|
||||
function format_ical_text($s) {
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
require_once('include/html2plain.php');
|
||||
|
||||
$s = html2plain(bbcode($s));
|
||||
|
@ -983,7 +984,6 @@ function event_store_item($arr, $event) {
|
|||
|
||||
require_once('include/datetime.php');
|
||||
require_once('include/items.php');
|
||||
require_once('include/bbcode.php');
|
||||
|
||||
$item = null;
|
||||
|
||||
|
|
|
@ -126,6 +126,16 @@ function get_features($filtered = true) {
|
|||
feature_level('cards',1),
|
||||
],
|
||||
|
||||
|
||||
[
|
||||
'articles',
|
||||
t('Articles'),
|
||||
t('Create interactive articles'),
|
||||
false,
|
||||
get_config('feature_lock','articles'),
|
||||
feature_level('articles',1),
|
||||
],
|
||||
|
||||
[
|
||||
'nav_channel_select',
|
||||
t('Navigation Channel Select'),
|
||||
|
@ -363,15 +373,6 @@ function get_features($filtered = true) {
|
|||
|
||||
t('Post/Comment Tools'),
|
||||
|
||||
[
|
||||
'markdown',
|
||||
t('Markdown'),
|
||||
t('Use markdown for editing posts'),
|
||||
false,
|
||||
get_config('feature_lock','markdown'),
|
||||
feature_level('markdown',2),
|
||||
],
|
||||
|
||||
[
|
||||
'commtag',
|
||||
t('Community Tagging'),
|
||||
|
@ -480,6 +481,8 @@ function get_features($filtered = true) {
|
|||
else {
|
||||
$narr = $arr;
|
||||
}
|
||||
call_hooks('get_features',$narr);
|
||||
return $narr;
|
||||
|
||||
$x = [ 'features' => $narr, 'filtered' => $filtered, 'techlevel' => $techlevel ];
|
||||
call_hooks('get_features',$x);
|
||||
return $x['features'];
|
||||
}
|
||||
|
|
|
@ -65,16 +65,35 @@ function get_feed_for($channel, $observer_hash, $params) {
|
|||
if(! $channel)
|
||||
http_status_exit(401);
|
||||
|
||||
if($params['pages']) {
|
||||
if(! perm_is_allowed($channel['channel_id'],$observer_hash,'view_pages'))
|
||||
http_status_exit(403);
|
||||
} else {
|
||||
if(! perm_is_allowed($channel['channel_id'],$observer_hash,'view_stream'))
|
||||
http_status_exit(403);
|
||||
}
|
||||
|
||||
// logger('params: ' . print_r($params,true));
|
||||
|
||||
|
||||
$interactive = ((is_array($params) && array_key_exists('interactive',$params)) ? intval($params['interactive']) : 0);
|
||||
|
||||
|
||||
if($params['pages']) {
|
||||
if(! perm_is_allowed($channel['channel_id'],$observer_hash,'view_pages')) {
|
||||
if($interactive) {
|
||||
return '';
|
||||
}
|
||||
else {
|
||||
http_status_exit(403);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(! perm_is_allowed($channel['channel_id'],$observer_hash,'view_stream')) {
|
||||
if($interactive) {
|
||||
return '';
|
||||
}
|
||||
else {
|
||||
http_status_exit(403);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$feed_template = get_markup_template('atom_feed.tpl');
|
||||
|
||||
$atom = '';
|
||||
|
@ -1286,7 +1305,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
|||
|
||||
// allow likes of comments
|
||||
|
||||
if($item_parent_mid && activity_match($datarray['verb'],ACTVITY_LIKE)) {
|
||||
if($item_parent_mid && activity_match($datarray['verb'],ACTIVITY_LIKE)) {
|
||||
$datarray['thr_parent'] = $item_parent_mid[0]['parent_mid'];
|
||||
}
|
||||
|
||||
|
@ -1782,12 +1801,17 @@ function compat_photos_list($s) {
|
|||
|
||||
if($found) {
|
||||
foreach($matches as $match) {
|
||||
$ret[] = [
|
||||
$entry = [
|
||||
'href' => $match[2],
|
||||
'length' => 0,
|
||||
'type' => guess_image_type($match[2])
|
||||
];
|
||||
$sizer = new \Zotlabs\Lib\Img_filesize($match[2]);
|
||||
$size = $sizer->getSize();
|
||||
if(intval($size)) {
|
||||
$entry['length'] = intval($size);
|
||||
}
|
||||
|
||||
$ret[] = $entry;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -226,6 +226,8 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
|
|||
|
||||
}
|
||||
|
||||
$profile_assign = get_pconfig($uid,'system','profile_assign','');
|
||||
|
||||
|
||||
$r = q("select abook_id, abook_xchan, abook_pending, abook_instance from abook
|
||||
where abook_xchan = '%s' and abook_channel = %d limit 1",
|
||||
|
@ -265,6 +267,7 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false)
|
|||
'abook_channel' => intval($uid),
|
||||
'abook_closeness' => intval($closeness),
|
||||
'abook_xchan' => $xchan_hash,
|
||||
'abook_profile' => $profile_assign,
|
||||
'abook_feed' => intval(($xchan['xchan_network'] === 'rss') ? 1 : 0),
|
||||
'abook_created' => datetime_convert(),
|
||||
'abook_updated' => datetime_convert(),
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue