Merge remote branch 'upstream/master'
This commit is contained in:
commit
cf58122b29
2
boot.php
2
boot.php
@ -48,7 +48,7 @@ define ( 'RED_PLATFORM', 'redmatrix' );
|
||||
define ( 'RED_VERSION', trim(file_get_contents('version.inc')) . 'R');
|
||||
define ( 'ZOT_REVISION', 1 );
|
||||
|
||||
define ( 'DB_UPDATE_VERSION', 1129 );
|
||||
define ( 'DB_UPDATE_VERSION', 1130 );
|
||||
|
||||
define ( 'EOL', '<br />' . "\r\n" );
|
||||
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
|
||||
|
@ -98,3 +98,6 @@ This document assumes you're an administrator.
|
||||
Logfile to use for logging auth errors. Used to plug in to server
|
||||
side software such as fail2ban. Auth failures are still logged to
|
||||
the main logs as well.
|
||||
[b]system > hide_in_statistics[/b]
|
||||
Tell the red statistics servers to completely hide this hub in hub lists.
|
||||
|
@ -55,7 +55,7 @@ server {
|
||||
ssl_certificate /etc/nginx/ssl/red.example.net.chain.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/example.net.key;
|
||||
ssl_session_timeout 5m;
|
||||
ssl_protocols SSLv3 TLSv1;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
|
@ -46,7 +46,7 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
/**
|
||||
*
|
||||
* @see RedBrowser::set_writeable()
|
||||
* @var DAV\Browser\Plugin
|
||||
* @var \Sabre\DAV\Browser\Plugin
|
||||
*/
|
||||
public $browser;
|
||||
/**
|
||||
@ -85,7 +85,7 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
*/
|
||||
protected function validateUserPass($username, $password) {
|
||||
if (trim($password) === '+++') {
|
||||
logger('(DAV): RedBasicAuth::validateUserPass(): guest ' . $username);
|
||||
logger('guest: ' . $username);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -112,13 +112,14 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
foreach ($x as $record) {
|
||||
if (($record['account_flags'] == ACCOUNT_OK) || ($record['account_flags'] == ACCOUNT_UNVERIFIED)
|
||||
&& (hash('whirlpool', $record['account_salt'] . $password) === $record['account_password'])) {
|
||||
logger('(DAV) RedBasicAuth: password verified for ' . $username);
|
||||
logger('password verified for ' . $username);
|
||||
return $this->setAuthenticated($r[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
logger('(DAV) RedBasicAuth: password failed for ' . $username);
|
||||
logger('password failed for ' . $username);
|
||||
// @TODO add security logger
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -186,23 +187,23 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
|
||||
* @brief Set browser plugin for SabreDAV.
|
||||
*
|
||||
* @see RedBrowser::set_writeable()
|
||||
* @param DAV\Browser\Plugin $browser
|
||||
* @param \Sabre\DAV\Browser\Plugin $browser
|
||||
*/
|
||||
public function setBrowserPlugin($browser) {
|
||||
$this->browser = $browser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out all RedBasicAuth variables to logger().
|
||||
* @brief Prints out all RedBasicAuth variables to logger().
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function log() {
|
||||
logger('dav: auth: channel_name ' . $this->channel_name, LOGGER_DATA);
|
||||
logger('dav: auth: channel_id ' . $this->channel_id, LOGGER_DATA);
|
||||
logger('dav: auth: channel_hash ' . $this->channel_hash, LOGGER_DATA);
|
||||
logger('dav: auth: observer ' . $this->observer, LOGGER_DATA);
|
||||
logger('dav: auth: owner_id ' . $this->owner_id, LOGGER_DATA);
|
||||
logger('dav: auth: owner_nick ' . $this->owner_nick, LOGGER_DATA);
|
||||
logger('channel_name ' . $this->channel_name, LOGGER_DATA);
|
||||
logger('channel_id ' . $this->channel_id, LOGGER_DATA);
|
||||
logger('channel_hash ' . $this->channel_hash, LOGGER_DATA);
|
||||
logger('observer ' . $this->observer, LOGGER_DATA);
|
||||
logger('owner_id ' . $this->owner_id, LOGGER_DATA);
|
||||
logger('owner_nick ' . $this->owner_nick, LOGGER_DATA);
|
||||
}
|
||||
}
|
@ -262,6 +262,14 @@ class RedBrowser extends DAV\Browser\Plugin {
|
||||
construct_page(get_app());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a human readable formatted string for filesizes.
|
||||
*
|
||||
* Don't we need such a functionality in other places, too?
|
||||
*
|
||||
* @param int $size filesize in bytes
|
||||
* @return string
|
||||
*/
|
||||
function userReadableSize($size) {
|
||||
$ret = "";
|
||||
if (is_numeric($size)) {
|
||||
|
@ -49,7 +49,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
* @param RedBasicAuth &$auth_plugin
|
||||
*/
|
||||
public function __construct($ext_path, &$auth_plugin) {
|
||||
logger('RedDirectory::__construct() ' . $ext_path, LOGGER_DATA);
|
||||
//logger('directory ' . $ext_path, LOGGER_DATA);
|
||||
$this->ext_path = $ext_path;
|
||||
// remove "/cloud" from the beginning of the path
|
||||
$this->red_path = ((strpos($ext_path, '/cloud') === 0) ? substr($ext_path, 6) : $ext_path);
|
||||
@ -66,19 +66,19 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
}
|
||||
|
||||
private function log() {
|
||||
logger('RedDirectory::log() ext_path ' . $this->ext_path, LOGGER_DATA);
|
||||
logger('RedDirectory::log() os_path ' . $this->os_path, LOGGER_DATA);
|
||||
logger('RedDirectory::log() red_path ' . $this->red_path, LOGGER_DATA);
|
||||
logger('ext_path ' . $this->ext_path, LOGGER_DATA);
|
||||
logger('os_path ' . $this->os_path, LOGGER_DATA);
|
||||
logger('red_path ' . $this->red_path, LOGGER_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns an array with all the child nodes.
|
||||
*
|
||||
* @throws DAV\Exception\Forbidden
|
||||
* @return array DAV\INode[]
|
||||
* @throw \Sabre\DAV\Exception\Forbidden
|
||||
* @return array \Sabre\DAV\INode[]
|
||||
*/
|
||||
public function getChildren() {
|
||||
logger('RedDirectory::getChildren() called for ' . $this->ext_path, LOGGER_DATA);
|
||||
//logger('children for ' . $this->ext_path, LOGGER_DATA);
|
||||
$this->log();
|
||||
|
||||
if (get_config('system', 'block_public') && (! $this->auth->channel_id) && (! $this->auth->observer)) {
|
||||
@ -97,12 +97,12 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
* @brief Returns a child by name.
|
||||
*
|
||||
*
|
||||
* @throw DAV\Exception\Forbidden
|
||||
* @throw DAV\Exception\NotFound
|
||||
* @throw \Sabre\DAV\Exception\Forbidden
|
||||
* @throw \Sabre\DAV\Exception\NotFound
|
||||
* @param string $name
|
||||
*/
|
||||
public function getChild($name) {
|
||||
logger('RedDirectory::getChild(): ' . $name, LOGGER_DATA);
|
||||
logger($name, LOGGER_DATA);
|
||||
|
||||
if (get_config('system', 'block_public') && (! $this->auth->channel_id) && (! $this->auth->observer)) {
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
@ -130,7 +130,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
logger('RedDirectory::getName() returns: ' . basename($this->red_path), LOGGER_DATA);
|
||||
//logger(basename($this->red_path), LOGGER_DATA);
|
||||
return (basename($this->red_path));
|
||||
}
|
||||
|
||||
@ -139,20 +139,20 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
*
|
||||
* @todo handle duplicate directory name
|
||||
*
|
||||
* @throw DAV\Exception\Forbidden
|
||||
* @throw \Sabre\DAV\Exception\Forbidden
|
||||
* @param string $name The new name of the directory.
|
||||
* @return void
|
||||
*/
|
||||
public function setName($name) {
|
||||
logger('RedDirectory::setName(): ' . basename($this->red_path) . ' -> ' . $name, LOGGER_DATA);
|
||||
logger('old name ' . basename($this->red_path) . ' -> ' . $name, LOGGER_DATA);
|
||||
|
||||
if ((! $name) || (! $this->auth->owner_id)) {
|
||||
logger('RedDirectory::setName(): permission denied');
|
||||
logger('permission denied ' . $name);
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
if (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage')) {
|
||||
logger('RedDirectory::setName(): permission denied');
|
||||
logger('permission denied '. $name);
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
@ -177,21 +177,21 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
* After successful creation of the file, you may choose to return the ETag
|
||||
* of the new file here.
|
||||
*
|
||||
* @throws DAV\Exception\Forbidden
|
||||
* @throw \Sabre\DAV\Exception\Forbidden
|
||||
* @param string $name Name of the file
|
||||
* @param resource|string $data Initial payload
|
||||
* @return null|string ETag
|
||||
*/
|
||||
public function createFile($name, $data = null) {
|
||||
logger('RedDirectory::createFile(): ' . $name, LOGGER_DATA);
|
||||
logger($name, LOGGER_DEBUG);
|
||||
|
||||
if (! $this->auth->owner_id) {
|
||||
logger('RedDirectory::createFile(): permission denied');
|
||||
logger('permission denied ' . $name);
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
if (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage')) {
|
||||
logger('RedDirectory::createFile(): permission denied');
|
||||
logger('permission denied ' . $name);
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
);
|
||||
|
||||
if (! $c) {
|
||||
logger('RedDirectory::createFile(): no channel');
|
||||
logger('no channel');
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
@ -237,7 +237,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
$size = file_put_contents($f, $data);
|
||||
// delete attach entry if file_put_contents() failed
|
||||
if ($size === false) {
|
||||
logger('RedDirectory::createFile(): file_put_contents() failed for ' . $name, LOGGER_DEBUG);
|
||||
logger('file_put_contents() failed to ' . $f);
|
||||
attach_delete($c[0]['channel_id'], $hash);
|
||||
return;
|
||||
}
|
||||
@ -273,7 +273,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
intval($c[0]['channel_account_id'])
|
||||
);
|
||||
if (($x) && ($x[0]['total'] + $size > $limit)) {
|
||||
logger('reddav: service class limit exceeded for ' . $c[0]['channel_name'] . ' total usage is ' . $x[0]['total'] . ' limit is ' . $limit);
|
||||
logger('service class limit exceeded for ' . $c[0]['channel_name'] . ' total usage is ' . $x[0]['total'] . ' limit is ' . $limit);
|
||||
attach_delete($c[0]['channel_id'], $hash);
|
||||
return;
|
||||
}
|
||||
@ -287,7 +287,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
* @return void
|
||||
*/
|
||||
public function createDirectory($name) {
|
||||
logger('RedDirectory::createDirectory(): ' . $name, LOGGER_DEBUG);
|
||||
logger($name, LOGGER_DEBUG);
|
||||
|
||||
if ((! $this->auth->owner_id) || (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage'))) {
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
@ -301,7 +301,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
if ($r) {
|
||||
$result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash));
|
||||
if (! $result['success']) {
|
||||
logger('RedDirectory::createDirectory(): ' . print_r($result, true), LOGGER_DEBUG);
|
||||
logger('error ' . print_r($result, true), LOGGER_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -310,31 +310,33 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
* @brief Checks if a child exists.
|
||||
*
|
||||
* @param string $name
|
||||
* The name to check if it exists.
|
||||
* @return boolean
|
||||
*/
|
||||
public function childExists($name) {
|
||||
// On /cloud we show a list of available channels.
|
||||
// @todo what happens if no channels are available?
|
||||
if ($this->red_path === '/' && $name === 'cloud') {
|
||||
logger('RedDirectory::childExists() /cloud: true', LOGGER_DATA);
|
||||
//logger('We are at /cloud show a channel list', LOGGER_DEBUG);
|
||||
return true;
|
||||
}
|
||||
|
||||
$x = RedFileData($this->ext_path . '/' . $name, $this->auth, true);
|
||||
logger('RedFileData returns: ' . print_r($x, true), LOGGER_DATA);
|
||||
//logger('RedFileData returns: ' . print_r($x, true), LOGGER_DATA);
|
||||
if ($x)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo add description of what this function does.
|
||||
*
|
||||
* @throw DAV\Exception\NotFound
|
||||
* @throw \Sabre\DAV\Exception\NotFound
|
||||
* @return void
|
||||
*/
|
||||
function getDir() {
|
||||
logger('RedDirectory::getDir(): ' . $this->ext_path, LOGGER_DEBUG);
|
||||
//logger($this->ext_path, LOGGER_DEBUG);
|
||||
$this->auth->log();
|
||||
|
||||
$file = $this->ext_path;
|
||||
@ -356,7 +358,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
if (! $path_arr)
|
||||
return;
|
||||
|
||||
logger('RedDirectory::getDir(): path: ' . print_r($path_arr, true), LOGGER_DATA);
|
||||
logger('paths: ' . print_r($path_arr, true), LOGGER_DATA);
|
||||
|
||||
$channel_name = $path_arr[0];
|
||||
|
||||
@ -367,7 +369,6 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
|
||||
if (! $r) {
|
||||
throw new DAV\Exception\NotFound('The file with name: ' . $channel_name . ' could not be found.');
|
||||
return;
|
||||
}
|
||||
|
||||
$channel_id = $r[0]['channel_id'];
|
||||
@ -397,12 +398,11 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
}
|
||||
$this->folder_hash = $folder;
|
||||
$this->os_path = $os_path;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the last modification time for the directory, as a UNIX
|
||||
* timestamp.
|
||||
* timestamp.
|
||||
*
|
||||
* It looks for the last edited file in the folder. If it is an empty folder
|
||||
* it returns the lastmodified time of the folder itself, to prevent zero
|
||||
@ -429,7 +429,8 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
|
||||
/**
|
||||
* @brief Return quota usage.
|
||||
*
|
||||
* Do guests relly see the used/free values from filesystem of the complete store directory?
|
||||
* @fixme Should guests relly see the used/free values from filesystem of the
|
||||
* complete store directory?
|
||||
*
|
||||
* @return array with used and free values in bytes.
|
||||
*/
|
||||
|
@ -49,7 +49,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
$this->data = $data;
|
||||
$this->auth = $auth;
|
||||
|
||||
logger('RedFile::__construct(): ' . print_r($this->data, true), LOGGER_DATA);
|
||||
//logger(print_r($this->data, true), LOGGER_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,7 +58,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
logger('RedFile::getName(): ' . basename($this->name), LOGGER_DEBUG);
|
||||
//logger(basename($this->name), LOGGER_DATA);
|
||||
return basename($this->name);
|
||||
}
|
||||
|
||||
@ -70,9 +70,10 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
* @return void
|
||||
*/
|
||||
public function setName($newName) {
|
||||
logger('RedFile::setName(): ' . basename($this->name) . ' -> ' . $newName, LOGGER_DEBUG);
|
||||
logger('old name ' . basename($this->name) . ' -> ' . $newName, LOGGER_DATA);
|
||||
|
||||
if ((! $newName) || (! $this->auth->owner_id) || (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage'))) {
|
||||
logger('permission denied '. $newName);
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
|
||||
@ -91,7 +92,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
* @return void
|
||||
*/
|
||||
public function put($data) {
|
||||
logger('RedFile::put(): ' . basename($this->name), LOGGER_DEBUG);
|
||||
logger('put file: ' . basename($this->name), LOGGER_DEBUG);
|
||||
$size = 0;
|
||||
|
||||
// @todo only 3 values are needed
|
||||
@ -110,7 +111,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
// @todo check return value and set $size directly
|
||||
@file_put_contents($f, $data);
|
||||
$size = @filesize($f);
|
||||
logger('RedFile::put(): filename: ' . $f . ' size: ' . $size, LOGGER_DEBUG);
|
||||
logger('filename: ' . $f . ' size: ' . $size, LOGGER_DEBUG);
|
||||
} else {
|
||||
$r = q("UPDATE attach SET data = '%s' WHERE hash = '%s' AND uid = %d LIMIT 1",
|
||||
dbesc(stream_get_contents($data)),
|
||||
@ -161,7 +162,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
intval($c[0]['channel_account_id'])
|
||||
);
|
||||
if (($x) && ($x[0]['total'] + $size > $limit)) {
|
||||
logger('RedFile::put(): service class limit exceeded for ' . $c[0]['channel_name'] . ' total usage is ' . $x[0]['total'] . ' limit is ' . $limit);
|
||||
logger('service class limit exceeded for ' . $c[0]['channel_name'] . ' total usage is ' . $x[0]['total'] . ' limit is ' . $limit);
|
||||
attach_delete($c[0]['channel_id'], $this->data['hash']);
|
||||
return;
|
||||
}
|
||||
@ -174,7 +175,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
* @return string
|
||||
*/
|
||||
public function get() {
|
||||
logger('RedFile::get(): ' . basename($this->name), LOGGER_DEBUG);
|
||||
logger('get file ' . basename($this->name), LOGGER_DEBUG);
|
||||
|
||||
$r = q("SELECT data, flags, filename, filetype FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
|
||||
dbesc($this->data['hash']),
|
||||
@ -206,7 +207,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
*
|
||||
* Return null if the ETag can not effectively be determined.
|
||||
*
|
||||
* @return mixed
|
||||
* @return null|string
|
||||
*/
|
||||
public function getETag() {
|
||||
$ret = null;
|
||||
@ -236,6 +237,7 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
* @brief Returns the size of the node, in bytes.
|
||||
*
|
||||
* @return int
|
||||
* filesize in bytes
|
||||
*/
|
||||
public function getSize() {
|
||||
return $this->data['filesize'];
|
||||
@ -254,11 +256,13 @@ class RedFile extends DAV\Node implements DAV\IFile {
|
||||
/**
|
||||
* @brief Delete the file.
|
||||
*
|
||||
* @throw Sabre\DAV\Exception\Forbidden
|
||||
* @return void
|
||||
* This method checks the permissions and then calls attach_delete() function
|
||||
* to actually remove the file.
|
||||
*
|
||||
* @throw \Sabre\DAV\Exception\Forbidden
|
||||
*/
|
||||
public function delete() {
|
||||
logger('RedFile::delete(): ' . basename($this->name), LOGGER_DEBUG);
|
||||
logger('delete file ' . basename($this->name), LOGGER_DEBUG);
|
||||
|
||||
if ((! $this->auth->owner_id) || (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage'))) {
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
|
@ -26,77 +26,74 @@ function z_mime_content_type($filename) {
|
||||
|
||||
$mime_types = array(
|
||||
|
||||
'txt' => 'text/plain',
|
||||
'htm' => 'text/html',
|
||||
'html' => 'text/html',
|
||||
'php' => 'text/html',
|
||||
'css' => 'text/css',
|
||||
'js' => 'application/javascript',
|
||||
'json' => 'application/json',
|
||||
'xml' => 'application/xml',
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'flv' => 'video/x-flv',
|
||||
'epub' => 'application/epub+zip',
|
||||
'txt' => 'text/plain',
|
||||
'htm' => 'text/html',
|
||||
'html' => 'text/html',
|
||||
'php' => 'text/html',
|
||||
'css' => 'text/css',
|
||||
'js' => 'application/javascript',
|
||||
'json' => 'application/json',
|
||||
'xml' => 'application/xml',
|
||||
'swf' => 'application/x-shockwave-flash',
|
||||
'flv' => 'video/x-flv',
|
||||
'epub' => 'application/epub+zip',
|
||||
|
||||
// images
|
||||
'png' => 'image/png',
|
||||
'jpe' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'gif' => 'image/gif',
|
||||
'bmp' => 'image/bmp',
|
||||
'ico' => 'image/vnd.microsoft.icon',
|
||||
'tiff' => 'image/tiff',
|
||||
'tif' => 'image/tiff',
|
||||
'svg' => 'image/svg+xml',
|
||||
'svgz' => 'image/svg+xml',
|
||||
// images
|
||||
'png' => 'image/png',
|
||||
'jpe' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpg' => 'image/jpeg',
|
||||
'gif' => 'image/gif',
|
||||
'bmp' => 'image/bmp',
|
||||
'ico' => 'image/vnd.microsoft.icon',
|
||||
'tiff' => 'image/tiff',
|
||||
'tif' => 'image/tiff',
|
||||
'svg' => 'image/svg+xml',
|
||||
'svgz' => 'image/svg+xml',
|
||||
|
||||
// archives
|
||||
'zip' => 'application/zip',
|
||||
'rar' => 'application/x-rar-compressed',
|
||||
'exe' => 'application/x-msdownload',
|
||||
'msi' => 'application/x-msdownload',
|
||||
'cab' => 'application/vnd.ms-cab-compressed',
|
||||
// archives
|
||||
'zip' => 'application/zip',
|
||||
'rar' => 'application/x-rar-compressed',
|
||||
'exe' => 'application/x-msdownload',
|
||||
'msi' => 'application/x-msdownload',
|
||||
'cab' => 'application/vnd.ms-cab-compressed',
|
||||
|
||||
// audio/video
|
||||
'mp3' => 'audio/mpeg',
|
||||
'wav' => 'audio/wav',
|
||||
'qt' => 'video/quicktime',
|
||||
'mov' => 'video/quicktime',
|
||||
'ogg' => 'application/ogg',
|
||||
// audio/video
|
||||
'mp3' => 'audio/mpeg',
|
||||
'wav' => 'audio/wav',
|
||||
'qt' => 'video/quicktime',
|
||||
'mov' => 'video/quicktime',
|
||||
'ogg' => 'application/ogg',
|
||||
|
||||
// adobe
|
||||
'pdf' => 'application/pdf',
|
||||
'psd' => 'image/vnd.adobe.photoshop',
|
||||
'ai' => 'application/postscript',
|
||||
'eps' => 'application/postscript',
|
||||
'ps' => 'application/postscript',
|
||||
// adobe
|
||||
'pdf' => 'application/pdf',
|
||||
'psd' => 'image/vnd.adobe.photoshop',
|
||||
'ai' => 'application/postscript',
|
||||
'eps' => 'application/postscript',
|
||||
'ps' => 'application/postscript',
|
||||
|
||||
// ms office
|
||||
'doc' => 'application/msword',
|
||||
'rtf' => 'application/rtf',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
// ms office
|
||||
'doc' => 'application/msword',
|
||||
'rtf' => 'application/rtf',
|
||||
'xls' => 'application/vnd.ms-excel',
|
||||
'ppt' => 'application/vnd.ms-powerpoint',
|
||||
|
||||
|
||||
// open office
|
||||
'odt' => 'application/vnd.oasis.opendocument.text',
|
||||
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
||||
// open office
|
||||
'odt' => 'application/vnd.oasis.opendocument.text',
|
||||
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
||||
);
|
||||
|
||||
$dot = strpos($filename,'.');
|
||||
if($dot !== false) {
|
||||
$ext = strtolower(substr($filename,$dot+1));
|
||||
$dot = strpos($filename, '.');
|
||||
if ($dot !== false) {
|
||||
$ext = strtolower(substr($filename, $dot + 1));
|
||||
if (array_key_exists($ext, $mime_types)) {
|
||||
return $mime_types[$ext];
|
||||
}
|
||||
}
|
||||
|
||||
return 'application/octet-stream';
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Count files/attachments.
|
||||
*
|
||||
@ -138,8 +135,8 @@ function attach_count_files($channel_id, $observer, $hash = '', $filename = '',
|
||||
|
||||
$ret['success'] = ((is_array($r)) ? true : false);
|
||||
$ret['results'] = ((is_array($r)) ? count($r) : false);
|
||||
return $ret;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,8 +187,8 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $
|
||||
|
||||
$ret['success'] = ((is_array($r)) ? true : false);
|
||||
$ret['results'] = ((is_array($r)) ? $r : false);
|
||||
return $ret;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,8 +243,8 @@ function attach_by_hash($hash, $rev = 0) {
|
||||
|
||||
$ret['success'] = true;
|
||||
$ret['data'] = $r[0];
|
||||
return $ret;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -301,7 +298,6 @@ function attach_by_hash_nodata($hash, $rev = 0) {
|
||||
$ret['success'] = true;
|
||||
$ret['data'] = $r[0];
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -400,6 +396,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
||||
|
||||
if(! isset($hash))
|
||||
$hash = random_string();
|
||||
|
||||
$created = datetime_convert();
|
||||
|
||||
if($options === 'replace') {
|
||||
@ -432,7 +429,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
||||
dbesc($x[0]['deny_cid']),
|
||||
dbesc($x[0]['deny_gid'])
|
||||
);
|
||||
}
|
||||
}
|
||||
elseif($options === 'update') {
|
||||
$r = q("update attach set filename = '%s', filetype = '%s', edited = '%s',
|
||||
allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where id = %d and uid = %d limit 1",
|
||||
@ -446,7 +443,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
||||
intval($x[0]['id']),
|
||||
intval($x[0]['uid'])
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, data, created, edited, allow_cid, allow_gid,deny_cid, deny_gid )
|
||||
VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
|
||||
@ -466,7 +463,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
||||
dbesc(($arr && array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : ''),
|
||||
dbesc(($arr && array_key_exists('deny_gid',$arr)) ? $arr['deny_gid'] : '')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if($options !== 'update')
|
||||
@unlink($src);
|
||||
@ -490,6 +487,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
||||
|
||||
$ret['success'] = true;
|
||||
$ret['data'] = $r[0];
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
@ -507,8 +505,8 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
|
||||
* $ret['data'] = array of attach DB entries without data component
|
||||
*/
|
||||
function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
|
||||
|
||||
$ret = array('success' => false);
|
||||
|
||||
if(! perm_is_allowed($r[0]['uid'], get_observer_hash(), 'view_storage')) {
|
||||
$ret['message'] = t('Permission denied.');
|
||||
return $ret;
|
||||
@ -547,6 +545,7 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
|
||||
}
|
||||
$ret['success'] = true;
|
||||
$ret['data'] = $r;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
@ -686,7 +685,6 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -732,15 +730,19 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi
|
||||
dbesc($resource),
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete a file/directory.
|
||||
*
|
||||
* @brief Delete a file/directory from a channel.
|
||||
*
|
||||
* If the provided resource hash is from a directory it will delete everything
|
||||
* recursively under this directory.
|
||||
*
|
||||
* @param int $channel_id
|
||||
* @param string $resource a hash to delete
|
||||
* The id of the channel
|
||||
* @param string $resource
|
||||
* The hash to delete
|
||||
* @return void
|
||||
*/
|
||||
function attach_delete($channel_id, $resource) {
|
||||
|
||||
@ -760,7 +762,7 @@ function attach_delete($channel_id, $resource) {
|
||||
|
||||
// If resource is a directory delete everything in the directory recursive
|
||||
if($r[0]['flags'] & ATTACH_FLAG_DIR) {
|
||||
$x = q("select hash, flags from attach where folder = '%s' and uid = %d",
|
||||
$x = q("SELECT hash, flags FROM attach WHERE folder = '%s' AND uid = %d",
|
||||
dbesc($resource),
|
||||
intval($channel_id)
|
||||
);
|
||||
@ -799,19 +801,21 @@ function attach_delete($channel_id, $resource) {
|
||||
dbesc($r[0]['folder']),
|
||||
intval($channel_id)
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns path to file in cloud/.
|
||||
*
|
||||
* @param $arr
|
||||
* @return string with the path the file to cloud/
|
||||
* @param array
|
||||
* $arr[uid] int the channels uid
|
||||
* $arr[folder] string
|
||||
* $arr[filename]] string
|
||||
* @return string
|
||||
* path to the file in cloud/
|
||||
*/
|
||||
function get_cloudpath($arr) {
|
||||
|
||||
$basepath = 'cloud/';
|
||||
|
||||
if($arr['uid']) {
|
||||
$r = q("select channel_address from channel where channel_id = %d limit 1",
|
||||
intval($arr['uid'])
|
||||
@ -823,7 +827,6 @@ function get_cloudpath($arr) {
|
||||
$path = $basepath;
|
||||
|
||||
if($arr['folder']) {
|
||||
|
||||
$lpath = '';
|
||||
$lfile = $arr['folder'];
|
||||
|
||||
@ -842,59 +845,82 @@ function get_cloudpath($arr) {
|
||||
$lpath = $r[0]['filename'] . '/' . $lpath;
|
||||
$lfile = $r[0]['folder'];
|
||||
|
||||
} while ( ($r[0]['folder']) && ($r[0]['flags'] & ATTACH_FLAG_DIR)) ;
|
||||
} while ( ($r[0]['folder']) && ($r[0]['flags'] & ATTACH_FLAG_DIR));
|
||||
|
||||
$path .= $lpath;
|
||||
$path .= $lpath;
|
||||
}
|
||||
|
||||
$path .= $arr['filename'];
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns path to parent folder in cloud/.
|
||||
*
|
||||
* @param $arr
|
||||
* @return string with the folder path
|
||||
*
|
||||
* @param int $channel_id
|
||||
* The id of the channel
|
||||
* @param string $channel_name
|
||||
* The name of the channel
|
||||
* @param string $attachHash
|
||||
* @return string with the full folder path
|
||||
*/
|
||||
function get_parent_cloudpath($channel_id, $channel_name, $attachHash) {
|
||||
//Build directory tree and redirect
|
||||
// build directory tree
|
||||
$parentHash = $attachHash;
|
||||
do {
|
||||
$parentHash = find_folder_hash_by_attach_hash($channel_id, $parentHash);
|
||||
if ($parentHash) {
|
||||
$parentName = find_filename_by_hash($channel_id, $parentHash);
|
||||
$parentFullPath = $parentName."/".$parentFullPath;
|
||||
$parentFullPath = $parentName . '/' . $parentFullPath;
|
||||
}
|
||||
} while ($parentHash);
|
||||
$parentFullPath = z_root() . "/cloud/" . $channel_name . "/" . $parentFullPath;
|
||||
$parentFullPath = z_root() . '/cloud/' . $channel_name . '/' . $parentFullPath;
|
||||
|
||||
return $parentFullPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the hash of an attachment's folder.
|
||||
*
|
||||
* @param int $channel_id
|
||||
* The id of the channel
|
||||
* @param string $attachHash
|
||||
* The hash of the attachment
|
||||
* @return string
|
||||
*/
|
||||
function find_folder_hash_by_attach_hash($channel_id, $attachHash) {
|
||||
$r = q("select * from attach where uid = %d and hash = '%s' limit 1",
|
||||
intval($channel_id), dbesc($attachHash)
|
||||
$r = q("SELECT folder FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
|
||||
intval($channel_id),
|
||||
dbesc($attachHash)
|
||||
);
|
||||
$hash = "";
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$hash = $rr['folder'];
|
||||
}
|
||||
$hash = '';
|
||||
if ($r) {
|
||||
$hash = $r[0]['folder'];
|
||||
}
|
||||
return $hash;
|
||||
}
|
||||
function find_filename_by_hash($channel_id, $attachHash) {
|
||||
$r = q("select * from attach where uid = %d and hash = '%s' limit 1",
|
||||
intval($channel_id), dbesc($attachHash)
|
||||
);
|
||||
$filename = "";
|
||||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$filename = $rr['filename'];
|
||||
}
|
||||
}
|
||||
return $filename;
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the filename of an attachment in a given channel.
|
||||
*
|
||||
* @param mixed $channel_id
|
||||
* The id of the channel
|
||||
* @param mixed $attachHash
|
||||
* The hash of the attachment
|
||||
* @return string
|
||||
* The filename of the attachment
|
||||
*/
|
||||
function find_filename_by_hash($channel_id, $attachHash) {
|
||||
$r = q("SELECT filename FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
|
||||
intval($channel_id),
|
||||
dbesc($attachHash)
|
||||
);
|
||||
$filename = '';
|
||||
if ($r) {
|
||||
$filename = $r[0]['filename'];
|
||||
}
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
@ -904,6 +930,6 @@ function find_filename_by_hash($channel_id, $attachHash) {
|
||||
function pipe_streams($in, $out) {
|
||||
$size = 0;
|
||||
while (!feof($in))
|
||||
$size += fwrite($out, fread($in,8192));
|
||||
$size += fwrite($out, fread($in, 8192));
|
||||
return $size;
|
||||
}
|
||||
|
@ -927,9 +927,14 @@ function get_diaspora_reshare_xml($url,$recurse = 0) {
|
||||
|
||||
// see if it's a reshare of a reshare
|
||||
|
||||
if($source_xml->root_diaspora_id && $source_xml->root_guid && $recurse < 15) {
|
||||
$orig_author = notags(unxmlify($source_xml->root_diaspora_id));
|
||||
$orig_guid = notags(unxmlify($source_xml->root_guid));
|
||||
if($source_xml->post->reshare)
|
||||
$xml = $source_xml->post->reshare;
|
||||
else
|
||||
return false;
|
||||
|
||||
if($xml->root_diaspora_id && $xml->root_guid && $recurse < 15) {
|
||||
$orig_author = notags(unxmlify($xml->root_diaspora_id));
|
||||
$orig_guid = notags(unxmlify($xml->root_guid));
|
||||
$source_url = 'https://' . substr($orig_author,strpos($orig_author,'@')+1) . '/p/' . $orig_guid . '.xml';
|
||||
$y = get_diaspora_reshare_xml($source_url,$recurse+1);
|
||||
if($y)
|
||||
|
@ -113,4 +113,61 @@ function remove_obsolete_hublocs() {
|
||||
}
|
||||
|
||||
|
||||
// This actually changes other structures to match the given (presumably current) hubloc primary selection
|
||||
|
||||
function hubloc_change_primary($hubloc) {
|
||||
|
||||
if(! is_array($hubloc)) {
|
||||
logger('no hubloc');
|
||||
return false;
|
||||
}
|
||||
if(! ($hubloc['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY)) {
|
||||
logger('not primary: ' . $hubloc['hubloc_url']);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger('setting primary: ' . $hubloc['hubloc_url']);
|
||||
|
||||
// See if there's a local channel
|
||||
|
||||
$r = q("select channel_id, channel_primary from channel where channel_hash = '%s' limit 1",
|
||||
dbesc($hubloc['hubloc_hash'])
|
||||
);
|
||||
if(($r) && (! $r[0]['channel_primary'])) {
|
||||
q("update channel set channel_primary = 1 where channel_id = %d limit 1",
|
||||
intval($r[0]['channel_id'])
|
||||
);
|
||||
}
|
||||
|
||||
// do we even have an xchan for this hubloc and if so is it already set as primary?
|
||||
|
||||
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($hubloc['hubloc_hash'])
|
||||
);
|
||||
if(! $r) {
|
||||
logger('xchan not found');
|
||||
return false;
|
||||
}
|
||||
if($r[0]['xchan_addr'] === $hubloc['hubloc_addr']) {
|
||||
logger('xchan already changed');
|
||||
return false;
|
||||
}
|
||||
|
||||
$url = $hubloc['hubloc_url'];
|
||||
$lwebbie = substr($hubloc['hubloc_addr'],0,strpos($hubloc['hubloc_addr'],'@'));
|
||||
|
||||
$r = q("update xchan set xchan_addr = '%s', xchan_url = '%s', xchan_follow = '%s', xchan_connurl = '%s' where xchan_hash = '%s' limit 1",
|
||||
dbesc($hubloc['hubloc_addr']),
|
||||
dbesc($url . '/channel/' . $lwebbie),
|
||||
dbesc($url . '/follow?f=&url=%s'),
|
||||
dbesc($url . '/poco/' . $lwebbie),
|
||||
dbesc($hubloc['hubloc_hash'])
|
||||
);
|
||||
if(! $r)
|
||||
logger('xchan_update failed.');
|
||||
|
||||
logger('primary hubloc changed.' . print_r($hubloc,true),LOGGER_DEBUG);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
@ -291,8 +291,8 @@ function create_identity($arr) {
|
||||
// Create a verified hub location pointing to this site.
|
||||
|
||||
$r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_flags,
|
||||
hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey )
|
||||
values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s' )",
|
||||
hubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network )
|
||||
values ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )",
|
||||
dbesc($guid),
|
||||
dbesc($sig),
|
||||
dbesc($hash),
|
||||
@ -302,7 +302,8 @@ function create_identity($arr) {
|
||||
dbesc(base64url_encode(rsa_sign(z_root(),$ret['channel']['channel_prvkey']))),
|
||||
dbesc(get_app()->get_hostname()),
|
||||
dbesc(z_root() . '/post'),
|
||||
dbesc(get_config('system','pubkey'))
|
||||
dbesc(get_config('system','pubkey')),
|
||||
dbesc('zot')
|
||||
);
|
||||
if(! $r)
|
||||
logger('create_identity: Unable to store hub location');
|
||||
|
@ -402,7 +402,7 @@ function validate_email($addr) {
|
||||
return false;
|
||||
$h = substr($addr,strpos($addr,'@') + 1);
|
||||
|
||||
if(($h) && (dns_get_record($h, DNS_A + DNS_CNAME + DNS_PTR + DNS_MX) || filter_var($h['host'], FILTER_VALIDATE_IP) )) {
|
||||
if(($h) && (dns_get_record($h, DNS_A + DNS_CNAME + DNS_PTR + DNS_MX) || filter_var($h, FILTER_VALIDATE_IP) )) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -36,8 +36,8 @@ require_once('include/RedDAV/RedBasicAuth.php');
|
||||
* @todo Is there any reason why this is not inside RedDirectory class?
|
||||
* @fixme function name looks like a class name, should we rename it?
|
||||
*
|
||||
* @param $auth
|
||||
* @return array containing RedDirectory objects
|
||||
* @param RedBasicAuth &$auth
|
||||
* @return array RedDirectory[]
|
||||
*/
|
||||
function RedChannelList(&$auth) {
|
||||
$ret = array();
|
||||
@ -50,7 +50,7 @@ function RedChannelList(&$auth) {
|
||||
if ($r) {
|
||||
foreach ($r as $rr) {
|
||||
if (perm_is_allowed($rr['channel_id'], $auth->observer, 'view_storage')) {
|
||||
logger('RedChannelList: ' . '/cloud/' . $rr['channel_address'], LOGGER_DATA);
|
||||
logger('found channel: /cloud/' . $rr['channel_address'], LOGGER_DEBUG);
|
||||
// @todo can't we drop '/cloud'? It gets stripped off anyway in RedDirectory
|
||||
$ret[] = new RedDAV\RedDirectory('/cloud/' . $rr['channel_address'], $auth);
|
||||
}
|
||||
@ -70,8 +70,10 @@ function RedChannelList(&$auth) {
|
||||
* @fixme function name looks like a class name, should we rename it?
|
||||
*
|
||||
* @param string $file path to a directory
|
||||
* @param &$auth
|
||||
* @returns array DAV\INode[]
|
||||
* @param RedBasicAuth &$auth
|
||||
* @returns null|array \Sabre\DAV\INode[]
|
||||
* @throw \Sabre\DAV\Exception\Forbidden
|
||||
* @throw \Sabre\DAV\Exception\NotFound
|
||||
*/
|
||||
function RedCollectionData($file, &$auth) {
|
||||
$ret = array();
|
||||
@ -88,7 +90,7 @@ function RedCollectionData($file, &$auth) {
|
||||
|
||||
$file = trim($file, '/');
|
||||
$path_arr = explode('/', $file);
|
||||
|
||||
|
||||
if (! $path_arr)
|
||||
return null;
|
||||
|
||||
@ -150,7 +152,7 @@ function RedCollectionData($file, &$auth) {
|
||||
|
||||
// This should no longer be needed since we just returned errors for paths not found
|
||||
if ($path !== '/' . $file) {
|
||||
logger("RedCollectionData: Path mismatch: $path !== /$file");
|
||||
logger("Path mismatch: $path !== /$file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -160,8 +162,7 @@ function RedCollectionData($file, &$auth) {
|
||||
);
|
||||
|
||||
foreach ($r as $rr) {
|
||||
logger('RedCollectionData: filename: ' . $rr['filename'], LOGGER_DATA);
|
||||
|
||||
//logger('filename: ' . $rr['filename'], LOGGER_DEBUG);
|
||||
if ($rr['flags'] & ATTACH_FLAG_DIR) {
|
||||
// @todo can't we drop '/cloud'? it gets stripped off anyway in RedDirectory
|
||||
$ret[] = new RedDAV\RedDirectory('/cloud' . $path . '/' . $rr['filename'], $auth);
|
||||
@ -180,11 +181,14 @@ function RedCollectionData($file, &$auth) {
|
||||
* @fixme function name looks like a class name, should we rename it?
|
||||
*
|
||||
* @param string $file
|
||||
* @param &$auth
|
||||
* path to file or directory
|
||||
* @param RedBasicAuth &$auth
|
||||
* @param boolean $test (optional) enable test mode
|
||||
* @return RedFile|RedDirectory|boolean|null
|
||||
* @throw \Sabre\DAV\Exception\Forbidden
|
||||
*/
|
||||
function RedFileData($file, &$auth, $test = false) {
|
||||
logger('RedFileData:' . $file . (($test) ? ' (test mode) ' : ''), LOGGER_DEBUG);
|
||||
logger($file . (($test) ? ' (test mode) ' : ''), LOGGER_DEBUG);
|
||||
|
||||
$x = strpos($file, '/cloud');
|
||||
if ($x === 0) {
|
||||
@ -198,7 +202,7 @@ function RedFileData($file, &$auth, $test = false) {
|
||||
$file = trim($file, '/');
|
||||
|
||||
$path_arr = explode('/', $file);
|
||||
|
||||
|
||||
if (! $path_arr)
|
||||
return null;
|
||||
|
||||
@ -237,7 +241,7 @@ function RedFileData($file, &$auth, $test = false) {
|
||||
if ($r && ( $r[0]['flags'] & ATTACH_FLAG_DIR)) {
|
||||
$folder = $r[0]['hash'];
|
||||
$path = $path . '/' . $r[0]['filename'];
|
||||
}
|
||||
}
|
||||
if (! $r) {
|
||||
$r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, created, edited from attach
|
||||
where folder = '%s' and filename = '%s' and uid = %d $perms group by filename limit 1",
|
||||
@ -267,11 +271,11 @@ function RedFileData($file, &$auth, $test = false) {
|
||||
}
|
||||
|
||||
if ($errors) {
|
||||
logger('RedFileData: not found');
|
||||
logger('not found ' . $file);
|
||||
if ($test)
|
||||
return false;
|
||||
if ($permission_error) {
|
||||
logger('RedFileData: permission error');
|
||||
logger('permission error ' . $file);
|
||||
throw new DAV\Exception\Forbidden('Permission denied.');
|
||||
}
|
||||
return;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
require_once('include/crypto.php');
|
||||
require_once('include/items.php');
|
||||
require_once('include/hubloc.php');
|
||||
|
||||
/**
|
||||
* Red implementation of zot protocol.
|
||||
@ -1714,9 +1715,14 @@ function process_location_delivery($sender,$arr,$deliveries) {
|
||||
);
|
||||
if($r)
|
||||
$sender['key'] = $r[0]['xchan_pubkey'];
|
||||
|
||||
$x = sync_locations($sender,$arr,true);
|
||||
logger('process_location_delivery: results: ' . print_r($x,true), LOGGER_DEBUG);
|
||||
if(array_key_exists('locations',$arr) && $arr['locations']) {
|
||||
$x = sync_locations($sender,$arr,true);
|
||||
logger('process_location_delivery: results: ' . print_r($x,true), LOGGER_DEBUG);
|
||||
if($x['changed']) {
|
||||
$guid = random_string() . '@' . get_app()->get_hostname();
|
||||
update_modtime($sender['hash'],$sender['guid'],$arr['locations'][0]['address'],UPDATE_FLAGS_UPDATED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1832,17 +1838,28 @@ function sync_locations($sender,$arr,$absolute = false) {
|
||||
|
||||
if((($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) && (! $location['primary']))
|
||||
|| ((! ($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY)) && ($location['primary']))) {
|
||||
$r = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d), hubloc_updated = '%s' where hubloc_id = %d limit 1",
|
||||
$m = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d), hubloc_updated = '%s' where hubloc_id = %d limit 1",
|
||||
intval(HUBLOC_FLAGS_PRIMARY),
|
||||
dbesc(datetime_convert()),
|
||||
intval($r[0]['hubloc_id'])
|
||||
);
|
||||
// make sure hubloc_change_primary() has current data
|
||||
$r[0]['hubloc_flags'] = $r[0]['hubloc_flags'] ^ HUBLOC_FLAGS_PRIMARY;
|
||||
hubloc_change_primary($r[0]);
|
||||
$what .= 'primary_hub ';
|
||||
$changed = true;
|
||||
}
|
||||
elseif($absolute) {
|
||||
// Absolute sync - make sure the current primary is correctly reflected in the xchan
|
||||
$pr = hubloc_change_primary($r[0]);
|
||||
if($pr) {
|
||||
$what .= 'xchan_primary';
|
||||
$changed = true;
|
||||
}
|
||||
}
|
||||
if((($r[0]['hubloc_flags'] & HUBLOC_FLAGS_DELETED) && (! $location['deleted']))
|
||||
|| ((! ($r[0]['hubloc_flags'] & HUBLOC_FLAGS_DELETED)) && ($location['deleted']))) {
|
||||
$r = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d), hubloc_updated = '%s' where hubloc_id = %d limit 1",
|
||||
$n = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d), hubloc_updated = '%s' where hubloc_id = %d limit 1",
|
||||
intval(HUBLOC_FLAGS_DELETED),
|
||||
dbesc(datetime_convert()),
|
||||
intval($r[0]['hubloc_id'])
|
||||
@ -1884,6 +1901,14 @@ function sync_locations($sender,$arr,$absolute = false) {
|
||||
$what .= 'newhub ';
|
||||
$changed = true;
|
||||
|
||||
if($location['primary']) {
|
||||
$r = q("select * from hubloc where hubloc_addr = '%s' and hubloc_sitekey = '%s' limit 1",
|
||||
dbesc($location['address']),
|
||||
dbesc($location['sitekey'])
|
||||
);
|
||||
if($r)
|
||||
hubloc_change_primary($r[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// get rid of any hubs we have for this channel which weren't reported.
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
define( 'UPDATE_VERSION' , 1129 );
|
||||
define( 'UPDATE_VERSION' , 1130 );
|
||||
|
||||
/**
|
||||
*
|
||||
@ -1457,3 +1457,10 @@ function update_r1128() {
|
||||
|
||||
}
|
||||
|
||||
function update_r1129() {
|
||||
$r = q("update hubloc set hubloc_network = 'zot' where hubloc_network = ''");
|
||||
if($r)
|
||||
return UPDATE_SUCCESS;
|
||||
return UPDATE_FAILED;
|
||||
}
|
||||
|
||||
|
@ -1,31 +0,0 @@
|
||||
<?php /** @file */
|
||||
|
||||
|
||||
/**
|
||||
Placeholder file at present. This is going to involve a bit of work.
|
||||
|
||||
This file will deal with the deletion of channels and management of hublocs.
|
||||
|
||||
We need to provide the following functionality:
|
||||
|
||||
- Delete my account and all channels from the entire network
|
||||
|
||||
- Delete my account and all channels from this server
|
||||
|
||||
- Delete a channel from the entire network
|
||||
|
||||
- Delete a channel from this server
|
||||
|
||||
- List all hub locations for this channel
|
||||
|
||||
- Remove this/some hub location from this channel
|
||||
|
||||
- promote this/some hub location to primary
|
||||
|
||||
- Remove hub location 'xyz' from this channel, (this should possibly only be allowed if that hub has been down for a period of time)
|
||||
|
||||
- Some of these actions should probably require email verification
|
||||
|
||||
*/
|
||||
|
||||
|
@ -1,18 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* @file mod/filestorage.php
|
||||
*
|
||||
*/
|
||||
|
||||
require_once('include/attach.php');
|
||||
|
||||
/**
|
||||
*
|
||||
* @param object &$a
|
||||
*/
|
||||
function filestorage_post(&$a) {
|
||||
|
||||
$channel_id = ((x($_POST,'uid')) ? intval($_POST['uid']) : 0);
|
||||
$channel_id = ((x($_POST, 'uid')) ? intval($_POST['uid']) : 0);
|
||||
|
||||
if((! $channel_id) || (! local_user()) || ($channel_id != local_user())) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$recurse = ((x($_POST,'recurse')) ? intval($_POST['recurse']) : 0);
|
||||
$resource = ((x($_POST,'filehash')) ? notags($_POST['filehash']) : '');
|
||||
$recurse = ((x($_POST, 'recurse')) ? intval($_POST['recurse']) : 0);
|
||||
$resource = ((x($_POST, 'filehash')) ? notags($_POST['filehash']) : '');
|
||||
|
||||
if(! $resource) {
|
||||
notice(t('Item not found.') . EOL);
|
||||
@ -24,11 +32,11 @@ function filestorage_post(&$a) {
|
||||
$str_group_deny = perms2str($_REQUEST['group_deny']);
|
||||
$str_contact_deny = perms2str($_REQUEST['contact_deny']);
|
||||
|
||||
attach_change_permissions($channel_id,$resource,$str_contact_allow,$str_group_allow,$str_contact_deny,$str_group_deny,$recurse = false);
|
||||
attach_change_permissions($channel_id, $resource, $str_contact_allow, $str_group_allow, $str_contact_deny,$str_group_deny, $recurse = false);
|
||||
|
||||
//Build directory tree and redirect
|
||||
$channel = $a->get_channel();
|
||||
$cloudPath = get_parent_cloudpath($channel_id, $channel['channel_address'], $resource) ;
|
||||
$cloudPath = get_parent_cloudpath($channel_id, $channel['channel_address'], $resource);
|
||||
goaway($cloudPath);
|
||||
}
|
||||
|
||||
@ -53,15 +61,15 @@ function filestorage_content(&$a) {
|
||||
$observer = $a->get_observer();
|
||||
$ob_hash = (($observer) ? $observer['xchan_hash'] : '');
|
||||
|
||||
$perms = get_all_perms($owner,$ob_hash);
|
||||
$perms = get_all_perms($owner, $ob_hash);
|
||||
|
||||
if(! $perms['view_storage']) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Since we have ACL'd files in the wild, but don't have ACL here yet, we
|
||||
// need to return for anyone other than the owner, despite the perms check for now.
|
||||
// Since we have ACL'd files in the wild, but don't have ACL here yet, we
|
||||
// need to return for anyone other than the owner, despite the perms check for now.
|
||||
|
||||
$is_owner = (((local_user()) && ($owner == local_user())) ? true : false);
|
||||
if(! $is_owner) {
|
||||
@ -69,7 +77,6 @@ function filestorage_content(&$a) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(argc() > 3 && argv(3) === 'delete') {
|
||||
if(! $perms['write_storage']) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
@ -77,7 +84,7 @@ function filestorage_content(&$a) {
|
||||
}
|
||||
|
||||
$file = intval(argv(2));
|
||||
$r = q("select hash from attach where id = %d and uid = %d limit 1",
|
||||
$r = q("SELECT hash FROM attach WHERE id = %d AND uid = %d LIMIT 1",
|
||||
dbesc($file),
|
||||
intval($owner)
|
||||
);
|
||||
@ -86,11 +93,15 @@ function filestorage_content(&$a) {
|
||||
goaway(z_root() . '/cloud/' . $which);
|
||||
}
|
||||
|
||||
attach_delete($owner,$r[0]['hash']);
|
||||
|
||||
goaway(z_root() . '/cloud/' . $which);
|
||||
}
|
||||
$f = $r[0];
|
||||
$channel = $a->get_channel();
|
||||
|
||||
$parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']);
|
||||
|
||||
attach_delete($owner, $f['hash']);
|
||||
|
||||
goaway($parentpath);
|
||||
}
|
||||
|
||||
if(argc() > 3 && argv(3) === 'edit') {
|
||||
require_once('include/acl_selectors.php');
|
||||
@ -106,18 +117,16 @@ function filestorage_content(&$a) {
|
||||
);
|
||||
|
||||
$f = $r[0];
|
||||
|
||||
$channel = $a->get_channel();
|
||||
|
||||
$cloudpath = get_cloudpath($f) . (($f['flags'] & ATTACH_FLAG_DIR) ? '?f=&davguest=1' : '');
|
||||
$parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']);
|
||||
|
||||
$aclselect_e = populate_acl($f,false);
|
||||
$aclselect_e = populate_acl($f, false);
|
||||
$is_a_dir = (($f['flags'] & ATTACH_FLAG_DIR) ? true : false);
|
||||
|
||||
$lockstate = (($f['allow_cid'] || $f['allow_gid'] || $f['deny_cid'] || $f['deny_gid']) ? 'lock' : 'unlock');
|
||||
|
||||
|
||||
$o = replace_macros(get_markup_template('attach_edit.tpl'), array(
|
||||
'$header' => t('Edit file permissions'),
|
||||
'$file' => $f,
|
||||
@ -135,12 +144,10 @@ function filestorage_content(&$a) {
|
||||
'$cpdesc' => t('Copy/paste this code to attach file to a post'),
|
||||
'$cpldesc' => t('Copy/paste this URL to link file from a web page'),
|
||||
'$submit' => t('Submit')
|
||||
|
||||
));
|
||||
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
goaway(z_root() . '/cloud/' . $which);
|
||||
|
||||
}
|
||||
|
@ -344,7 +344,7 @@ function import_post(&$a) {
|
||||
unset($group['id']);
|
||||
$group['uid'] = $channel['channel_id'];
|
||||
dbesc_array($group);
|
||||
$r = dbq("INSERT INTO group (`"
|
||||
$r = dbq("INSERT INTO groups (`"
|
||||
. implode("`, `", array_keys($group))
|
||||
. "`) VALUES ('"
|
||||
. implode("', '", array_values($group))
|
||||
|
90
mod/locs.php
Normal file
90
mod/locs.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php /** @file */
|
||||
|
||||
|
||||
/**
|
||||
Placeholder file at present. This is going to involve a bit of work.
|
||||
|
||||
This file will deal with the deletion of channels and management of hublocs.
|
||||
|
||||
We need to provide the following functionality:
|
||||
|
||||
- Delete my account and all channels from the entire network
|
||||
|
||||
- Delete my account and all channels from this server
|
||||
|
||||
- Delete a channel from the entire network
|
||||
|
||||
- Delete a channel from this server
|
||||
|
||||
- List all hub locations for this channel
|
||||
|
||||
- Remove this/some hub location from this channel
|
||||
|
||||
- promote this/some hub location to primary
|
||||
|
||||
- Remove hub location 'xyz' from this channel, (this should possibly only be allowed if that hub has been down for a period of time)
|
||||
|
||||
- Some of these actions should probably require email verification
|
||||
|
||||
*/
|
||||
|
||||
|
||||
function locs_post(&$a) {
|
||||
|
||||
if(! local_user())
|
||||
return;
|
||||
|
||||
$channel = $a->get_channel();
|
||||
|
||||
if($_REQUEST['primary']) {
|
||||
$hubloc_id = intval($_REQUEST['primary']);
|
||||
if($hubloc_id) {
|
||||
$r = q("select hubloc_id from hubloc where hubloc_id = %d and hubloc_hash = '%s' limit 1",
|
||||
intval($hubloc_id),
|
||||
dbesc($channel['channel_hash'])
|
||||
);
|
||||
if(! $r) {
|
||||
notice( t('Location not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
$r = q("update hubloc set hubloc_flags = (hubloc_flags ^ %d) where (hubloc_flags & %d) and hubloc_hash = '%s' ",
|
||||
intval(HUBLOC_FLAGS_PRIMARY),
|
||||
intval(HUBLOC_FLAGS_PRIMARY),
|
||||
dbesc($channel['channel_hash'])
|
||||
);
|
||||
$r = q("update hubloc set hubloc_flags = (hubloc_flags & %d) where hubloc_id = %d and hubloc_hash = '%s' limit 1",
|
||||
intval(HUBLOC_FLAGS_PRIMARY),
|
||||
intval($hubloc_id),
|
||||
dbesc($channel['channel_hash'])
|
||||
);
|
||||
proc_run('php','include/notifier.php','location',$channel['channel_id']);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if($_REQUEST['drop']) {
|
||||
$hubloc_id = intval($_REQUEST['drop']);
|
||||
if($hubloc_id) {
|
||||
$r = q("select hubloc_id, hubloc_flags from hubloc where hubloc_id = %d and hubloc_url != '%s' and hubloc_hash = '%s' limit 1",
|
||||
intval($hubloc_id),
|
||||
dbesc(z_root()),
|
||||
dbesc($channel['channel_hash'])
|
||||
);
|
||||
if(! $r) {
|
||||
notice( t('Location not found.') . EOL);
|
||||
return;
|
||||
}
|
||||
if($r[0]['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) {
|
||||
notice( t('Primary location cannot be removed.') . EOL);
|
||||
return;
|
||||
}
|
||||
$r = q("update hubloc set hubloc_flags = (hubloc_flags & %d) where hubloc_id = %d and hubloc_hash = '%s' limit 1",
|
||||
intval(HUBLOC_FLAGS_DELETED),
|
||||
intval($hubloc_id),
|
||||
dbesc($channel['channel_hash'])
|
||||
);
|
||||
proc_run('php','include/notifier.php','location',$channel['channel_id']);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
@ -999,7 +999,7 @@ function photos_content(&$a) {
|
||||
$comments = '';
|
||||
if(! count($r)) {
|
||||
if($can_post || $can_comment) {
|
||||
$comments .= replace_macros($cmnt_tpl,array(
|
||||
$commentbox = replace_macros($cmnt_tpl,array(
|
||||
'$return_path' => '',
|
||||
'$mode' => 'photos',
|
||||
'$jsreload' => $return_url,
|
||||
@ -1070,7 +1070,7 @@ function photos_content(&$a) {
|
||||
$body_e = prepare_text($item['body'],$item['mimetype']);
|
||||
|
||||
$comments .= replace_macros($template,array(
|
||||
'$id' => $item['item_id'],
|
||||
'$id' => $item['id'],
|
||||
'$mode' => 'photos',
|
||||
'$profile_url' => $profile_link,
|
||||
'$name' => $name_e,
|
||||
@ -1079,7 +1079,7 @@ function photos_content(&$a) {
|
||||
'$title' => $title_e,
|
||||
'$body' => $body_e,
|
||||
'$ago' => relative_date($item['created']),
|
||||
'$indent' => (($item['parent'] != $item['item_id']) ? ' comment' : ''),
|
||||
'$indent' => (($item['parent'] != $item['id']) ? ' comment' : ''),
|
||||
'$drop' => $drop,
|
||||
'$comment' => $comment
|
||||
));
|
||||
@ -1087,7 +1087,7 @@ function photos_content(&$a) {
|
||||
}
|
||||
|
||||
if($can_post || $can_comment) {
|
||||
$comments .= replace_macros($cmnt_tpl,array(
|
||||
$commentbox = replace_macros($cmnt_tpl,array(
|
||||
'$return_path' => '',
|
||||
'$jsreload' => $return_url,
|
||||
'$type' => 'wall-comment',
|
||||
@ -1129,6 +1129,7 @@ function photos_content(&$a) {
|
||||
'$like' => $like_e,
|
||||
'$dislike' => $dislike_e,
|
||||
'$comments' => $comments,
|
||||
'$commentbox' => $commentbox,
|
||||
'$paginate' => $paginate,
|
||||
));
|
||||
|
||||
|
@ -1 +1 @@
|
||||
2014-10-13.827
|
||||
2014-10-14.828
|
||||
|
@ -81,13 +81,8 @@
|
||||
|
||||
|
||||
/* group */
|
||||
input.group-edit-checkbox {
|
||||
margin: unset;
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
a.group-edit-link {
|
||||
a.group-edit-tool {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
@ -986,6 +986,7 @@ function updateConvItems(mode,data) {
|
||||
$('body').css('cursor', 'wait');
|
||||
$.get('contactgroup/' + gid + '/' + cid, function(data) {
|
||||
$('body').css('cursor', 'auto');
|
||||
$('#group-' + gid).toggleClass('icon-check icon-check-empty');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -5,16 +5,12 @@
|
||||
{{foreach $groups as $group}}
|
||||
<li>
|
||||
{{if $group.cid}}
|
||||
<a class="pull-right group-edit-link">
|
||||
<input type="checkbox"
|
||||
class="{{if $group.selected}}ticked{{else}}unticked {{/if}} group-edit-checkbox"
|
||||
onclick="contactgroupChangeMember('{{$group.id}}','{{$group.enc_cid}}');return true;"
|
||||
{{if $group.ismember}}checked="checked"{{/if}}
|
||||
/>
|
||||
<a class="pull-right group-edit-tool fakelink" onclick="contactgroupChangeMember('{{$group.id}}','{{$group.enc_cid}}'); return true;"/>
|
||||
<i id="group-{{$group.id}}" class="{{if $group.ismember}}icon-check{{else}}icon-check-empty{{/if}}"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{if $group.edit}}
|
||||
<a class="pull-right group-edit-link" href="{{$group.edit.href}}" title="{{$edittext}}"><i class="group-edit-icon icon-pencil"></i></a>
|
||||
<a class="pull-right group-edit-tool" href="{{$group.edit.href}}" title="{{$edittext}}"><i class="group-edit-icon icon-pencil"></i></a>
|
||||
{{/if}}
|
||||
<a{{if $group.selected}} class="group-selected"{{/if}} href="{{$group.href}}">{{$group.text}}</a>
|
||||
</li>
|
||||
|
@ -1,22 +1,27 @@
|
||||
<div class="wall-item-outside-wrapper{{$indent}}" id="wall-item-outside-wrapper-{{$id}}" >
|
||||
<div class="wall-item-photo-wrapper" id="wall-item-photo-wrapper-{{$id}}" >
|
||||
<a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-photo-link" id="wall-item-photo-link-{{$id}}">
|
||||
<img src="{{$thumb}}" class="wall-item-photo" id="wall-item-photo-{{$id}}" style="height: 80px; width: 80px;" alt="{{$name}}" /></a>
|
||||
</div>
|
||||
<div class="wall-item-outside-wrapper {{$indent}}" id="wall-item-outside-wrapper-{{$id}}" >
|
||||
<div class="wall-item-content-wrapper {{$indent}}" id="wall-item-content-wrapper-{{$id}}" style="clear:both;">
|
||||
<div class="wall-item-info" id="wall-item-info-{{$item.id}}" >
|
||||
<div class="wall-item-photo-wrapper" id="wall-item-photo-wrapper-{{$id}}" >
|
||||
<a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-photo-link" id="wall-item-photo-link-{{$id}}">
|
||||
<img src="{{$thumb}}" class="wall-item-photo" id="wall-item-photo-{{$id}}" style="height: 80px; width: 80px;" alt="{{$name}}" /></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wall-item-wrapper" id="wall-item-wrapper-{{$id}}" >
|
||||
<div class="wall-item-author">
|
||||
<a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-name-link"><span class="wall-item-name" id="wall-item-name-{{$id}}" >{{$name}}</span></a>
|
||||
</div>
|
||||
<div class="wall-item-ago" id="wall-item-ago-{{$id}}">{{$ago}}</div>
|
||||
</div>
|
||||
<div class="wall-item-content" id="wall-item-content-{{$id}}" >
|
||||
<div class="wall-item-title" id="wall-item-title-{{$id}}">{{$title}}</div>
|
||||
<div class="wall-item-body" id="wall-item-body-{{$id}}" >{{$body}}</div>
|
||||
</div>
|
||||
{{$drop}}
|
||||
<div class="wall-item-wrapper-end"></div>
|
||||
|
||||
<div class="wall-item-wrapper" id="wall-item-wrapper-{{$id}}" >
|
||||
<a href="{{$profile_url}}" title="View {{$name}}'s profile" class="wall-item-name-link"><span class="wall-item-name" id="wall-item-name-{{$id}}" >{{$name}}</span></a>
|
||||
<div class="wall-item-ago" id="wall-item-ago-{{$id}}">{{$ago}}</div>
|
||||
</div>
|
||||
<div class="wall-item-content" id="wall-item-content-{{$id}}" >
|
||||
<div class="wall-item-title" id="wall-item-title-{{$id}}">{{$title}}</div>
|
||||
<div class="wall-item-body" id="wall-item-body-{{$id}}" >{{$body}}</div>
|
||||
</div>
|
||||
{{$drop}}
|
||||
<div class="wall-item-wrapper-end"></div>
|
||||
<div class="wall-item-comment-separator"></div>
|
||||
{{$comment}}
|
||||
{{$comment}}
|
||||
|
||||
<div class="wall-item-outside-wrapper-end{{$indent}}" ></div>
|
||||
<div class="wall-item-outside-wrapper-end{{$indent}}" ></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -92,6 +92,10 @@
|
||||
|
||||
{{$comments}}
|
||||
|
||||
<div class="wall-item-comment-wrapper{{if $comments}} wall-item-comment-wrapper-wc{{/if}}" >
|
||||
{{$commentbox}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{if $nextlink}}<div id="photo-next-link"><a href="{{$nextlink.0}}"><i class="icon-forward photo-icons"></i></a></div>{{/if}}
|
||||
|
Reference in New Issue
Block a user