diff --git a/.gitignore b/.gitignore old mode 100755 new mode 100644 diff --git a/.htaccess b/.htaccess old mode 100755 new mode 100644 diff --git a/INSTALL.txt b/INSTALL.txt old mode 100755 new mode 100644 diff --git a/LICENSE b/LICENSE old mode 100755 new mode 100644 diff --git a/boot.php b/boot.php old mode 100755 new mode 100644 index 2f2e28ceb..1dd52fe7f --- a/boot.php +++ b/boot.php @@ -9,9 +9,9 @@ require_once('include/nav.php'); require_once('include/cache.php'); define ( 'FRIENDICA_PLATFORM', 'Friendica'); -define ( 'FRIENDICA_VERSION', '2.3.1299' ); +define ( 'FRIENDICA_VERSION', '2.3.1320' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); -define ( 'DB_UPDATE_VERSION', 1134 ); +define ( 'DB_UPDATE_VERSION', 1138 ); define ( 'EOL', "
\r\n" ); define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' ); @@ -20,14 +20,14 @@ define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' ); /** * * Image storage quality. Lower numbers save space at cost of image detail. - * For ease of upgrade, please do not change here. Change jpeg quality with - * $a->config['system']['jpeg_quality'] = n; - * in .htconfig.php, where n is netween 1 and 100, and with very poor results - * below about 50 + * For ease of upgrade, please do not change here. Change jpeg quality with + * $a->config['system']['jpeg_quality'] = n; + * in .htconfig.php, where n is netween 1 and 100, and with very poor results + * below about 50 * */ -define ( 'JPEG_QUALITY', 100 ); +define ( 'JPEG_QUALITY', 100 ); /** * SSL redirection policies @@ -68,7 +68,7 @@ define ( 'CONTACT_IS_FRIEND', 3); /** * Hook array order */ - + define ( 'HOOK_HOOK', 0); define ( 'HOOK_FILE', 1); define ( 'HOOK_FUNCTION', 2); @@ -79,9 +79,9 @@ define ( 'HOOK_FUNCTION', 2); * * PAGE_NORMAL is a typical personal profile account * PAGE_SOAPBOX automatically approves all friend requests as CONTACT_IS_SHARING, (readonly) - * PAGE_COMMUNITY automatically approves all friend requests as CONTACT_IS_SHARING, but with + * PAGE_COMMUNITY automatically approves all friend requests as CONTACT_IS_SHARING, but with * write access to wall and comments (no email and not included in page owner's ACL lists) - * PAGE_FREELOVE automatically approves all friend requests as full friends (CONTACT_IS_FRIEND). + * PAGE_FREELOVE automatically approves all friend requests as full friends (CONTACT_IS_FRIEND). * */ @@ -90,9 +90,10 @@ define ( 'PAGE_SOAPBOX', 1 ); define ( 'PAGE_COMMUNITY', 2 ); define ( 'PAGE_FREELOVE', 3 ); define ( 'PAGE_BLOG', 4 ); +define ( 'PAGE_PRVGROUP', 5 ); /** - * Network and protocol family types + * Network and protocol family types */ define ( 'NETWORK_DFRN', 'dfrn'); // Friendica, Mistpark, other DFRN implementations @@ -102,13 +103,13 @@ define ( 'NETWORK_FEED', 'feed'); // RSS/Atom feeds with no known define ( 'NETWORK_DIASPORA', 'dspr'); // Diaspora define ( 'NETWORK_MAIL', 'mail'); // IMAP/POP define ( 'NETWORK_MAIL2', 'mai2'); // extended IMAP/POP -define ( 'NETWORK_FACEBOOK', 'face'); // Facebook API +define ( 'NETWORK_FACEBOOK', 'face'); // Facebook API define ( 'NETWORK_LINKEDIN', 'lnkd'); // LinkedIn -define ( 'NETWORK_XMPP', 'xmpp'); // XMPP +define ( 'NETWORK_XMPP', 'xmpp'); // XMPP define ( 'NETWORK_MYSPACE', 'mysp'); // MySpace define ( 'NETWORK_GPLUS', 'goog'); // Google+ -/* +/** * These numbers are used in stored permissions * and existing allocations MUST NEVER BE CHANGED * OR RE-ASSIGNED! You may only add to them. @@ -165,7 +166,7 @@ define ( 'NOTIFY_SYSTEM', 0x8000 ); */ define ( 'NAMESPACE_ZOT', 'http://purl.org/macgirvin/zot' ); -define ( 'NAMESPACE_DFRN' , 'http://purl.org/macgirvin/dfrn/1.0' ); +define ( 'NAMESPACE_DFRN' , 'http://purl.org/macgirvin/dfrn/1.0' ); define ( 'NAMESPACE_THREAD' , 'http://purl.org/syndication/thread/1.0' ); define ( 'NAMESPACE_TOMB' , 'http://purl.org/atompub/tombstones/1.0' ); define ( 'NAMESPACE_ACTIVITY', 'http://activitystrea.ms/spec/1.0/' ); @@ -205,6 +206,7 @@ define ( 'ACTIVITY_OBJ_P_PHOTO', NAMESPACE_ACTIVITY_SCHEMA . 'profile-photo' ); define ( 'ACTIVITY_OBJ_ALBUM', NAMESPACE_ACTIVITY_SCHEMA . 'photo-album' ); define ( 'ACTIVITY_OBJ_EVENT', NAMESPACE_ACTIVITY_SCHEMA . 'event' ); define ( 'ACTIVITY_OBJ_TAGTERM', NAMESPACE_DFRN . '/tagterm' ); +define ( 'ACTIVITY_OBJ_PROFILE', NAMESPACE_DFRN . '/profile' ); /** * item weight for query ordering @@ -231,19 +233,19 @@ function startup() { if (get_magic_quotes_gpc()) { - $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST); - while (list($key, $val) = each($process)) { - foreach ($val as $k => $v) { - unset($process[$key][$k]); - if (is_array($v)) { - $process[$key][stripslashes($k)] = $v; - $process[] = &$process[$key][stripslashes($k)]; - } else { - $process[$key][stripslashes($k)] = stripslashes($v); - } - } - } - unset($process); + $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST); + while (list($key, $val) = each($process)) { + foreach ($val as $k => $v) { + unset($process[$key][$k]); + if (is_array($v)) { + $process[$key][stripslashes($k)] = $v; + $process[] = &$process[$key][stripslashes($k)]; + } else { + $process[$key][stripslashes($k)] = stripslashes($v); + } + } + } + unset($process); } } @@ -254,271 +256,278 @@ function startup() { * * Our main application structure for the life of this page * Primarily deals with the URL that got us here - * and tries to make some sense of it, and + * and tries to make some sense of it, and * stores our page contents and config storage - * and anything else that might need to be passed around - * before we spit the page out. + * and anything else that might need to be passed around + * before we spit the page out. * */ if(! class_exists('App')) { -class App { + class App { - public $module_loaded = false; - public $query_string; - public $config; - public $page; - public $profile; - public $user; - public $cid; - public $contact; - public $contacts; - public $page_contact; - public $content; - public $data = array(); - public $error = false; - public $cmd; - public $argv; - public $argc; - public $module; - public $pager; - public $strings; - public $path; - public $hooks; - public $timezone; - public $interactive = true; - public $plugins; - public $apps = array(); - public $identities; + public $module_loaded = false; + public $query_string; + public $config; + public $page; + public $profile; + public $user; + public $cid; + public $contact; + public $contacts; + public $page_contact; + public $content; + public $data = array(); + public $error = false; + public $cmd; + public $argv; + public $argc; + public $module; + public $pager; + public $strings; + public $path; + public $hooks; + public $timezone; + public $interactive = true; + public $plugins; + public $apps = array(); + public $identities; - public $nav_sel; + public $nav_sel; - private $scheme; - private $hostname; - private $baseurl; - private $db; + public $category; - private $curl_code; - private $curl_headers; + private $scheme; + private $hostname; + private $baseurl; + private $db; - function __construct() { + private $curl_code; + private $curl_headers; - $this->config = array(); - $this->page = array(); - $this->pager= array(); + function __construct() { - $this->query_string = ''; + $this->config = array(); + $this->page = array(); + $this->pager= array(); - startup(); + $this->query_string = ''; - $this->scheme = 'http'; - if(x($_SERVER,'HTTPS') && $_SERVER['HTTPS']) - $this->scheme = 'https'; - elseif(x($_SERVER,'SERVER_PORT') && (intval($_SERVER['SERVER_PORT']) == 443)) + startup(); + + $this->scheme = 'http'; + if(x($_SERVER,'HTTPS') && $_SERVER['HTTPS']) + $this->scheme = 'https'; + elseif(x($_SERVER,'SERVER_PORT') && (intval($_SERVER['SERVER_PORT']) == 443)) $this->scheme = 'https'; - if(x($_SERVER,'SERVER_NAME')) { - $this->hostname = $_SERVER['SERVER_NAME']; - if(x($_SERVER,'SERVER_PORT') && $_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) - $this->hostname .= ':' . $_SERVER['SERVER_PORT']; - /** - * Figure out if we are running at the top of a domain - * or in a sub-directory and adjust accordingly + if(x($_SERVER,'SERVER_NAME')) { + $this->hostname = $_SERVER['SERVER_NAME']; + if(x($_SERVER,'SERVER_PORT') && $_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) + $this->hostname .= ':' . $_SERVER['SERVER_PORT']; + /** + * Figure out if we are running at the top of a domain + * or in a sub-directory and adjust accordingly + */ + + $path = trim(dirname($_SERVER['SCRIPT_NAME']),'/\\'); + if(isset($path) && strlen($path) && ($path != $this->path)) + $this->path = $path; + } + + set_include_path( + "include/$this->hostname" . PATH_SEPARATOR + . 'include' . PATH_SEPARATOR + . 'library' . PATH_SEPARATOR + . 'library/phpsec' . PATH_SEPARATOR + . '.' ); + + if((x($_SERVER,'QUERY_STRING')) && substr($_SERVER['QUERY_STRING'],0,2) === "q=") { + $this->query_string = substr($_SERVER['QUERY_STRING'],2); + // removing trailing / - maybe a nginx problem + if (substr($this->query_string, 0, 1) == "/") + $this->query_string = substr($this->query_string, 1); + } + if(x($_GET,'q')) + $this->cmd = trim($_GET['q'],'/\\'); + + // unix style "homedir" + + if(substr($this->cmd,0,1) === '~') + $this->cmd = 'profile/' . substr($this->cmd,1); + + // Diaspora style profile url + + if(substr($this->cmd,0,2) === 'u/') + $this->cmd = 'profile/' . substr($this->cmd,2); + + /** + * + * Break the URL path into C style argc/argv style arguments for our + * modules. Given "http://example.com/module/arg1/arg2", $this->argc + * will be 3 (integer) and $this->argv will contain: + * [0] => 'module' + * [1] => 'arg1' + * [2] => 'arg2' + * + * + * There will always be one argument. If provided a naked domain + * URL, $this->argv[0] is set to "home". + * */ - $path = trim(dirname($_SERVER['SCRIPT_NAME']),'/\\'); - if(isset($path) && strlen($path) && ($path != $this->path)) - $this->path = $path; + $this->argv = explode('/',$this->cmd); + $this->argc = count($this->argv); + if((array_key_exists('0',$this->argv)) && strlen($this->argv[0])) { + $this->module = str_replace(".", "_", $this->argv[0]); + if(array_key_exists('2',$this->argv)) { + $this->category = $this->argv[2]; + } + } + else { + $this->argc = 1; + $this->argv = array('home'); + $this->module = 'home'; + } + + /** + * Special handling for the webfinger/lrdd host XRD file + */ + + if($this->cmd === '.well-known/host-meta') { + $this->argc = 1; + $this->argv = array('hostxrd'); + $this->module = 'hostxrd'; + } + + /** + * See if there is any page number information, and initialise + * pagination + */ + + $this->pager['page'] = ((x($_GET,'page')) ? $_GET['page'] : 1); + $this->pager['itemspage'] = 50; + $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage']; + $this->pager['total'] = 0; } - set_include_path( - "include/$this->hostname" . PATH_SEPARATOR - . 'include' . PATH_SEPARATOR - . 'library' . PATH_SEPARATOR - . 'library/phpsec' . PATH_SEPARATOR - . '.' ); + function get_baseurl($ssl = false) { - if((x($_SERVER,'QUERY_STRING')) && substr($_SERVER['QUERY_STRING'],0,2) === "q=") { - $this->query_string = substr($_SERVER['QUERY_STRING'],2); - // removing trailing / - maybe a nginx problem - if (substr($this->query_string, 0, 1) == "/") - $this->query_string = substr($this->query_string, 1); - } - if(x($_GET,'q')) - $this->cmd = trim($_GET['q'],'/\\'); + $scheme = $this->scheme; - // unix style "homedir" + if((x($this->config,'system')) && (x($this->config['system'],'ssl_policy'))) { + if(intval($this->config['system']['ssl_policy']) === intval(SSL_POLICY_FULL)) + $scheme = 'https'; - if(substr($this->cmd,0,1) === '~') - $this->cmd = 'profile/' . substr($this->cmd,1); + // We need to populate the $ssl flag across the entire program before turning this on. + // Basically, we'll have $ssl = true on any links which can only be seen by a logged in user + // (and also the login link). Anything seen by an outsider will have it turned off. + // At present, setting SSL_POLICY_SELFSIGN will only force remote contacts to update their + // contact links to this site with "http:" if they are currently using "https:" - // Diaspora style profile url - - if(substr($this->cmd,0,2) === 'u/') - $this->cmd = 'profile/' . substr($this->cmd,2); - - /** - * - * Break the URL path into C style argc/argv style arguments for our - * modules. Given "http://example.com/module/arg1/arg2", $this->argc - * will be 3 (integer) and $this->argv will contain: - * [0] => 'module' - * [1] => 'arg1' - * [2] => 'arg2' - * - * - * There will always be one argument. If provided a naked domain - * URL, $this->argv[0] is set to "home". - * - */ - - $this->argv = explode('/',$this->cmd); - $this->argc = count($this->argv); - if((array_key_exists('0',$this->argv)) && strlen($this->argv[0])) { - $this->module = str_replace(".", "_", $this->argv[0]); - } - else { - $this->argc = 1; - $this->argv = array('home'); - $this->module = 'home'; + // if($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) { + // if($ssl) + // $scheme = 'https'; + // else + // $scheme = 'http'; + // } } - /** - * Special handling for the webfinger/lrdd host XRD file - */ - - if($this->cmd === '.well-known/host-meta') { - $this->argc = 1; - $this->argv = array('hostxrd'); - $this->module = 'hostxrd'; + $this->baseurl = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' ); + return $this->baseurl; } - /** - * See if there is any page number information, and initialise - * pagination - */ + function set_baseurl($url) { + $parsed = @parse_url($url); - $this->pager['page'] = ((x($_GET,'page')) ? $_GET['page'] : 1); - $this->pager['itemspage'] = 50; - $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage']; - $this->pager['total'] = 0; - } + $this->baseurl = $url; - function get_baseurl($ssl = false) { + if($parsed) { + $this->scheme = $parsed['scheme']; - $scheme = $this->scheme; + $this->hostname = $parsed['host']; + if(x($parsed,'port')) + $this->hostname .= ':' . $parsed['port']; + if(x($parsed,'path')) + $this->path = trim($parsed['path'],'\\/'); + } - if((x($this->config,'system')) && (x($this->config['system'],'ssl_policy'))) { - if(intval($this->config['system']['ssl_policy']) === intval(SSL_POLICY_FULL)) - $scheme = 'https'; - -// We need to populate the $ssl flag across the entire program before turning this on. -// Basically, we'll have $ssl = true on any links which can only be seen by a logged in user -// (and also the login link). Anything seen by an outsider will have it turned off. -// At present, setting SSL_POLICY_SELFSIGN will only force remote contacts to update their -// contact links to this site with "http:" if they are currently using "https:" - -// if($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) { -// if($ssl) -// $scheme = 'https'; -// else -// $scheme = 'http'; -// } } - $this->baseurl = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' ); - return $this->baseurl; - } - - function set_baseurl($url) { - $parsed = @parse_url($url); - - $this->baseurl = $url; - - if($parsed) { - $this->scheme = $parsed['scheme']; - - $this->hostname = $parsed['host']; - if(x($parsed,'port')) - $this->hostname .= ':' . $parsed['port']; - if(x($parsed,'path')) - $this->path = trim($parsed['path'],'\\/'); + function get_hostname() { + return $this->hostname; } + function set_hostname($h) { + $this->hostname = $h; + } + + function set_path($p) { + $this->path = trim(trim($p),'/'); + } + + function get_path() { + return $this->path; + } + + function set_pager_total($n) { + $this->pager['total'] = intval($n); + } + + function set_pager_itemspage($n) { + $this->pager['itemspage'] = intval($n); + $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage']; + + } + + function init_pagehead() { + $interval = ((local_user()) ? get_pconfig(local_user(),'system','update_interval') : 40000); + if($interval < 10000) + $interval = 40000; + + $this->page['title'] = $this->config['sitename']; + $tpl = file_get_contents('view/head.tpl'); + $this->page['htmlhead'] = replace_macros($tpl,array( + '$baseurl' => $this->get_baseurl(), // FIXME for z_path!!!! + '$generator' => 'Friendica' . ' ' . FRIENDICA_VERSION, + '$delitem' => t('Delete this item?'), + '$comment' => t('Comment'), + '$showmore' => t('show more'), + '$showfewer' => t('show fewer'), + '$update_interval' => $interval + )); + } + + function set_curl_code($code) { + $this->curl_code = $code; + } + + function get_curl_code() { + return $this->curl_code; + } + + function set_curl_headers($headers) { + $this->curl_headers = $headers; + } + + function get_curl_headers() { + return $this->curl_headers; + } + + } - - function get_hostname() { - return $this->hostname; - } - - function set_hostname($h) { - $this->hostname = $h; - } - - function set_path($p) { - $this->path = trim(trim($p),'/'); - } - - function get_path() { - return $this->path; - } - - function set_pager_total($n) { - $this->pager['total'] = intval($n); - } - - function set_pager_itemspage($n) { - $this->pager['itemspage'] = intval($n); - $this->pager['start'] = ($this->pager['page'] * $this->pager['itemspage']) - $this->pager['itemspage']; - - } - - function init_pagehead() { - $interval = ((local_user()) ? get_pconfig(local_user(),'system','update_interval') : 40000); - if($interval < 10000) - $interval = 40000; - - $this->page['title'] = $this->config['sitename']; - $tpl = file_get_contents('view/head.tpl'); - $this->page['htmlhead'] = replace_macros($tpl,array( - '$baseurl' => $this->get_baseurl(), // FIXME for z_path!!!! - '$generator' => 'Friendica' . ' ' . FRIENDICA_VERSION, - '$delitem' => t('Delete this item?'), - '$comment' => t('Comment'), - '$showmore' => t('show more'), - '$showfewer' => t('show fewer'), - '$update_interval' => $interval - )); - } - - function set_curl_code($code) { - $this->curl_code = $code; - } - - function get_curl_code() { - return $this->curl_code; - } - - function set_curl_headers($headers) { - $this->curl_headers = $headers; - } - - function get_curl_headers() { - return $this->curl_headers; - } - - -}} +} // retrieve the App structure // useful in functions which require it but don't get it passed to them if(! function_exists('get_app')) { -function get_app() { - global $a; - return $a; -}}; + function get_app() { + global $a; + return $a; + } +}; // Multi-purpose function to check variable state. @@ -528,42 +537,44 @@ function get_app() { // e.g. x('') or x(0) returns 0; if(! function_exists('x')) { -function x($s,$k = NULL) { - if($k != NULL) { - if((is_array($s)) && (array_key_exists($k,$s))) { - if($s[$k]) - return (int) 1; - return (int) 0; + function x($s,$k = NULL) { + if($k != NULL) { + if((is_array($s)) && (array_key_exists($k,$s))) { + if($s[$k]) + return (int) 1; + return (int) 0; } - return false; - } - else { - if(isset($s)) { - if($s) { - return (int) 1; + return false; + } + else { + if(isset($s)) { + if($s) { + return (int) 1; + } + return (int) 0; } - return (int) 0; + return false; } - return false; } -}} +} // called from db initialisation if db is dead. if(! function_exists('system_unavailable')) { -function system_unavailable() { - include('system_unavailable.php'); - system_down(); - killme(); -}} + function system_unavailable() { + include('system_unavailable.php'); + system_down(); + killme(); + } +} function clean_urls() { global $a; -// if($a->config['system']['clean_urls']) - return true; -// return false; + // if($a->config['system']['clean_urls']) + return true; + // return false; } function z_path() { @@ -590,125 +601,150 @@ function is_ajax() { } -// Primarily involved with database upgrade, but also sets the +// Primarily involved with database upgrade, but also sets the // base url for use in cmdline programs which don't have // $_SERVER variables, and synchronising the state of installed plugins. if(! function_exists('check_config')) { -function check_config(&$a) { + function check_config(&$a) { - $build = get_config('system','build'); - if(! x($build)) - $build = set_config('system','build',DB_UPDATE_VERSION); + $build = get_config('system','build'); + if(! x($build)) + $build = set_config('system','build',DB_UPDATE_VERSION); - $url = get_config('system','url'); + $url = get_config('system','url'); - // if the url isn't set or the stored url is radically different - // than the currently visited url, store the current value accordingly. - // "Radically different" ignores common variations such as http vs https - // and www.example.com vs example.com. + // if the url isn't set or the stored url is radically different + // than the currently visited url, store the current value accordingly. + // "Radically different" ignores common variations such as http vs https + // and www.example.com vs example.com. - if((! x($url)) || (! link_compare($url,$a->get_baseurl()))) - $url = set_config('system','url',$a->get_baseurl()); + if((! x($url)) || (! link_compare($url,$a->get_baseurl()))) + $url = set_config('system','url',$a->get_baseurl()); - if($build != DB_UPDATE_VERSION) { - $stored = intval($build); - $current = intval(DB_UPDATE_VERSION); - if(($stored < $current) && file_exists('update.php')) { + if($build != DB_UPDATE_VERSION) { + $stored = intval($build); + $current = intval(DB_UPDATE_VERSION); + if(($stored < $current) && file_exists('update.php')) { - load_config('database'); + load_config('database'); - // We're reporting a different version than what is currently installed. - // Run any existing update scripts to bring the database up to current. + // We're reporting a different version than what is currently installed. + // Run any existing update scripts to bring the database up to current. - require_once('update.php'); + require_once('update.php'); - // make sure that boot.php and update.php are the same release, we might be - // updating right this very second and the correct version of the update.php - // file may not be here yet. This can happen on a very busy site. + // make sure that boot.php and update.php are the same release, we might be + // updating right this very second and the correct version of the update.php + // file may not be here yet. This can happen on a very busy site. - if(DB_UPDATE_VERSION == UPDATE_VERSION) { + if(DB_UPDATE_VERSION == UPDATE_VERSION) { - for($x = $stored; $x < $current; $x ++) { - if(function_exists('update_' . $x)) { + for($x = $stored; $x < $current; $x ++) { + if(function_exists('update_' . $x)) { - // There could be a lot of processes running or about to run. - // We want exactly one process to run the update command. - // So store the fact that we're taking responsibility - // after first checking to see if somebody else already has. + // There could be a lot of processes running or about to run. + // We want exactly one process to run the update command. + // So store the fact that we're taking responsibility + // after first checking to see if somebody else already has. - // If the update fails or times-out completely you may need to - // delete the config entry to try again. + // If the update fails or times-out completely you may need to + // delete the config entry to try again. - if(get_config('database','update_' . $x)) - break; - set_config('database','update_' . $x, '1'); + if(get_config('database','update_' . $x)) + break; + set_config('database','update_' . $x, '1'); - // call the specific update + // call the specific update - $func = 'update_' . $x; - $func($a); +// global $db; +// $db->excep(TRUE); +// try { +// $db->beginTransaction(); + $func = 'update_' . $x; + $func($a); +// $db->commit(); +// } catch(Exception $ex) { +// $db->rollback(); +// //send the administrator an e-mail +// $email_tpl = get_intltext_template("update_fail_eml.tpl"); +// $email_tpl = replace_macros($email_tpl, array( +// '$sitename' => $a->config['sitename'], +// '$siteurl' => $a->get_baseurl(), +// '$update' => $x, +// '$error' => $ex->getMessage())); +// $subject=sprintf(t('Update Error at %s'), $a->get_baseurl()); + +// mail($a->config['admin_email'], $subject, $text, +// 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" +// . 'Content-type: text/plain; charset=UTF-8' . "\n" +// . 'Content-transfer-encoding: 8bit' ); +// //try the logger +// logger('update failed: '.$ex->getMessage().EOL); +// } +// $db->excep(FALSE); + } } + set_config('system','build', DB_UPDATE_VERSION); } - set_config('system','build', DB_UPDATE_VERSION); } } - } - /** - * - * Synchronise plugins: - * - * $a->config['system']['addon'] contains a comma-separated list of names - * of plugins/addons which are used on this system. - * Go through the database list of already installed addons, and if we have - * an entry, but it isn't in the config list, call the uninstall procedure - * and mark it uninstalled in the database (for now we'll remove it). - * Then go through the config list and if we have a plugin that isn't installed, - * call the install procedure and add it to the database. - * - */ + /** + * + * Synchronise plugins: + * + * $a->config['system']['addon'] contains a comma-separated list of names + * of plugins/addons which are used on this system. + * Go through the database list of already installed addons, and if we have + * an entry, but it isn't in the config list, call the uninstall procedure + * and mark it uninstalled in the database (for now we'll remove it). + * Then go through the config list and if we have a plugin that isn't installed, + * call the install procedure and add it to the database. + * + */ - $r = q("SELECT * FROM `addon` WHERE `installed` = 1"); - if(count($r)) - $installed = $r; - else - $installed = array(); + $r = q("SELECT * FROM `addon` WHERE `installed` = 1"); + if(count($r)) + $installed = $r; + else + $installed = array(); - $plugins = get_config('system','addon'); - $plugins_arr = array(); + $plugins = get_config('system','addon'); + $plugins_arr = array(); - if($plugins) - $plugins_arr = explode(',',str_replace(' ', '',$plugins)); + if($plugins) + $plugins_arr = explode(',',str_replace(' ', '',$plugins)); - $a->plugins = $plugins_arr; + $a->plugins = $plugins_arr; - $installed_arr = array(); + $installed_arr = array(); - if(count($installed)) { - foreach($installed as $i) { - if(! in_array($i['name'],$plugins_arr)) { - uninstall_plugin($i['name']); + if(count($installed)) { + foreach($installed as $i) { + if(! in_array($i['name'],$plugins_arr)) { + uninstall_plugin($i['name']); } - else - $installed_arr[] = $i['name']; - } - } - - if(count($plugins_arr)) { - foreach($plugins_arr as $p) { - if(! in_array($p,$installed_arr)) { - install_plugin($p); + else + $installed_arr[] = $i['name']; } } + + if(count($plugins_arr)) { + foreach($plugins_arr as $p) { + if(! in_array($p,$installed_arr)) { + install_plugin($p); + } + } + } + + + load_hooks(); + + return; } - - - load_hooks(); - - return; -}} +} function get_guid($size=16) { @@ -729,116 +765,124 @@ function get_guid($size=16) { // returns the complete html for inserting into the page if(! function_exists('login')) { -function login($register = false, $hiddens=false) { - $a = get_app(); - $o = ""; - $reg = false; - if ($register) { - $reg = array( - 'title' => t('Create a New Account'), - 'desc' => t('Register') - ); - } + function login($register = false, $hiddens=false) { + $a = get_app(); + $o = ""; + $reg = false; + if ($register) { + $reg = array( + 'title' => t('Create a New Account'), + 'desc' => t('Register') + ); + } - $noid = get_config('system','no_openid'); + $noid = get_config('system','no_openid'); - $dest_url = $a->get_baseurl(true) . '/' . $a->query_string; + $dest_url = $a->get_baseurl(true) . '/' . $a->query_string; - if(local_user()) { - $tpl = get_markup_template("logout.tpl"); - } - else { - $tpl = get_markup_template("login.tpl"); - $_SESSION['return_url'] = $a->query_string; + if(local_user()) { + $tpl = get_markup_template("logout.tpl"); + } + else { + $tpl = get_markup_template("login.tpl"); + $_SESSION['return_url'] = $a->query_string; + } + + + $o .= replace_macros($tpl,array( + + '$dest_url' => $dest_url, + '$logout' => t('Logout'), + '$login' => t('Login'), + + '$lname' => array('username', t('Nickname or Email address: ') , '', ''), + '$lpassword' => array('password', t('Password: '), '', ''), + + '$openid' => !$noid, + '$lopenid' => array('openid_url', t('Or login using OpenID: '),'',''), + + '$hiddens' => $hiddens, + + '$register' => $reg, + + '$lostpass' => t('Forgot your password?'), + '$lostlink' => t('Password Reset'), + )); + + call_hooks('login_hook',$o); + + return $o; } +} - - $o .= replace_macros($tpl,array( - - '$dest_url' => $dest_url, - '$logout' => t('Logout'), - '$login' => t('Login'), - - '$lname' => array('username', t('Nickname or Email address: ') , '', ''), - '$lpassword' => array('password', t('Password: '), '', ''), - - '$openid' => !$noid, - '$lopenid' => array('openid_url', t('Or login using OpenID: '),'',''), - - '$hiddens' => $hiddens, - - '$register' => $reg, - - '$lostpass' => t('Forgot your password?'), - '$lostlink' => t('Password Reset'), - )); - - call_hooks('login_hook',$o); - - return $o; -}} - -// Used to end the current process, after saving session state. +// Used to end the current process, after saving session state. if(! function_exists('killme')) { -function killme() { - session_write_close(); - exit; -}} + function killme() { + session_write_close(); + exit; + } +} // redirect to another URL and terminate this process. if(! function_exists('goaway')) { -function goaway($s) { - header("Location: $s"); - killme(); -}} + function goaway($s) { + header("Location: $s"); + killme(); + } +} // Returns the uid of locally logged in user or false. if(! function_exists('local_user')) { -function local_user() { - if((x($_SESSION,'authenticated')) && (x($_SESSION,'uid'))) - return intval($_SESSION['uid']); - return false; -}} + function local_user() { + if((x($_SESSION,'authenticated')) && (x($_SESSION,'uid'))) + return intval($_SESSION['uid']); + return false; + } +} // Returns contact id of authenticated site visitor or false if(! function_exists('remote_user')) { -function remote_user() { - if((x($_SESSION,'authenticated')) && (x($_SESSION,'visitor_id'))) - return intval($_SESSION['visitor_id']); - return false; -}} + function remote_user() { + if((x($_SESSION,'authenticated')) && (x($_SESSION,'visitor_id'))) + return intval($_SESSION['visitor_id']); + return false; + } +} // contents of $s are displayed prominently on the page the next time // a page is loaded. Usually used for errors or alerts. if(! function_exists('notice')) { -function notice($s) { - $a = get_app(); - if(! x($_SESSION,'sysmsg')) $_SESSION['sysmsg'] = array(); - if($a->interactive) - $_SESSION['sysmsg'][] = $s; -}} + function notice($s) { + $a = get_app(); + if(! x($_SESSION,'sysmsg')) $_SESSION['sysmsg'] = array(); + if($a->interactive) + $_SESSION['sysmsg'][] = $s; + } +} if(! function_exists('info')) { -function info($s) { - $a = get_app(); - if(! x($_SESSION,'sysmsg_info')) $_SESSION['sysmsg_info'] = array(); - if($a->interactive) - $_SESSION['sysmsg_info'][] = $s; -}} + function info($s) { + $a = get_app(); + if(! x($_SESSION,'sysmsg_info')) $_SESSION['sysmsg_info'] = array(); + if($a->interactive) + $_SESSION['sysmsg_info'][] = $s; + } +} // wrapper around config to limit the text length of an incoming message if(! function_exists('get_max_import_size')) { -function get_max_import_size() { - global $a; - return ((x($a->config,'max_import_size')) ? $a->config['max_import_size'] : 0 ); -}} + function get_max_import_size() { + global $a; + return ((x($a->config,'max_import_size')) ? $a->config['max_import_size'] : 0 ); + } +} @@ -849,7 +893,7 @@ function get_max_import_size() { * @parameter string $nickname * @parameter int $profile * - * Summary: Loads a profile into the page sidebar. + * Summary: Loads a profile into the page sidebar. * The function requires a writeable copy of the main App structure, and the nickname * of a registered local account. * @@ -859,87 +903,90 @@ function get_max_import_size() { * by the owner. * * Profile information is placed in the App structure for later retrieval. - * Honours the owner's chosen theme for display. + * Honours the owner's chosen theme for display. * */ if(! function_exists('profile_load')) { -function profile_load(&$a, $nickname, $profile = 0) { - if(remote_user()) { - $r = q("SELECT `profile-id` FROM `contact` WHERE `id` = %d LIMIT 1", - intval($_SESSION['visitor_id'])); - if(count($r)) - $profile = $r[0]['profile-id']; - } + function profile_load(&$a, $nickname, $profile = 0) { + if(remote_user()) { + $r = q("SELECT `profile-id` FROM `contact` WHERE `id` = %d LIMIT 1", + intval($_SESSION['visitor_id'])); + if(count($r)) + $profile = $r[0]['profile-id']; + } - $r = null; + $r = null; - if($profile) { - $profile_int = intval($profile); - $r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `user`.* FROM `profile` - left join `contact` on `contact`.`uid` = `profile`.`uid` LEFT JOIN `user` ON `profile`.`uid` = `user`.`uid` - WHERE `user`.`nickname` = '%s' AND `profile`.`id` = %d and `contact`.`self` = 1 LIMIT 1", - dbesc($nickname), - intval($profile_int) - ); - } - if((! $r) && (! count($r))) { - $r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `user`.* FROM `profile` - left join `contact` on `contact`.`uid` = `profile`.`uid` LEFT JOIN `user` ON `profile`.`uid` = `user`.`uid` - WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` = 1 and `contact`.`self` = 1 LIMIT 1", - dbesc($nickname) - ); - } + if($profile) { + $profile_int = intval($profile); + $r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `user`.* FROM `profile` + left join `contact` on `contact`.`uid` = `profile`.`uid` LEFT JOIN `user` ON `profile`.`uid` = `user`.`uid` + WHERE `user`.`nickname` = '%s' AND `profile`.`id` = %d and `contact`.`self` = 1 LIMIT 1", + dbesc($nickname), + intval($profile_int) + ); + } + if((! $r) && (! count($r))) { + $r = q("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `user`.* FROM `profile` + left join `contact` on `contact`.`uid` = `profile`.`uid` LEFT JOIN `user` ON `profile`.`uid` = `user`.`uid` + WHERE `user`.`nickname` = '%s' AND `profile`.`is-default` = 1 and `contact`.`self` = 1 LIMIT 1", + dbesc($nickname) + ); + } + + if(($r === false) || (! count($r))) { + logger('profile error: ' . $a->query_string, LOGGER_DEBUG); + notice( t('Requested profile is not available.') . EOL ); + $a->error = 404; + return; + } + + // fetch user tags if this isn't the default profile + + if(! $r[0]['is-default']) { + $x = q("select `pub_keywords` from `profile` where uid = %d and `is-default` = 1 limit 1", + intval($profile_uid) + ); + if($x && count($x)) + $r[0]['pub_keywords'] = $x[0]['pub_keywords']; + } + + $a->profile = $r[0]; + + + $a->page['title'] = $a->profile['name'] . " @ " . $a->config['sitename']; + $_SESSION['theme'] = $a->profile['theme']; + + /** + * load/reload current theme info + */ + + $theme_info_file = "view/theme/".current_theme()."/theme.php"; + if (file_exists($theme_info_file)){ + require_once($theme_info_file); + } + + if(! (x($a->page,'aside'))) + $a->page['aside'] = ''; + + if(local_user() && local_user() == $a->profile['uid']) { + $a->page['aside'] .= replace_macros(get_markup_template('profile_edlink.tpl'),array( + '$editprofile' => t('Edit profile'), + '$profid' => $a->profile['id'] + )); + } + + $block = (((get_config('system','block_public')) && (! local_user()) && (! remote_user())) ? true : false); + + $a->page['aside'] .= profile_sidebar($a->profile, $block); + + /*if(! $block) + $a->page['aside'] .= contact_block();*/ - if(($r === false) || (! count($r))) { - notice( t('Requested profile is not available.') . EOL ); - $a->error = 404; return; } - - // fetch user tags if this isn't the default profile - - if(! $r[0]['is-default']) { - $x = q("select `pub_keywords` from `profile` where uid = %d and `is-default` = 1 limit 1", - intval($profile_uid) - ); - if($x && count($x)) - $r[0]['pub_keywords'] = $x[0]['pub_keywords']; - } - - $a->profile = $r[0]; - - - $a->page['title'] = $a->profile['name'] . " @ " . $a->config['sitename']; - $_SESSION['theme'] = $a->profile['theme']; - - /** - * load/reload current theme info - */ - $theme_info_file = "view/theme/".current_theme()."/theme.php"; - if (file_exists($theme_info_file)){ - require_once($theme_info_file); - } - - if(! (x($a->page,'aside'))) - $a->page['aside'] = ''; - - if(local_user() && local_user() == $a->profile['uid']) { - $a->page['aside'] .= replace_macros(get_markup_template('profile_edlink.tpl'),array( - '$editprofile' => t('Edit profile'), - '$profid' => $a->profile['id'] - )); - } - - $block = (((get_config('system','block_public')) && (! local_user()) && (! remote_user())) ? true : false); - - $a->page['aside'] .= profile_sidebar($a->profile, $block); - - /*if(! $block) - $a->page['aside'] .= contact_block();*/ - - return; -}} +} /** @@ -959,478 +1006,488 @@ function profile_load(&$a, $nickname, $profile = 0) { if(! function_exists('profile_sidebar')) { -function profile_sidebar($profile, $block = 0) { + function profile_sidebar($profile, $block = 0) { - $a = get_app(); + $a = get_app(); - $o = ''; - $location = false; - $address = false; - $pdesc = true; + $o = ''; + $location = false; + $address = false; + $pdesc = true; - if((! is_array($profile)) && (! count($profile))) - return $o; + if((! is_array($profile)) && (! count($profile))) + return $o; - $profile['picdate'] = urlencode($profile['picdate']); + $profile['picdate'] = urlencode($profile['picdate']); - call_hooks('profile_sidebar_enter', $profile); + call_hooks('profile_sidebar_enter', $profile); - // don't show connect link to yourself - $connect = (($profile['uid'] != local_user()) ? t('Connect') : False); + // don't show connect link to yourself + $connect = (($profile['uid'] != local_user()) ? t('Connect') : False); - // don't show connect link to authenticated visitors either + // don't show connect link to authenticated visitors either - if((remote_user()) && ($_SESSION['visitor_visiting'] == $profile['uid'])) - $connect = False; + if((remote_user()) && ($_SESSION['visitor_visiting'] == $profile['uid'])) + $connect = False; - if(get_my_url() && $profile['unkmail']) - $wallmessage = t('Message'); - else - $wallmessage = false; + if(get_my_url() && $profile['unkmail']) + $wallmessage = t('Message'); + else + $wallmessage = false; - // show edit profile to yourself - if ($profile['uid'] == local_user()) { - $profile['edit'] = array($a->get_baseurl(). '/profiles', t('Profiles'),"", t('Manage/edit profiles')); + // show edit profile to yourself + if ($profile['uid'] == local_user()) { + $profile['edit'] = array($a->get_baseurl(). '/profiles', t('Profiles'),"", t('Manage/edit profiles')); - $r = q("SELECT * FROM `profile` WHERE `uid` = %d", - local_user()); + $r = q("SELECT * FROM `profile` WHERE `uid` = %d", + local_user()); - $profile['menu'] = array( - 'chg_photo' => t('Change profile photo'), - 'cr_new' => t('Create New Profile'), - 'entries' => array(), - ); - - if(count($r)) { + $profile['menu'] = array( + 'chg_photo' => t('Change profile photo'), + 'cr_new' => t('Create New Profile'), + 'entries' => array(), + ); + + if(count($r)) { + + foreach($r as $rr) { + $profile['menu']['entries'][] = array( + 'photo' => $rr['thumb'], + 'id' => $rr['id'], + 'alt' => t('Profile Image'), + 'profile_name' => $rr['profile-name'], + 'isdefault' => $rr['is-default'], + 'visibile_to_everybody' => t('visible to everybody'), + 'edit_visibility' => t('Edit visibility'), + + ); + } + - foreach($r as $rr) { - $profile['menu']['entries'][] = array( - 'photo' => $rr['thumb'], - 'id' => $rr['id'], - 'alt' => t('Profile Image'), - 'profile_name' => $rr['profile-name'], - 'isdefault' => $rr['is-default'], - 'visibile_to_everybody' => t('visible to everybody'), - 'edit_visibility' => t('Edit visibility'), - - ); } } - - - } - if((x($profile,'address') == 1) - || (x($profile,'locality') == 1) - || (x($profile,'region') == 1) - || (x($profile,'postal-code') == 1) - || (x($profile,'country-name') == 1)) - $location = t('Location:'); + if((x($profile,'address') == 1) + || (x($profile,'locality') == 1) + || (x($profile,'region') == 1) + || (x($profile,'postal-code') == 1) + || (x($profile,'country-name') == 1)) + $location = t('Location:'); - $gender = ((x($profile,'gender') == 1) ? t('Gender:') : False); + $gender = ((x($profile,'gender') == 1) ? t('Gender:') : False); - $marital = ((x($profile,'marital') == 1) ? t('Status:') : False); + $marital = ((x($profile,'marital') == 1) ? t('Status:') : False); - $homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False); + $homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False); - if(($profile['hidewall'] || $block) && (! local_user()) && (! remote_user())) { - $location = $pdesc = $gender = $marital = $homepage = False; + if(($profile['hidewall'] || $block) && (! local_user()) && (! remote_user())) { + $location = $pdesc = $gender = $marital = $homepage = False; + } + + $firstname = ((strpos($profile['name'],' ')) + ? trim(substr($profile['name'],0,strpos($profile['name'],' '))) : $profile['name']); + $lastname = (($firstname === $profile['name']) ? '' : trim(substr($profile['name'],strlen($firstname)))); + + $diaspora = array( + 'podloc' => $a->get_baseurl(), + 'searchable' => (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' ), + 'nickname' => $profile['nickname'], + 'fullname' => $profile['name'], + 'firstname' => $firstname, + 'lastname' => $lastname, + 'photo300' => $a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg', + 'photo100' => $a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg', + 'photo50' => $a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg', + ); + + if (!$block){ + $contact_block = contact_block(); + } + + + $tpl = get_markup_template('profile_vcard.tpl'); + + $o .= replace_macros($tpl, array( + '$profile' => $profile, + '$connect' => $connect, + '$wallmessage' => $wallmessage, + '$location' => template_escape($location), + '$gender' => $gender, + '$pdesc' => $pdesc, + '$marital' => $marital, + '$homepage' => $homepage, + '$diaspora' => $diaspora, + '$contact_block' => $contact_block, + )); + + + $arr = array('profile' => &$profile, 'entry' => &$o); + + call_hooks('profile_sidebar', $arr); + + return $o; } - - $firstname = ((strpos($profile['name'],' ')) - ? trim(substr($profile['name'],0,strpos($profile['name'],' '))) : $profile['name']); - $lastname = (($firstname === $profile['name']) ? '' : trim(substr($profile['name'],strlen($firstname)))); - - $diaspora = array( - 'podloc' => $a->get_baseurl(), - 'searchable' => (($profile['publish'] && $profile['net-publish']) ? 'true' : 'false' ), - 'nickname' => $profile['nickname'], - 'fullname' => $profile['name'], - 'firstname' => $firstname, - 'lastname' => $lastname, - 'photo300' => $a->get_baseurl() . '/photo/custom/300/' . $profile['uid'] . '.jpg', - 'photo100' => $a->get_baseurl() . '/photo/custom/100/' . $profile['uid'] . '.jpg', - 'photo50' => $a->get_baseurl() . '/photo/custom/50/' . $profile['uid'] . '.jpg', - ); - - if (!$block){ - $contact_block = contact_block(); - } - - - $tpl = get_markup_template('profile_vcard.tpl'); - - $o .= replace_macros($tpl, array( - '$profile' => $profile, - '$connect' => $connect, - '$wallmessage' => $wallmessage, - '$location' => template_escape($location), - '$gender' => $gender, - '$pdesc' => $pdesc, - '$marital' => $marital, - '$homepage' => $homepage, - '$diaspora' => $diaspora, - '$contact_block' => $contact_block, - )); - - - $arr = array('profile' => &$profile, 'entry' => &$o); - - call_hooks('profile_sidebar', $arr); - - return $o; -}} +} if(! function_exists('get_birthdays')) { -function get_birthdays() { + function get_birthdays() { - $a = get_app(); - $o = ''; + $a = get_app(); + $o = ''; - if(! local_user()) - return $o; + if(! local_user()) + return $o; - $bd_format = t('g A l F d') ; // 8 AM Friday January 18 - $bd_short = t('F d'); + $bd_format = t('g A l F d') ; // 8 AM Friday January 18 + $bd_short = t('F d'); - $r = q("SELECT `event`.*, `event`.`id` AS `eid`, `contact`.* FROM `event` - LEFT JOIN `contact` ON `contact`.`id` = `event`.`cid` - WHERE `event`.`uid` = %d AND `type` = 'birthday' AND `start` < '%s' AND `finish` > '%s' - ORDER BY `start` ASC ", - intval(local_user()), - dbesc(datetime_convert('UTC','UTC','now + 6 days')), - dbesc(datetime_convert('UTC','UTC','now')) - ); + $r = q("SELECT `event`.*, `event`.`id` AS `eid`, `contact`.* FROM `event` + LEFT JOIN `contact` ON `contact`.`id` = `event`.`cid` + WHERE `event`.`uid` = %d AND `type` = 'birthday' AND `start` < '%s' AND `finish` > '%s' + ORDER BY `start` ASC ", + intval(local_user()), + dbesc(datetime_convert('UTC','UTC','now + 6 days')), + dbesc(datetime_convert('UTC','UTC','now')) + ); - if($r && count($r)) { - $total = 0; - $now = strtotime('now'); - $cids = array(); + if($r && count($r)) { + $total = 0; + $now = strtotime('now'); + $cids = array(); - $istoday = false; - foreach($r as $rr) { - if(strlen($rr['name'])) - $total ++; + $istoday = false; + foreach($r as $rr) { + if(strlen($rr['name'])) + $total ++; if((strtotime($rr['start'] . ' +00:00') < $now) && (strtotime($rr['finish'] . ' +00:00') > $now)) $istoday = true; + } + $classtoday = $istoday ? ' birthday-today ' : ''; + if($total) { + $o .= '
' . t('Birthday Reminders') . ' ' . '(' . $total . ')' . '
'; + $o .= ''; + } } - $classtoday = $istoday ? ' birthday-today ' : ''; - if($total) { - $o .= '
' . t('Birthday Reminders') . ' ' . '(' . $total . ')' . '
'; - $o .= ''; } - - return $o; -}} +} /** - * + * * Wrap calls to proc_close(proc_open()) and call hook * so plugins can take part in process :) - * + * * args: * $cmd program to run * next args are passed as $cmd command line - * + * * e.g.: proc_run("ls","-la","/tmp"); - * + * * $cmd and string args are surrounded with "" */ if(! function_exists('proc_run')) { -function proc_run($cmd){ + function proc_run($cmd){ - $a = get_app(); + $a = get_app(); - $args = func_get_args(); - $arr = array('args' => $args, 'run_cmd' => true); + $args = func_get_args(); + $arr = array('args' => $args, 'run_cmd' => true); - call_hooks("proc_run", $arr); - if(! $arr['run_cmd']) - return; + call_hooks("proc_run", $arr); + if(! $arr['run_cmd']) + return; - if(count($args) && $args[0] === 'php') - $args[0] = ((x($a->config,'php_path')) && (strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php'); - foreach ($args as $arg){ - $arg = escapeshellarg($arg); + if(count($args) && $args[0] === 'php') + $args[0] = ((x($a->config,'php_path')) && (strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php'); + foreach ($args as $arg){ + $arg = escapeshellarg($arg); + } + $cmdline = implode($args," "); + proc_close(proc_open($cmdline." &",array(),$foo)); } - $cmdline = implode($args," "); - proc_close(proc_open($cmdline." &",array(),$foo)); -}} +} if(! function_exists('current_theme')) { -function current_theme(){ - $app_base_themes = array('duepuntozero', 'loozah'); + function current_theme(){ + $app_base_themes = array('duepuntozero', 'loozah'); - $a = get_app(); + $a = get_app(); - $system_theme = ((isset($a->config['system']['theme'])) ? $a->config['system']['theme'] : ''); - $theme_name = ((isset($_SESSION) && x($_SESSION,'theme')) ? $_SESSION['theme'] : $system_theme); + $system_theme = ((isset($a->config['system']['theme'])) ? $a->config['system']['theme'] : ''); + $theme_name = ((isset($_SESSION) && x($_SESSION,'theme')) ? $_SESSION['theme'] : $system_theme); - if($theme_name && - (file_exists('view/theme/' . $theme_name . '/style.css') || - file_exists('view/theme/' . $theme_name . '/style.php'))) - return($theme_name); + if($theme_name && + (file_exists('view/theme/' . $theme_name . '/style.css') || + file_exists('view/theme/' . $theme_name . '/style.php'))) + return($theme_name); + + foreach($app_base_themes as $t) { + if(file_exists('view/theme/' . $t . '/style.css')|| + file_exists('view/theme/' . $t . '/style.php')) + return($t); + } + + $fallback = glob('view/theme/*/style.[css|php]'); + if(count($fallback)) + return (str_replace('view/theme/','', substr($fallback[0],0,-10))); - foreach($app_base_themes as $t) { - if(file_exists('view/theme/' . $t . '/style.css')|| - file_exists('view/theme/' . $t . '/style.php')) - return($t); } - - $fallback = glob('view/theme/*/style.[css|php]'); - if(count($fallback)) - return (str_replace('view/theme/','', substr($fallback[0],0,-10))); - -}} +} /* -* Return full URL to theme which is currently in effect. + * Return full URL to theme which is currently in effect. * Provide a sane default if nothing is chosen or the specified theme does not exist. */ if(! function_exists('current_theme_url')) { -function current_theme_url() { - global $a; - $t = current_theme(); - if (file_exists('view/theme/' . $t . '/style.php')) - return($a->get_baseurl() . '/view/theme/' . $t . '/style.pcss'); - return($a->get_baseurl() . '/view/theme/' . $t . '/style.css'); -}} + function current_theme_url() { + global $a; + $t = current_theme(); + if (file_exists('view/theme/' . $t . '/style.php')) + return($a->get_baseurl() . '/view/theme/' . $t . '/style.pcss'); + return($a->get_baseurl() . '/view/theme/' . $t . '/style.css'); + } +} if(! function_exists('feed_birthday')) { -function feed_birthday($uid,$tz) { + function feed_birthday($uid,$tz) { - /** - * - * Determine the next birthday, but only if the birthday is published - * in the default profile. We _could_ also look for a private profile that the - * recipient can see, but somebody could get mad at us if they start getting - * public birthday greetings when they haven't made this info public. - * - * Assuming we are able to publish this info, we are then going to convert - * the start time from the owner's timezone to UTC. - * - * This will potentially solve the problem found with some social networks - * where birthdays are converted to the viewer's timezone and salutations from - * elsewhere in the world show up on the wrong day. We will convert it to the - * viewer's timezone also, but first we are going to convert it from the birthday - * person's timezone to GMT - so the viewer may find the birthday starting at - * 6:00PM the day before, but that will correspond to midnight to the birthday person. - * - */ + /** + * + * Determine the next birthday, but only if the birthday is published + * in the default profile. We _could_ also look for a private profile that the + * recipient can see, but somebody could get mad at us if they start getting + * public birthday greetings when they haven't made this info public. + * + * Assuming we are able to publish this info, we are then going to convert + * the start time from the owner's timezone to UTC. + * + * This will potentially solve the problem found with some social networks + * where birthdays are converted to the viewer's timezone and salutations from + * elsewhere in the world show up on the wrong day. We will convert it to the + * viewer's timezone also, but first we are going to convert it from the birthday + * person's timezone to GMT - so the viewer may find the birthday starting at + * 6:00PM the day before, but that will correspond to midnight to the birthday person. + * + */ - $birthday = ''; + $birthday = ''; - if(! strlen($tz)) - $tz = 'UTC'; + if(! strlen($tz)) + $tz = 'UTC'; - $p = q("SELECT `dob` FROM `profile` WHERE `is-default` = 1 AND `uid` = %d LIMIT 1", - intval($uid) - ); + $p = q("SELECT `dob` FROM `profile` WHERE `is-default` = 1 AND `uid` = %d LIMIT 1", + intval($uid) + ); - if($p && count($p)) { - $tmp_dob = substr($p[0]['dob'],5); - if(intval($tmp_dob)) { - $y = datetime_convert($tz,$tz,'now','Y'); - $bd = $y . '-' . $tmp_dob . ' 00:00'; - $t_dob = strtotime($bd); - $now = strtotime(datetime_convert($tz,$tz,'now')); - if($t_dob < $now) - $bd = $y + 1 . '-' . $tmp_dob . ' 00:00'; - $birthday = datetime_convert($tz,'UTC',$bd,ATOM_TIME); + if($p && count($p)) { + $tmp_dob = substr($p[0]['dob'],5); + if(intval($tmp_dob)) { + $y = datetime_convert($tz,$tz,'now','Y'); + $bd = $y . '-' . $tmp_dob . ' 00:00'; + $t_dob = strtotime($bd); + $now = strtotime(datetime_convert($tz,$tz,'now')); + if($t_dob < $now) + $bd = $y + 1 . '-' . $tmp_dob . ' 00:00'; + $birthday = datetime_convert($tz,'UTC',$bd,ATOM_TIME); + } } - } - return $birthday; -}} + return $birthday; + } +} if(! function_exists('is_site_admin')) { -function is_site_admin() { - $a = get_app(); - if(local_user() && x($a->user,'email') && x($a->config,'admin_email') && ($a->user['email'] === $a->config['admin_email'])) - return true; - return false; -}} + function is_site_admin() { + $a = get_app(); + if(local_user() && x($a->user,'email') && x($a->config,'admin_email') && ($a->user['email'] === $a->config['admin_email'])) + return true; + return false; + } +} if(! function_exists('load_contact_links')) { -function load_contact_links($uid) { + function load_contact_links($uid) { - $a = get_app(); + $a = get_app(); - $ret = array(); + $ret = array(); - if(! $uid || x($a->contacts,'empty')) - return; + if(! $uid || x($a->contacts,'empty')) + return; - $r = q("SELECT `id`,`network`,`url`,`thumb` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 ", - intval($uid) - ); - if(count($r)) { - foreach($r as $rr){ - $url = normalise_link($rr['url']); - $ret[$url] = $rr; + $r = q("SELECT `id`,`network`,`url`,`thumb` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 ", + intval($uid) + ); + if(count($r)) { + foreach($r as $rr){ + $url = normalise_link($rr['url']); + $ret[$url] = $rr; + } } + else + $ret['empty'] = true; + $a->contacts = $ret; + return; } - else - $ret['empty'] = true; - $a->contacts = $ret; - return; -}} +} if(! function_exists('profile_tabs')){ -function profile_tabs($a, $is_owner=False, $nickname=Null){ - //echo "
"; var_dump($a->user); killme();
+	function profile_tabs($a, $is_owner=False, $nickname=Null){
+		//echo "
"; var_dump($a->user); killme();
 	
-	if (is_null($nickname))
-		$nickname  = $a->user['nickname'];
+		if (is_null($nickname))
+			$nickname  = $a->user['nickname'];
 		
-	if(x($_GET,'tab'))
-		$tab = notags(trim($_GET['tab']));
+		if(x($_GET,'tab'))
+			$tab = notags(trim($_GET['tab']));
 	
-	$url = $a->get_baseurl() . '/profile/' . $nickname;
+		$url = $a->get_baseurl() . '/profile/' . $nickname;
 
-	$tabs = array(
-		array(
-			'label'=>t('Status'),
-			'url' => $url,
-			'sel' => ((!isset($tab)&&$a->argv[0]=='profile')?'active':''),
-		),
-		array(
-			'label' => t('Profile'),
-			'url' 	=> $url.'/?tab=profile',
-			'sel'	=> ((isset($tab) && $tab=='profile')?'active':''),
-		),
-		array(
-			'label' => t('Photos'),
-			'url'	=> $a->get_baseurl() . '/photos/' . $nickname,
-			'sel'	=> ((!isset($tab)&&$a->argv[0]=='photos')?'active':''),
-		),
-	);
+		$tabs = array(
+			array(
+				'label'=>t('Status'),
+				'url' => $url,
+				'sel' => ((!isset($tab)&&$a->argv[0]=='profile')?'active':''),
+			),
+			array(
+				'label' => t('Profile'),
+				'url' 	=> $url.'/?tab=profile',
+				'sel'	=> ((isset($tab) && $tab=='profile')?'active':''),
+			),
+			array(
+				'label' => t('Photos'),
+				'url'	=> $a->get_baseurl() . '/photos/' . $nickname,
+				'sel'	=> ((!isset($tab)&&$a->argv[0]=='photos')?'active':''),
+			),
+		);
 	
-	if ($is_owner){
-		 $tabs[] = array(
-			'label' => t('Events'),
-			'url'	=> $a->get_baseurl() . '/events',
-			'sel' 	=>((!isset($tab)&&$a->argv[0]=='events')?'active':''),
-		);
-		$tabs[] = array(
-			'label' => t('Personal Notes'),
-			'url'	=> $a->get_baseurl() . '/notes',
-			'sel' 	=>((!isset($tab)&&$a->argv[0]=='notes')?'active':''),
-		);
+		if ($is_owner){
+			$tabs[] = array(
+				'label' => t('Events'),
+				'url'	=> $a->get_baseurl() . '/events',
+				'sel' 	=>((!isset($tab)&&$a->argv[0]=='events')?'active':''),
+			);
+			$tabs[] = array(
+				'label' => t('Personal Notes'),
+				'url'	=> $a->get_baseurl() . '/notes',
+				'sel' 	=>((!isset($tab)&&$a->argv[0]=='notes')?'active':''),
+			);
+		}
+
+
+		$arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs);
+		call_hooks('profile_tabs', $arr);
+	
+		$tpl = get_markup_template('common_tabs.tpl');
+
+		return replace_macros($tpl,array('$tabs' => $arr['tabs']));
 	}
-
-
-	$arr = array('is_owner' => $is_owner, 'nickname' => $nickname, 'tab' => (($tab) ? $tab : false), 'tabs' => $tabs);
-	call_hooks('profile_tabs', $arr);
-	
-	$tpl = get_markup_template('common_tabs.tpl');
-
-	return replace_macros($tpl,array('$tabs' => $arr['tabs']));
-}}	
+}
 
 function get_my_url() {
 	if(x($_SESSION,'my_url'))
@@ -1438,11 +1495,13 @@ function get_my_url() {
 	return false;
 }
 
-function zrl($s) {
+function zrl($s,$force = false) {
 	if(! strlen($s))
 		return $s;
-	if(! strpos($s,'/profile/'))
-		return $s;	
+	if((! strpos($s,'/profile/')) && (! $force))
+		return $s;
+	if($force && substr($s,-1,1) !== '/')
+		$s = $s . '/';
 	$achar = strpos($s,'?') ? '&' : '?';
 	$mine = get_my_url();
 	if($mine and ! link_compare($mine,$s))
diff --git a/database.sql b/database.sql
old mode 100755
new mode 100644
index a271e5491..eadb53cc6
--- a/database.sql
+++ b/database.sql
@@ -1,19 +1,77 @@
 -- phpMyAdmin SQL Dump
--- version 2.11.9.4
+-- version 3.3.10.4
 -- http://www.phpmyadmin.net
 --
 
 SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
 
-
-/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
-/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
-/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
-/*!40101 SET NAMES utf8 */;
+-- --------------------------------------------------------
 
 --
+-- Table structure for table `addon`
 --
 
+CREATE TABLE IF NOT EXISTS `addon` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` char(255) NOT NULL,
+  `version` char(255) NOT NULL,
+  `installed` tinyint(1) NOT NULL DEFAULT '0',
+  `timestamp` bigint(20) NOT NULL DEFAULT '0',
+  `plugin_admin` tinyint(1) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `attach`
+--
+
+CREATE TABLE IF NOT EXISTS `attach` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `uid` int(11) NOT NULL,
+  `hash` char(64) NOT NULL,
+  `filename` char(255) NOT NULL,
+  `filetype` char(64) NOT NULL,
+  `filesize` int(11) NOT NULL,
+  `data` longblob NOT NULL,
+  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `allow_cid` mediumtext NOT NULL,
+  `allow_gid` mediumtext NOT NULL,
+  `deny_cid` mediumtext NOT NULL,
+  `deny_gid` mediumtext NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `auth_codes`
+--
+
+CREATE TABLE IF NOT EXISTS `auth_codes` (
+  `id` varchar(40) NOT NULL,
+  `client_id` varchar(20) NOT NULL,
+  `redirect_uri` varchar(200) NOT NULL,
+  `expires` int(11) NOT NULL,
+  `scope` varchar(250) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `cache`
+--
+
+CREATE TABLE IF NOT EXISTS `cache` (
+  `k` char(255) NOT NULL,
+  `v` text NOT NULL,
+  `updated` datetime NOT NULL,
+  PRIMARY KEY (`k`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
 -- --------------------------------------------------------
 
 --
@@ -32,16 +90,36 @@ CREATE TABLE IF NOT EXISTS `challenge` (
 
 -- --------------------------------------------------------
 
-CREATE TABLE IF NOT EXISTS `config` (
-  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
-  `cat` char(255) NOT NULL,
-  `k` char(255) NOT NULL,
-  `v` text NOT NULL,
-  PRIMARY KEY (`id`)
+--
+-- Table structure for table `clients`
+--
+
+CREATE TABLE IF NOT EXISTS `clients` (
+  `client_id` varchar(20) NOT NULL,
+  `pw` varchar(20) NOT NULL,
+  `redirect_uri` varchar(200) NOT NULL,
+  `name` text,
+  `icon` text,
+  `uid` int(11) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`client_id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
+-- --------------------------------------------------------
 
+--
+-- Table structure for table `config`
+--
 
+CREATE TABLE IF NOT EXISTS `config` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `cat` char(255) CHARACTER SET ascii NOT NULL,
+  `k` char(255) CHARACTER SET ascii NOT NULL,
+  `v` text NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `access` (`cat`,`k`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
 
 --
 -- Table structure for table `contact`
@@ -51,7 +129,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `uid` int(11) NOT NULL COMMENT 'owner uid',
   `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
-  `self` tinyint(1) NOT NULL DEFAULT '0',
+  `self` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'boolean 1 == info for local UID, primarily name and photo to use in item displays.',
   `remote_self` tinyint(1) NOT NULL DEFAULT '0',
   `rel` tinyint(1) NOT NULL DEFAULT '0',
   `duplex` tinyint(1) NOT NULL DEFAULT '0',
@@ -59,7 +137,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
   `name` char(255) NOT NULL,
   `nick` char(255) NOT NULL,
   `attag` char(255) NOT NULL,
-  `photo` text NOT NULL, 
+  `photo` text NOT NULL COMMENT 'remote photo URL initially until approved',
   `thumb` text NOT NULL,
   `micro` text NOT NULL,
   `site-pubkey` text NOT NULL,
@@ -95,32 +173,219 @@ CREATE TABLE IF NOT EXISTS `contact` (
   `forum` tinyint(1) NOT NULL DEFAULT '0',
   `hidden` tinyint(1) NOT NULL DEFAULT '0',
   `pending` tinyint(1) NOT NULL DEFAULT '1',
-  `rating` tinyint(1) NOT NULL DEFAULT '0',
-  `reason` text NOT NULL,
+  `rating` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0-5 reputation, 0 unknown, 1 call police, 5 inscrutable',
+  `reason` text NOT NULL COMMENT 'why a rating was given - will help friends decide to make friends or not',
   `closeness` tinyint(2) NOT NULL DEFAULT '99',
   `info` mediumtext NOT NULL,
-  `profile-id` int(11) NOT NULL DEFAULT '0',
-  `bdyear` CHAR( 4 ) NOT NULL COMMENT 'birthday notify flag',
+  `profile-id` int(11) NOT NULL DEFAULT '0' COMMENT 'which profile to display - 0 is public default',
+  `bdyear` char(4) NOT NULL COMMENT 'birthday notify flag',
   `bd` date NOT NULL,
   PRIMARY KEY (`id`),
   KEY `uid` (`uid`),
   KEY `self` (`self`),
-  KEY `network` (`network`),
-  KEY `name` (`name`),
-  KEY `nick` (`nick`),
-  KEY `attag` (`attag`),
-  KEY `url` (`url`),
-  KEY `nurl` (`nurl`),
-  KEY `addr` (`addr`),
-  KEY `batch` (`batch`),
   KEY `issued-id` (`issued-id`),
   KEY `dfrn-id` (`dfrn-id`),
   KEY `blocked` (`blocked`),
   KEY `readonly` (`readonly`),
-  KEY `forum` (`forum`),
-  KEY `hidden` (`hidden`),
+  KEY `network` (`network`),
+  KEY `name` (`name`),
+  KEY `nick` (`nick`),
+  KEY `attag` (`attag`),
+  KEY `addr` (`addr`),
+  KEY `url` (`url`),
+  KEY `batch` (`batch`),
+  KEY `nurl` (`nurl`),
   KEY `pending` (`pending`),
-  KEY `closeness` (`closeness`)  
+  KEY `hidden` (`hidden`),
+  KEY `forum` (`forum`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `conv`
+--
+
+CREATE TABLE IF NOT EXISTS `conv` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `guid` char(64) NOT NULL,
+  `recips` mediumtext NOT NULL,
+  `uid` int(11) NOT NULL,
+  `creator` char(255) NOT NULL,
+  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `subject` mediumtext NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `created` (`created`),
+  KEY `updated` (`updated`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `deliverq`
+--
+
+CREATE TABLE IF NOT EXISTS `deliverq` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `cmd` char(32) NOT NULL,
+  `item` int(11) NOT NULL,
+  `contact` int(11) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `event`
+--
+
+CREATE TABLE IF NOT EXISTS `event` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `uid` int(11) NOT NULL,
+  `cid` int(11) NOT NULL,
+  `uri` char(255) NOT NULL,
+  `created` datetime NOT NULL,
+  `edited` datetime NOT NULL,
+  `start` datetime NOT NULL,
+  `finish` datetime NOT NULL,
+  `desc` text NOT NULL,
+  `location` text NOT NULL,
+  `type` char(255) NOT NULL,
+  `nofinish` tinyint(1) NOT NULL DEFAULT '0',
+  `adjust` tinyint(1) NOT NULL DEFAULT '1',
+  `allow_cid` mediumtext NOT NULL,
+  `allow_gid` mediumtext NOT NULL,
+  `deny_cid` mediumtext NOT NULL,
+  `deny_gid` mediumtext NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `fcontact`
+--
+
+CREATE TABLE IF NOT EXISTS `fcontact` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `url` char(255) NOT NULL,
+  `name` char(255) NOT NULL,
+  `photo` char(255) NOT NULL,
+  `request` char(255) NOT NULL,
+  `nick` char(255) NOT NULL,
+  `addr` char(255) NOT NULL,
+  `batch` char(255) NOT NULL,
+  `notify` char(255) NOT NULL,
+  `poll` char(255) NOT NULL,
+  `confirm` char(255) NOT NULL,
+  `priority` tinyint(1) NOT NULL,
+  `network` char(32) NOT NULL,
+  `alias` char(255) NOT NULL,
+  `pubkey` text NOT NULL,
+  `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  PRIMARY KEY (`id`),
+  KEY `addr` (`addr`),
+  KEY `network` (`network`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `ffinder`
+--
+
+CREATE TABLE IF NOT EXISTS `ffinder` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `uid` int(10) unsigned NOT NULL,
+  `cid` int(10) unsigned NOT NULL,
+  `fid` int(10) unsigned NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `fserver`
+--
+
+CREATE TABLE IF NOT EXISTS `fserver` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `server` char(255) NOT NULL,
+  `posturl` char(255) NOT NULL,
+  `key` text NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `server` (`server`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `fsuggest`
+--
+
+CREATE TABLE IF NOT EXISTS `fsuggest` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `uid` int(11) NOT NULL,
+  `cid` int(11) NOT NULL,
+  `name` char(255) NOT NULL,
+  `url` char(255) NOT NULL,
+  `request` char(255) NOT NULL,
+  `photo` char(255) NOT NULL,
+  `note` text NOT NULL,
+  `created` datetime NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `gcign`
+--
+
+CREATE TABLE IF NOT EXISTS `gcign` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `uid` int(11) NOT NULL,
+  `gcid` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `uid` (`uid`),
+  KEY `gcid` (`gcid`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `gcontact`
+--
+
+CREATE TABLE IF NOT EXISTS `gcontact` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `name` char(255) NOT NULL,
+  `url` char(255) NOT NULL,
+  `nurl` char(255) NOT NULL,
+  `photo` char(255) NOT NULL,
+  `connect` char(255) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `nurl` (`nurl`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `glink`
+--
+
+CREATE TABLE IF NOT EXISTS `glink` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `cid` int(11) NOT NULL,
+  `uid` int(11) NOT NULL,
+  `gcid` int(11) NOT NULL,
+  `updated` datetime NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `cid` (`cid`),
+  KEY `uid` (`uid`),
+  KEY `gcid` (`gcid`),
+  KEY `updated` (`updated`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
 -- --------------------------------------------------------
@@ -154,6 +419,33 @@ CREATE TABLE IF NOT EXISTS `group_member` (
 
 -- --------------------------------------------------------
 
+--
+-- Table structure for table `guid`
+--
+
+CREATE TABLE IF NOT EXISTS `guid` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `guid` char(64) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `guid` (`guid`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `hook`
+--
+
+CREATE TABLE IF NOT EXISTS `hook` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `hook` char(255) NOT NULL,
+  `file` char(255) NOT NULL,
+  `function` char(255) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
 --
 -- Table structure for table `intro`
 --
@@ -182,18 +474,18 @@ CREATE TABLE IF NOT EXISTS `intro` (
 CREATE TABLE IF NOT EXISTS `item` (
   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
   `guid` char(64) NOT NULL,
-  `uri` char(255) NOT NULL,
+  `uri` char(255) CHARACTER SET ascii NOT NULL,
   `uid` int(10) unsigned NOT NULL DEFAULT '0',
   `contact-id` int(10) unsigned NOT NULL DEFAULT '0',
   `type` char(255) NOT NULL,
   `wall` tinyint(1) NOT NULL DEFAULT '0',
   `gravity` tinyint(1) NOT NULL DEFAULT '0',
   `parent` int(10) unsigned NOT NULL DEFAULT '0',
-  `parent-uri` char(255) NOT NULL,
+  `parent-uri` char(255) CHARACTER SET ascii NOT NULL,
   `extid` char(255) NOT NULL,
   `thr-parent` char(255) NOT NULL,
-  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
-  `edited` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `created` datetime NOT NULL,
+  `edited` datetime NOT NULL,
   `commented` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   `received` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   `changed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
@@ -212,9 +504,9 @@ CREATE TABLE IF NOT EXISTS `item` (
   `target-type` char(255) NOT NULL,
   `target` text NOT NULL,
   `postopts` text NOT NULL,
-  `plink` char(255) NOT NULL, 
+  `plink` char(255) NOT NULL,
   `resource-id` char(255) NOT NULL,
-  `event-id` int(10) unsigned NOT NULL,
+  `event-id` int(11) NOT NULL,
   `tag` mediumtext NOT NULL,
   `attach` mediumtext NOT NULL,
   `inform` mediumtext NOT NULL,
@@ -238,42 +530,59 @@ CREATE TABLE IF NOT EXISTS `item` (
   `forum_mode` tinyint(1) NOT NULL DEFAULT '0',
   `last-child` tinyint(1) unsigned NOT NULL DEFAULT '1',
   PRIMARY KEY (`id`),
-  KEY `guid` (`guid`),
   KEY `uri` (`uri`),
   KEY `uid` (`uid`),
   KEY `contact-id` (`contact-id`),
   KEY `type` (`type`),
   KEY `parent` (`parent`),
   KEY `parent-uri` (`parent-uri`),
-  KEY `extid` (`extid`),
   KEY `created` (`created`),
   KEY `edited` (`edited`),
-  KEY `received` (`received`),
-  KEY `moderated` (`moderated`),
   KEY `visible` (`visible`),
-  KEY `spam` (`spam`),
-  KEY `starred` (`starred`),
-  KEY `bookmark` (`bookmark`),
   KEY `deleted` (`deleted`),
-  KEY `origin`  (`origin`),
-  KEY `forum_mode` (`forum_mode`),
   KEY `last-child` (`last-child`),
   KEY `unseen` (`unseen`),
+  KEY `extid` (`extid`),
+  KEY `received` (`received`),
+  KEY `starred` (`starred`),
+  KEY `guid` (`guid`),
+  KEY `origin` (`origin`),
   KEY `wall` (`wall`),
-  KEY `author-name` (`author-name`),
+  KEY `forum_mode` (`forum_mode`),
   KEY `author-link` (`author-link`),
+  KEY `bookmark` (`bookmark`),
+  KEY `moderated` (`moderated`),
+  KEY `spam` (`spam`),
+  KEY `author-name` (`author-name`),
   FULLTEXT KEY `title` (`title`),
   FULLTEXT KEY `body` (`body`),
-  FULLTEXT KEY `tag` (`tag`),
-  FULLTEXT KEY `file` (`file`),
   FULLTEXT KEY `allow_cid` (`allow_cid`),
   FULLTEXT KEY `allow_gid` (`allow_gid`),
   FULLTEXT KEY `deny_cid` (`deny_cid`),
-  FULLTEXT KEY `deny_gid` (`deny_gid`)
+  FULLTEXT KEY `deny_gid` (`deny_gid`),
+  FULLTEXT KEY `tag` (`tag`),
+  FULLTEXT KEY `file` (`file`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
 -- --------------------------------------------------------
 
+--
+-- Table structure for table `item_id`
+--
+
+CREATE TABLE IF NOT EXISTS `item_id` (
+  `iid` int(11) NOT NULL,
+  `uid` int(11) NOT NULL,
+  `sid` char(255) NOT NULL,
+  `service` char(255) NOT NULL,
+  PRIMARY KEY (`iid`),
+  KEY `uid` (`uid`),
+  KEY `sid` (`sid`),
+  KEY `service` (`service`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
 --
 -- Table structure for table `mail`
 --
@@ -286,26 +595,130 @@ CREATE TABLE IF NOT EXISTS `mail` (
   `from-photo` char(255) NOT NULL,
   `from-url` char(255) NOT NULL,
   `contact-id` char(255) NOT NULL,
-  `convid` int(10) unsigned NOT NULL,
+  `convid` int(11) NOT NULL,
   `title` char(255) NOT NULL,
   `body` mediumtext NOT NULL,
-  `seen` tinyint(1) NOT NULL DEFAULT '0',
+  `seen` tinyint(1) NOT NULL,
   `reply` tinyint(1) NOT NULL DEFAULT '0',
-  `replied` tinyint(1) NOT NULL DEFAULT '0',
+  `replied` tinyint(1) NOT NULL,
   `unknown` tinyint(1) NOT NULL DEFAULT '0',
   `uri` char(255) NOT NULL,
   `parent-uri` char(255) NOT NULL,
   `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   PRIMARY KEY (`id`),
+  KEY `reply` (`reply`),
   KEY `uid` (`uid`),
   KEY `guid` (`guid`),
-  KEY `convid` (`convid`),
-  KEY `reply` (`reply`),
-  KEY `unknown` (`unknown`),
+  KEY `seen` (`seen`),
   KEY `uri` (`uri`),
   KEY `parent-uri` (`parent-uri`),
-  KEY `created` (`created`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+  KEY `created` (`created`),
+  KEY `convid` (`convid`),
+  KEY `unknown` (`unknown`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `mailacct`
+--
+
+CREATE TABLE IF NOT EXISTS `mailacct` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `uid` int(11) NOT NULL,
+  `server` char(255) NOT NULL,
+  `port` int(11) NOT NULL,
+  `ssltype` char(16) NOT NULL,
+  `mailbox` char(255) NOT NULL,
+  `user` char(255) NOT NULL,
+  `pass` text NOT NULL,
+  `action` int(11) NOT NULL,
+  `movetofolder` char(255) NOT NULL,
+  `reply_to` char(255) NOT NULL,
+  `pubmail` tinyint(1) NOT NULL DEFAULT '0',
+  `last_check` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `manage`
+--
+
+CREATE TABLE IF NOT EXISTS `manage` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `uid` int(11) NOT NULL,
+  `mid` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `uid` (`uid`),
+  KEY `mid` (`mid`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `notify`
+--
+
+CREATE TABLE IF NOT EXISTS `notify` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `hash` char(64) NOT NULL,
+  `name` char(255) NOT NULL,
+  `url` char(255) NOT NULL,
+  `photo` char(255) NOT NULL,
+  `date` datetime NOT NULL,
+  `msg` mediumtext NOT NULL,
+  `uid` int(11) NOT NULL,
+  `link` char(255) NOT NULL,
+  `parent` int(11) NOT NULL,
+  `seen` tinyint(1) NOT NULL DEFAULT '0',
+  `type` int(11) NOT NULL,
+  `verb` char(255) NOT NULL,
+  `otype` char(16) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `type` (`type`),
+  KEY `seen` (`seen`),
+  KEY `uid` (`uid`),
+  KEY `date` (`date`),
+  KEY `hash` (`hash`),
+  KEY `parent` (`parent`),
+  KEY `link` (`link`),
+  KEY `otype` (`otype`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `notify-threads`
+--
+
+CREATE TABLE IF NOT EXISTS `notify-threads` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `notify-id` int(11) NOT NULL,
+  `master-parent-item` int(10) unsigned NOT NULL DEFAULT '0',
+  `parent-item` int(10) unsigned NOT NULL DEFAULT '0',
+  `receiver-uid` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `master-parent-item` (`master-parent-item`),
+  KEY `receiver-uid` (`receiver-uid`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `pconfig`
+--
+
+CREATE TABLE IF NOT EXISTS `pconfig` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `uid` int(11) NOT NULL DEFAULT '0',
+  `cat` char(255) CHARACTER SET ascii NOT NULL,
+  `k` char(255) CHARACTER SET ascii NOT NULL,
+  `v` mediumtext NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `access` (`uid`,`cat`,`k`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
 -- --------------------------------------------------------
 
@@ -316,8 +729,8 @@ CREATE TABLE IF NOT EXISTS `mail` (
 CREATE TABLE IF NOT EXISTS `photo` (
   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
   `uid` int(10) unsigned NOT NULL,
-  `contact-id` int(10) unsigned NOT NULL,
-  `guid` char(64) NOT NULL, 
+  `contact-id` int(10) unsigned NOT NULL DEFAULT '0',
+  `guid` char(64) NOT NULL,
   `resource-id` char(255) NOT NULL,
   `created` datetime NOT NULL,
   `edited` datetime NOT NULL,
@@ -339,12 +752,49 @@ CREATE TABLE IF NOT EXISTS `photo` (
   KEY `resource-id` (`resource-id`),
   KEY `album` (`album`),
   KEY `scale` (`scale`),
-  KEY `profile` (`profile`),
-  KEY `guid` (`guid`)
+  KEY `profile` (`profile`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
 -- --------------------------------------------------------
 
+--
+-- Table structure for table `poll`
+--
+
+CREATE TABLE IF NOT EXISTS `poll` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `uid` int(11) NOT NULL,
+  `q0` mediumtext NOT NULL,
+  `q1` mediumtext NOT NULL,
+  `q2` mediumtext NOT NULL,
+  `q3` mediumtext NOT NULL,
+  `q4` mediumtext NOT NULL,
+  `q5` mediumtext NOT NULL,
+  `q6` mediumtext NOT NULL,
+  `q7` mediumtext NOT NULL,
+  `q8` mediumtext NOT NULL,
+  `q9` mediumtext NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `uid` (`uid`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `poll_result`
+--
+
+CREATE TABLE IF NOT EXISTS `poll_result` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `poll_id` int(11) NOT NULL,
+  `choice` int(11) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `poll_id` (`poll_id`),
+  KEY `choice` (`choice`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
 --
 -- Table structure for table `profile`
 --
@@ -365,7 +815,6 @@ CREATE TABLE IF NOT EXISTS `profile` (
   `country-name` char(255) NOT NULL,
   `gender` char(32) NOT NULL,
   `marital` char(255) NOT NULL,
-  `showwith` tinyint(1) NOT NULL DEFAULT '0',
   `with` text NOT NULL,
   `sexual` char(255) NOT NULL,
   `politic` char(255) NOT NULL,
@@ -402,7 +851,7 @@ CREATE TABLE IF NOT EXISTS `profile` (
 CREATE TABLE IF NOT EXISTS `profile_check` (
   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
   `uid` int(10) unsigned NOT NULL,
-  `cid` int(10) unsigned NOT NULL,
+  `cid` int(10) unsigned NOT NULL DEFAULT '0',
   `dfrn_id` char(255) NOT NULL,
   `sec` char(255) NOT NULL,
   `expire` int(11) NOT NULL,
@@ -411,6 +860,59 @@ CREATE TABLE IF NOT EXISTS `profile_check` (
 
 -- --------------------------------------------------------
 
+--
+-- Table structure for table `queue`
+--
+
+CREATE TABLE IF NOT EXISTS `queue` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `cid` int(11) NOT NULL,
+  `network` char(32) NOT NULL,
+  `created` datetime NOT NULL,
+  `last` datetime NOT NULL,
+  `content` mediumtext NOT NULL,
+  `batch` tinyint(1) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`id`),
+  KEY `cid` (`cid`),
+  KEY `network` (`network`),
+  KEY `created` (`created`),
+  KEY `last` (`last`),
+  KEY `batch` (`batch`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `register`
+--
+
+CREATE TABLE IF NOT EXISTS `register` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `hash` char(255) NOT NULL,
+  `created` datetime NOT NULL,
+  `uid` int(10) unsigned NOT NULL,
+  `password` char(255) NOT NULL,
+  `language` char(16) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `search`
+--
+
+CREATE TABLE IF NOT EXISTS `search` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `uid` int(11) NOT NULL,
+  `term` char(255) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `uid` (`uid`),
+  KEY `term` (`term`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
 --
 -- Table structure for table `session`
 --
@@ -427,6 +929,58 @@ CREATE TABLE IF NOT EXISTS `session` (
 
 -- --------------------------------------------------------
 
+--
+-- Table structure for table `sign`
+--
+
+CREATE TABLE IF NOT EXISTS `sign` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `iid` int(10) unsigned NOT NULL,
+  `signed_text` mediumtext NOT NULL,
+  `signature` text NOT NULL,
+  `signer` char(255) NOT NULL,
+  PRIMARY KEY (`id`),
+  KEY `iid` (`iid`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `spam`
+--
+
+CREATE TABLE IF NOT EXISTS `spam` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `uid` int(11) NOT NULL,
+  `spam` int(11) NOT NULL DEFAULT '0',
+  `ham` int(11) NOT NULL DEFAULT '0',
+  `term` char(255) NOT NULL,
+  `date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  PRIMARY KEY (`id`),
+  KEY `uid` (`uid`),
+  KEY `spam` (`spam`),
+  KEY `ham` (`ham`),
+  KEY `term` (`term`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `tokens`
+--
+
+CREATE TABLE IF NOT EXISTS `tokens` (
+  `id` varchar(40) NOT NULL,
+  `secret` text NOT NULL,
+  `client_id` varchar(20) NOT NULL,
+  `expires` int(11) NOT NULL,
+  `scope` varchar(200) NOT NULL,
+  `uid` int(11) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+-- --------------------------------------------------------
+
 --
 -- Table structure for table `user`
 --
@@ -440,7 +994,7 @@ CREATE TABLE IF NOT EXISTS `user` (
   `email` char(255) NOT NULL,
   `openid` char(255) NOT NULL,
   `timezone` char(128) NOT NULL,
-  `language` char(32) NOT NULL DEFAULT 'en',
+  `language` char(16) NOT NULL DEFAULT 'en',
   `register_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   `login_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   `default-location` char(255) NOT NULL,
@@ -450,426 +1004,47 @@ CREATE TABLE IF NOT EXISTS `user` (
   `prvkey` text NOT NULL,
   `spubkey` text NOT NULL,
   `sprvkey` text NOT NULL,
-  `verified` tinyint(1) unsigned NOT NULL DEFAULT '0', 
-  `blocked` tinyint(1) unsigned NOT NULL DEFAULT '0', 
-  `blockwall` tinyint(1) unsigned NOT NULL DEFAULT '0',
-  `hidewall` tinyint(1) unsigned NOT NULL DEFAULT '0',
-  `blocktags` tinyint(1) unsigned NOT NULL DEFAULT '0',
-  `unkmail` tinyint(1) unsigned NOT NULL DEFAULT '0',
-  `cntunkmail` int(11) unsigned NOT NULL DEFAULT '10',
-  `notify-flags` int(11) unsigned NOT NULL DEFAULT '65535', 
-  `page-flags` int(11) unsigned NOT NULL DEFAULT '0',
+  `verified` tinyint(1) unsigned NOT NULL DEFAULT '0',
+  `blocked` tinyint(1) unsigned NOT NULL DEFAULT '0',
+  `blockwall` tinyint(1) NOT NULL DEFAULT '0',
+  `hidewall` tinyint(1) NOT NULL DEFAULT '0',
+  `blocktags` tinyint(1) NOT NULL DEFAULT '0',
+  `unkmail` tinyint(1) NOT NULL DEFAULT '0',
+  `cntunkmail` int(11) NOT NULL DEFAULT '10',
+  `notify-flags` int(11) unsigned NOT NULL DEFAULT '65535',
+  `page-flags` int(11) NOT NULL DEFAULT '0',
   `prvnets` tinyint(1) NOT NULL DEFAULT '0',
   `pwdreset` char(255) NOT NULL,
   `maxreq` int(11) NOT NULL DEFAULT '10',
-  `expire` int(11) unsigned NOT NULL DEFAULT '0',
-  `account_expired` tinyint( 1 ) NOT NULL DEFAULT '0',
+  `expire` int(10) unsigned NOT NULL DEFAULT '0',
+  `account_expired` tinyint(1) NOT NULL DEFAULT '0',
   `account_expires_on` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   `expire_notification_sent` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
-  `allow_cid` mediumtext NOT NULL, 
+  `allow_cid` mediumtext NOT NULL,
   `allow_gid` mediumtext NOT NULL,
-  `deny_cid` mediumtext NOT NULL, 
+  `deny_cid` mediumtext NOT NULL,
   `deny_gid` mediumtext NOT NULL,
   `openidserver` text NOT NULL,
-  PRIMARY KEY (`uid`), 
+  PRIMARY KEY (`uid`),
   KEY `nickname` (`nickname`),
+  KEY `login_date` (`login_date`),
   KEY `account_expired` (`account_expired`),
   KEY `hidewall` (`hidewall`),
   KEY `blockwall` (`blockwall`),
-  KEY `unkmail` (`unkmail`),
-  KEY `cntunkmail` (`cntunkmail`),
   KEY `blocked` (`blocked`),
   KEY `verified` (`verified`),
-  KEY `login_date` (`login_date`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `register` (
-  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
-  `hash` CHAR( 255 ) NOT NULL ,
-  `created` DATETIME NOT NULL ,
-  `uid` INT(11) UNSIGNED NOT NULL,
-  `password` CHAR(255) NOT NULL,
-  `language` CHAR(16) NOT NULL,
-  PRIMARY KEY (`id`)
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `clients` (
-`client_id` VARCHAR( 20 ) NOT NULL ,
-`pw` VARCHAR( 20 ) NOT NULL ,
-`redirect_uri` VARCHAR( 200 ) NOT NULL ,
-`name` VARCHAR( 128 ) NULL DEFAULT NULL,
-`icon` VARCHAR( 255 ) NULL DEFAULT NULL,
-`uid` INT NOT NULL DEFAULT 0,
-PRIMARY KEY ( `client_id` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `tokens` (
-`id` VARCHAR( 40 ) NOT NULL ,
-`secret` VARCHAR( 40 ) NOT NULL ,
-`client_id` VARCHAR( 20 ) NOT NULL ,
-`expires` INT NOT NULL ,
-`scope` VARCHAR( 200 ) NOT NULL ,
-`uid` INT NOT NULL ,
-PRIMARY KEY ( `id` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `auth_codes` (
-`id` VARCHAR( 40 ) NOT NULL ,
-`client_id` VARCHAR( 20 ) NOT NULL ,
-`redirect_uri` VARCHAR( 200 ) NOT NULL ,
-`expires` INT NOT NULL ,
-`scope` VARCHAR( 250 ) NOT NULL ,
-PRIMARY KEY ( `id` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `queue` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`cid` INT NOT NULL ,
-`network` CHAR( 32 ) NOT NULL,
-`created` DATETIME NOT NULL ,
-`last` DATETIME NOT NULL ,
-`content` MEDIUMTEXT NOT NULL,
-`batch` TINYINT( 1 ) NOT NULL DEFAULT '0',
-INDEX ( `cid` ),
-INDEX ( `created` ),
-INDEX ( `last` ),
-INDEX ( `network` ),
-INDEX ( `batch` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `pconfig` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`uid` INT NOT NULL DEFAULT '0',
-`cat` CHAR( 255 ) NOT NULL ,
-`k` CHAR( 255 ) NOT NULL ,
-`v` MEDIUMTEXT NOT NULL
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `hook` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`hook` CHAR( 255 ) NOT NULL ,
-`file` CHAR( 255 ) NOT NULL ,
-`function` CHAR( 255 ) NOT NULL
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `addon` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`name` CHAR( 255 ) NOT NULL ,
-`version` CHAR( 255 ) NOT NULL ,
-`installed` TINYINT( 1 ) NOT NULL DEFAULT '0' ,
-`timestamp` BIGINT NOT NULL DEFAULT '0' ,
-`plugin_admin` TINYINT( 1 ) NOT NULL DEFAULT '0'
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `event` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`uid` INT NOT NULL ,
-`cid` INT NOT NULL ,
-`uri` CHAR( 255 ) NOT NULL,
-`created` DATETIME NOT NULL ,
-`edited` DATETIME NOT NULL ,
-`start` DATETIME NOT NULL ,
-`finish` DATETIME NOT NULL ,
-`desc` TEXT NOT NULL ,
-`location` TEXT NOT NULL ,
-`type` CHAR( 255 ) NOT NULL ,
-`nofinish` TINYINT( 1 ) NOT NULL DEFAULT '0',
-`adjust` TINYINT( 1 ) NOT NULL DEFAULT '1',
-`allow_cid` MEDIUMTEXT NOT NULL ,
-`allow_gid` MEDIUMTEXT NOT NULL ,
-`deny_cid` MEDIUMTEXT NOT NULL ,
-`deny_gid` MEDIUMTEXT NOT NULL
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `cache` (
- `k` CHAR( 255 ) NOT NULL PRIMARY KEY ,
- `v` TEXT NOT NULL,
- `updated` DATETIME NOT NULL
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `fcontact` (
-`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`url` CHAR( 255 ) NOT NULL ,
-`name` CHAR( 255 ) NOT NULL ,
-`photo` CHAR( 255 ) NOT NULL ,
-`request` CHAR( 255 ) NOT NULL,
-`nick` CHAR( 255 ) NOT NULL ,
-`addr` CHAR( 255 ) NOT NULL ,
-`batch` CHAR( 255) NOT NULL,
-`notify` CHAR( 255 ) NOT NULL ,
-`poll` CHAR( 255 ) NOT NULL ,
-`confirm` CHAR( 255 ) NOT NULL ,
-`priority` TINYINT( 1 ) NOT NULL ,
-`network` CHAR( 32 ) NOT NULL ,
-`alias` CHAR( 255 ) NOT NULL ,
-`pubkey` TEXT NOT NULL ,
-`updated` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
-INDEX ( `addr` ),
-INDEX ( `network` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `ffinder` (
-`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`uid` INT UNSIGNED NOT NULL ,
-`cid` INT UNSIGNED NOT NULL ,
-`fid` INT UNSIGNED NOT NULL
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `fsuggest` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`uid` INT NOT NULL ,
-`cid` INT NOT NULL ,
-`name` CHAR( 255 ) NOT NULL ,
-`url` CHAR( 255 ) NOT NULL ,
-`request` CHAR( 255 ) NOT NULL,
-`photo` CHAR( 255 ) NOT NULL ,
-`note` TEXT NOT NULL ,
-`created` DATETIME NOT NULL
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
- 
-
-CREATE TABLE IF NOT EXISTS `mailacct` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`uid` INT NOT NULL,
-`server` CHAR( 255 ) NOT NULL ,
-`port` INT NOT NULL,
-`ssltype` CHAR( 16 ) NOT NULL,
-`mailbox` CHAR( 255 ) NOT NULL,
-`user` CHAR( 255 ) NOT NULL ,
-`pass` TEXT NOT NULL ,
-`reply_to` CHAR( 255 ) NOT NULL ,
-`action` INT NOT NULL ,
-`movetofolder` CHAR(255) NOT NULL ,
-`pubmail` TINYINT(1) NOT NULL DEFAULT '0',
-`last_check` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00'
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `attach` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`uid` INT NOT NULL ,
-`hash` CHAR(64) NOT NULL,
-`filename` CHAR(255) NOT NULL,
-`filetype` CHAR( 64 ) NOT NULL ,
-`filesize` INT NOT NULL ,
-`data` LONGBLOB NOT NULL ,
-`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
-`edited` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
-`allow_cid` MEDIUMTEXT NOT NULL ,
-`allow_gid` MEDIUMTEXT NOT NULL ,
-`deny_cid` MEDIUMTEXT NOT NULL ,
-`deny_gid` MEDIUMTEXT NOT NULL
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `guid` (
-`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`guid` CHAR( 64 ) NOT NULL ,
-INDEX ( `guid` )
-) ENGINE = MyISAM  DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `sign` (
-`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`iid` INT UNSIGNED NOT NULL ,
-`signed_text` MEDIUMTEXT NOT NULL ,
-`signature` TEXT NOT NULL ,
-`signer` CHAR( 255 ) NOT NULL ,
-INDEX ( `iid` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `deliverq` (
-`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`cmd` CHAR( 32 ) NOT NULL ,
-`item` INT NOT NULL ,
-`contact` INT NOT NULL
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `search` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`uid` INT NOT NULL ,
-`term` CHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
-INDEX ( `uid` ),
-INDEX ( `term` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `fserver` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`server` CHAR( 255 ) NOT NULL ,
-`posturl` CHAR( 255 ) NOT NULL ,
-`key` TEXT NOT NULL,
-INDEX ( `server` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `gcontact` (
-`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`name` CHAR( 255 ) NOT NULL ,
-`url` CHAR( 255 ) NOT NULL ,
-`nurl` CHAR( 255 ) NOT NULL ,
-`photo` CHAR( 255 ) NOT NULL,
-`connect` CHAR( 255 ) NOT NULL,
-INDEX ( `nurl` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `glink` (
-`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`cid` INT NOT NULL ,
-`uid` INT NOT NULL ,
-`gcid` INT NOT NULL,
-`updated` DATETIME NOT NULL,
-INDEX ( `cid` ),
-INDEX ( `uid` ),
-INDEX ( `gcid` ),
-INDEX ( `updated` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `gcign` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`uid` INT NOT NULL ,
-`gcid` INT NOT NULL,
-INDEX ( `uid` ),
-INDEX ( `gcid` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `conv` (
-  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-  `guid` CHAR( 64 ) NOT NULL ,
-  `recips` MEDIUMTEXT NOT NULL ,
-  `uid` INT NOT NULL,
-  `creator` CHAR( 255 ) NOT NULL ,
-  `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
-  `updated` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
-  `subject` MEDIUMTEXT NOT NULL,
-  INDEX ( `created` ),
-  INDEX ( `updated` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `notify` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`hash` CHAR( 64 ) NOT NULL,
-`type` INT( 11 ) NOT NULL ,
-`name` CHAR( 255 ) NOT NULL ,
-`url` CHAR( 255 ) NOT NULL ,
-`photo` CHAR( 255 ) NOT NULL ,
-`date` DATETIME NOT NULL ,
-`msg` MEDIUMTEXT NOT NULL ,
-`uid` INT NOT NULL ,
-`link` CHAR( 255 ) NOT NULL ,
-`parent` INT( 11 ) NOT NULL,
-`seen` TINYINT( 1 ) NOT NULL DEFAULT '0',
-`verb` CHAR( 255 ) NOT NULL,
-`otype` CHAR( 16 ) NOT NULL,
-INDEX ( `hash` ),
-INDEX ( `type` ),
-INDEX ( `uid` ),
-INDEX ( `link` ),
-INDEX ( `parent` ),
-INDEX ( `seen` ),
-INDEX ( `date` ),
-INDEX ( `otype` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `item_id` (
-`iid` INT NOT NULL ,
-`uid` INT NOT NULL ,
-`face` CHAR( 255 ) NOT NULL ,
-`dspr` CHAR( 255 ) NOT NULL ,
-`twit` CHAR( 255 ) NOT NULL ,
-`stat` CHAR( 255 ) NOT NULL ,
-PRIMARY KEY ( `iid` ),
-INDEX ( `uid` ),
-INDEX ( `face` ),
-INDEX ( `dspr` ),
-INDEX ( `twit` ),
-INDEX ( `stat` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `manage` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`uid` INT NOT NULL ,
-`mid` INT NOT NULL,
-INDEX ( `uid` ),
-INDEX ( `mid` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `poll_result` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`poll_id` INT NOT NULL ,
-`choice` INT NOT NULL ,
-INDEX ( `poll_id` ),
-INDEX ( `choice` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-
-CREATE TABLE IF NOT EXISTS `poll` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`uid` INT NOT NULL ,
-`q0` MEDIUMTEXT NOT NULL ,
-`q1` MEDIUMTEXT NOT NULL ,
-`q2` MEDIUMTEXT NOT NULL ,
-`q3` MEDIUMTEXT NOT NULL ,
-`q4` MEDIUMTEXT NOT NULL ,
-`q5` MEDIUMTEXT NOT NULL ,
-`q6` MEDIUMTEXT NOT NULL ,
-`q7` MEDIUMTEXT NOT NULL ,
-`q8` MEDIUMTEXT NOT NULL ,
-`q9` MEDIUMTEXT NOT NULL ,
-INDEX ( `uid` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
+  KEY `unkmail` (`unkmail`),
+  KEY `cntunkmail` (`cntunkmail`)
+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
+-- --------------------------------------------------------
 
 --
--- Table structure for table `notify-threads`
+-- Table structure for table `userd`
 --
--- notify-id:          notify.id of the first notification of this thread
--- master-parent-item: item.id of the parent item
--- parent-item:        item.id of the imediate parent (only for multi-thread)
---                     not used yet.
--- receiver-uid: user.uid of the receiver of this notification.
---
--- If we query for a master-parent-item and receiver-uid...
---   * Returns 1 item: this is not the parent notification, 
---     so just "follow" the thread (references to this notification)
---   * Returns no item: this is the first notification related to
---     this parent item. So, create the record and use the message-id 
---     header.
-
-
-CREATE TABLE IF NOT EXISTS `notify-threads` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`notify-id` INT NOT NULL,
-`master-parent-item` INT( 10 ) unsigned NOT NULL DEFAULT '0',
-`parent-item` INT( 10 ) unsigned NOT NULL DEFAULT '0',
-`receiver-uid` INT NOT NULL,
-INDEX ( `master-parent-item` ),
-INDEX ( `receiver-uid` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
-CREATE TABLE IF NOT EXISTS `spam` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`uid` INT NOT NULL,
-`spam` INT NOT NULL DEFAULT '0',
-`ham` INT NOT NULL DEFAULT '0',
-`term` CHAR(255) NOT NULL,
-`date` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
-INDEX ( `uid` ),
-INDEX ( `spam` ),
-INDEX ( `ham` ),
-INDEX ( `term` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
 
 CREATE TABLE IF NOT EXISTS `userd` (
-`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
-`username` CHAR( 255 ) NOT NULL,
-INDEX ( `username` )
-) ENGINE = MyISAM DEFAULT CHARSET=utf8;
-
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `username` char(255) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
diff --git a/doc/Account-Basics.md b/doc/Account-Basics.md
old mode 100755
new mode 100644
index 164a6be46..41ca95b36
--- a/doc/Account-Basics.md
+++ b/doc/Account-Basics.md
@@ -6,40 +6,41 @@ Account Basics
 
 **Registration**
 
-Not all Friendica sites allow open registration. If registration is allowed, you will see a "Register" link immediately below the login prompts on the site home page. Following this link will take you to the site registration page.  The strength of our network is that lots of different sites are all completely compatible with each other.  If the site you're visting doesn't allow registration, or you think you might prefer another one, you can find a list of public servers here, and find one that meets your needs.  
+Not all Friendica sites allow open registration. If registration is allowed, you will see a "Register" link immediately below the login prompts on the site home page. Following this link will take you to the site registration page.  The strength of our network is that lots of different sites are all completely compatible with each other.  If the site you're visting doesn't allow registration, or you think you might prefer another one, you can find a list of public servers here, and find one that meets your needs.  
+
+If you'd like to have your own server, you can do that too.  Visit the Friendica website to download the code with setup instructions.  It's a very simple install process that anybody experienced in hosting websites, or with basic Linux experience can handle easily.
 
-If you'd like to have your own server, you can do that too.  Visit the Friendica website to download the code with setup instructions.  It's a very simple install process that anybody experienced in hosting websites, or with basic Linux experience can handle easily.
 
 *OpenID*
 
 The first field on the Registration page is for an OpenID address. If you do not have an OpenID address or do not wish to use OpenID, leave this field blank. If you have an OpenID account elsewhere and wish to use it, enter the address into this field and click 'Register'. Friendica will attempt to extract as much information as possible from your OpenID provider and return to this page with those items already filled in.
 
+
 *Your Full Name*
 
 Please provide your full name **as you would like it to be displayed on this system**.  Most people use their real name for this, but you're under no obligation to do so yourself.
 
+
 *Email Address*
 
 Please provide a valid email address. Your email address is **never** published. We need this to send you account information and your login details. You may also occasionally receive notifications of incoming messages or items requiring your attention, but you have the ability to completely disable these from your Settings page once you have logged in.  This doesn't have to be your primary email address, but it does need to be a real email address.  You can't get your initial password, or reset a lost password later without it.  This is the only bit of personal information that has to be accurate.
 
+
 *Nickname*
 
 A nickname is used to generate web addresses for many of your personal pages, and is also treated like an email address when establishing communications with others. Due to the way that the nickname is used, it has some limitations. It must contain only US-ASCII text characters and numbers, and must also start with a text character. It also must be unique on this system. This is used in many places to identify your account, and once set - cannot be changed.
 
 
-
 *Directory Publishing*
 
 The Registration form also allows you to choose whether or not to list your account in the online directory. This is like a "phone book" and you may choose to be unlisted. We recommend that you select 'Yes' so that other people (friends, family, etc.) will be able to find you. If you choose 'No', you will essentially be invisible and have few opportunities for interaction. Whichever you choose, this can be changed any time from your Settings page after you login. 
 
+
 *Register*
 
 Once you have provided the necessary details, click the 'Register' button. An email will be sent to you providing your account login details. Please watch your email (including spam folders) for your registration details and initial password. 
 
 
-
-
-
 **Login Page**
 
 On the 'Login' page, please enter your login information that was provided during registration. You may use either your nickname or email address as a Login Name. 
@@ -55,6 +56,7 @@ Otherwise, enter your password. This will have been initially provided in your r
 
 After your first login, please visit the 'Settings' page from the top menu bar and change your password to something that you will remember.
 
+
 **Getting Started**
 
 A ['Tips for New Members'](newmember) link will show up on your home page for two weeks to provide some important Getting Started information.
diff --git a/doc/Bugs-and-Issues.md b/doc/Bugs-and-Issues.md
old mode 100755
new mode 100644
index 46abea9a3..251f91e93
--- a/doc/Bugs-and-Issues.md
+++ b/doc/Bugs-and-Issues.md
@@ -6,11 +6,11 @@ Bugs and Issues
 
 If your server has a support page, you should report any bugs/issues you encounter there first.  Reporting to your support page before reporting to the developers makes their job easier, as they don't have to deal with bug reports that might not have anything to do with them, and that helps us get new features faster.
 
-If you're a technical user, or your site doesn't have a support page, you'll need to use the Bug Tracker.  Please perform a search to see if there's already an open bug that matches yours before submitting anything.
+If you're a technical user, or your site doesn't have a support page, you'll need to use the Bug Tracker.  Please perform a search to see if there's already an open bug that matches yours before submitting anything.
 
 Try to provide as much information as you can about the bug, including the **full** text of any error messages or notices, and any steps required to replicate the problem in as much detail as possible.  It's generally better to provide too much information than not enough.
 
-See this article to learn more about submitting **good** bug reports.
+See this article to learn more about submitting **good** bug reports.
 
 
 **Bug Sponsorship**
diff --git a/doc/Connectors.md b/doc/Connectors.md
old mode 100755
new mode 100644
diff --git a/doc/Developers.md b/doc/Developers.md
old mode 100755
new mode 100644
diff --git a/doc/Home.md b/doc/Home.md
old mode 100755
new mode 100644
diff --git a/doc/Install.md b/doc/Install.md
old mode 100755
new mode 100644
diff --git a/doc/Installing-Connectors.md b/doc/Installing-Connectors.md
old mode 100755
new mode 100644
diff --git a/doc/Making-Friends.md b/doc/Making-Friends.md
old mode 100755
new mode 100644
index 3f1a24c8d..70b87abbc
--- a/doc/Making-Friends.md
+++ b/doc/Making-Friends.md
@@ -5,11 +5,11 @@ Making Friends
 
 Friendship in Friendica can take on a great many different meanings. But let's keep it simple, you want to be friends with somebody. How do you do it?
 
-The easiest thing to do is to join the New Here group.  This group is especially for people new to the Friendica network.  Simply connect to the group, post to the wall, and make new friends.  You don't even have to like us - comment on a few of our posts, and other people will start to add you too.
+The easiest thing to do is to join the New Here group.  This group is especially for people new to the Friendica network.  Simply connect to the group, post to the wall, and make new friends.  You don't even have to like us - comment on a few of our posts, and other people will start to add you too.
 
 The next thing you can do is look at the Directory.  The directory is split up into two parts.  If you click the directory button, you will be presented with a list of all members (who chose to be listed) on your server.  You'll also see a link to the Global Directory.  If you click through to the global directory, you will be presented with a list of everybody who chose to be listed across all instances of Friendica.  You will also see a "Show Community Forums" link, which will direct you to Groups, Forums and Fanpages.  You connect to people, groups and forums in the same way, except groups and forums will automatically accept your introduction request, whereas a human will approve you manually.
 
-To connect with other Friendica user
+To connect with other Friendica users:
 
 Visit their profile. Just beneath their profile picture will be the word 'Connect' (we're assuming this is an English language profile).
 
diff --git a/doc/Message-Flow.md b/doc/Message-Flow.md
old mode 100755
new mode 100644
diff --git a/doc/Pages.md b/doc/Pages.md
old mode 100755
new mode 100644
diff --git a/doc/Plugins.md b/doc/Plugins.md
old mode 100755
new mode 100644
index 29dff3187..df6004450
--- a/doc/Plugins.md
+++ b/doc/Plugins.md
@@ -164,10 +164,15 @@ Your module functions will often contain the function plugin_name_content(&$a),
 **'init_1'** - called just after DB has been opened and before session start
     $b is not used or passed
 
-
 **'page_end'** - called after HTML content functions have completed
     $b is (string) HTML of content div
 
+**'avatar_lookup'** - called when looking up the avatar
+    $b is (array)
+        'size' => the size of the avatar that will be looked up
+        'email' => email to look up the avatar for
+        'url' => the (string) generated URL of the avatar
+
 
 A complete list of all hook callbacks with file locations (generated 14-Feb-2012): Please see the source for details of any hooks not documented above.
 
diff --git a/doc/Profiles.md b/doc/Profiles.md
old mode 100755
new mode 100644
diff --git a/doc/Remove-Account.md b/doc/Remove-Account.md
old mode 100755
new mode 100644
diff --git a/doc/Settings.md b/doc/Settings.md
old mode 100755
new mode 100644
index 9808ecc5d..574ce8dcc
--- a/doc/Settings.md
+++ b/doc/Settings.md
@@ -172,16 +172,6 @@ $a->config['system']['no_regfullname'] = true;
 ```
 
 
-**Gravatars**
-
-During registration, we will try to automatically find a user photo for you on the web using the gravatar service. You may turn this off by setting 'no_gravatar' to true. Default is false.
-
-Config:
-```
-$a->config['system']['no_gravatar'] = true;
-```
-
-
 **OpenID**
 
 By default, OpenID may be used for both registration and logins. If you do not wish to make OpenID facilities available on your system (at all), set 'no_openid' to true. Default is false.
diff --git a/doc/Tags-and-Mentions.md b/doc/Tags-and-Mentions.md
old mode 100755
new mode 100644
diff --git a/doc/andfinally.md b/doc/andfinally.md
index cd8a6994b..c4e8cb948 100644
--- a/doc/andfinally.md
+++ b/doc/andfinally.md
@@ -1,3 +1,5 @@
+[[!meta title="And Finally..."]]
+
 And that brings the Quick Start to an end.
 
 Here are some more things to help get you started:
@@ -5,20 +7,20 @@ Here are some more things to help get you started:
 **Groups**
 
 
-- New Here - a group for people new to Friendica
+- New Here - a group for people new to Friendica
 
-- Friendica Support - problems?  This is the place to ask.
+- Friendica Support - problems?  This is the place to ask.
 
-- Public Stream - a place to talk about anything to anyone.
+- Public Stream - a place to talk about anything to anyone.
 
-- Let's Talk a group for finding people and groups who share similar interests.
+- Let's Talk a group for finding people and groups who share similar interests.
 
-- Local Friendica a page for local Friendica groups
+- Local Friendica a page for local Friendica groups
 
 
 **Documentation**
 
-- Connecting to more networks
-- Help Index
+- Connecting to more networks
+- Help Index
 
 
diff --git a/doc/groupsandpages.md b/doc/groupsandpages.md
index 418e682c8..5cfbc653c 100644
--- a/doc/groupsandpages.md
+++ b/doc/groupsandpages.md
@@ -1,11 +1,11 @@
-This is the global directory.  If you get lost, you can click this link to bring yourself back here.
+This is the global directory.  If you get lost, you can click this link to bring yourself back here.
 
 On this page, you'll find a collection of groups, forums and celebrity pages.  Groups are not real people.  Connecting to them is similar to "liking" something on Facebook, or signing up for a new forum.  You don't have to feel awkward about introducing yourself to a new person, because they're not people!
 
 When you connect to a group, all messages to that group will start appearing in your network tab.  You can comment on these posts, or post to the group yourself without ever having to add any of the groups members.  This is a great way to make friends dynamically - you'll find people you like and add each other naturally instead of adding random strangers.  Simply find a group you're interested in, and connect to it the same way you did with people in the last section.  There are a lot of groups, and you're likely to get lost.  Remember the link at the top of this page will bring you back here.
 
-Once you've added some groups, move on to the next section.
+Once you've added some groups, move on to the next section.
 
-
+
 
 
diff --git a/doc/guide.md b/doc/guide.md
index 178170c4e..d76af92e2 100644
--- a/doc/guide.md
+++ b/doc/guide.md
@@ -6,8 +6,8 @@ This is a bit like your Facebook wall.  It's where all your status messgages are
 
 Once you've finished writing your post, click on the padlock icon to select who can see it.  If you do not use the padlock icon, your post will be public.  This means it will appear to anybody who views your profile, and in the community tab if your site has it enabled, as well as in the network tab of any of your contacts.
 
-Play around with this a bit, then when you're ready to move on, we'll take a look at the Network Tab
+Play around with this a bit, then when you're ready to move on, we'll take a look at the Network Tab
 
-
+
 
 
diff --git a/doc/makingnewfriends.md b/doc/makingnewfriends.md
index 35befaa36..7eff1eda1 100644
--- a/doc/makingnewfriends.md
+++ b/doc/makingnewfriends.md
@@ -1,11 +1,11 @@
-This is your Suggested Friends page.  If you get lost, you can click this link to bring yourself back here.
+This is your Suggested Friends page.  If you get lost, you can click this link to bring yourself back here.
 
 This is a bit like the Friend Suggestions page of Facebook.  Everybody on this list has agreed that they may be suggested as a friend.  This means they're unlikely to refuse an introduction you send, and they want to meet new people too!
 
 See somebody you like the look of?  Click the connect button beneath their photograph.  This will bring you to the introductions page.  Fill in the form as instructed, and add a small note (optional).  Now, wait a bit and they'll accept your request - note that these are real people, and it might take a while.  Now you've added one, you're probably lost.  Click the link at the top of this page to go back to the suggested friends list and add some more.
 
-Feel uncomfortable adding people you don't know?  Don't worry - that's where Groups and Pages come in!
+Feel uncomfortable adding people you don't know?  Don't worry - that's where Groups and Pages come in!
 
-
+
 
 
diff --git a/doc/network.md b/doc/network.md
index f445b0055..afb092395 100644
--- a/doc/network.md
+++ b/doc/network.md
@@ -1,9 +1,9 @@
-This is your Network Tab.  If you get lost, you can click this link to bring yourself back here.
+This is your Network Tab.  If you get lost, you can click this link to bring yourself back here.
 
 This is a bit like the Newsfeed at Facebook or the Stream at Diaspora.  It's where all the posts from your contacts, groups, and feeds will appear.  If you're new, you won't see anything in this page, unless you posted your status in the last step.  If you've already added a few friends, you'll be able to see their posts.  Here, you can comment, like, or dislike posts, or click on somebody's name to visit their profile page where you can write on their wall.
 
-Now we need to fill it up, the first step, is to  add people you already know from Facebook.
+Now we need to fill it up, the first step, is to  add people you already know from Facebook.
 
-
+
 
 
diff --git a/doc/peopleyouknow.md b/doc/peopleyouknow.md
index 143c49217..ae0c9ef59 100644
--- a/doc/peopleyouknow.md
+++ b/doc/peopleyouknow.md
@@ -1,13 +1,13 @@
-This is your connector settings page.  If you get lost, you can click this link to bring yourself back here.
+This is your connector settings page.  If you get lost, you can click this link to bring yourself back here.
 
 This is the bit that makes Friendica unique.  You can connect to anybody on the internet from your Friendica account using this page!  The available connectors varies depending on which plugins you have installed, but for now, we'll walk you through Facebook.  Note that not all servers have the Facebook connector installed.  If you can't find it in the list below, don't worry, we'll look at ways of connecting to more people in the following pages.  
 
-The biggest of all social networks is Facebook.  Fortunately, this connector is really easy.  Scroll down the page, and click Facebook Connector Settings.  Enter your Facebook user name and password and let the application (the connector) do everything the options suggest.  You can fine tune this or experiment with the other connectors too.  If you need help, you can always ask at Friendica Support or see the instructions here.
+The biggest of all social networks is Facebook.  Fortunately, this connector is really easy.  Scroll down the page, and click Facebook Connector Settings.  Enter your Facebook user name and password and let the application (the connector) do everything the options suggest.  You can fine tune this or experiment with the other connectors too.  If you need help, you can always ask at Friendica Support or see the instructions here.
 
-When you're ready, we can move on to making new friends.
+When you're ready, we can move on to making new friends.
 
 
 
-
+
 
 
diff --git a/htconfig.php b/htconfig.php
old mode 100755
new mode 100644
index 9d9c8a2c7..63a40c809
--- a/htconfig.php
+++ b/htconfig.php
@@ -83,5 +83,8 @@ $a->config['system']['no_regfullname'] = true;
 // If set to true the priority settings of ostatus contacts are used
 $a->config['system']['ostatus_use_priority'] = false;
 
-// If enabled all items are cached in the given directory
+// If enabled, all items are cached in the given directory
 $a->config['system']['itemcache'] = "";
+
+// If enabled, the lockpath is used for a lockfile to check if the poller is running
+$a->config['system']['lockpath'] = "";
diff --git a/images/article.gif b/images/article.gif
old mode 100755
new mode 100644
diff --git a/images/audio.gif b/images/audio.gif
old mode 100755
new mode 100644
diff --git a/images/b_block.gif b/images/b_block.gif
old mode 100755
new mode 100644
diff --git a/images/b_drop.gif b/images/b_drop.gif
old mode 100755
new mode 100644
diff --git a/images/b_drop.png b/images/b_drop.png
old mode 100755
new mode 100644
diff --git a/images/b_drophide.gif b/images/b_drophide.gif
old mode 100755
new mode 100644
diff --git a/images/b_dropshow.gif b/images/b_dropshow.gif
old mode 100755
new mode 100644
diff --git a/images/b_edit.gif b/images/b_edit.gif
old mode 100755
new mode 100644
diff --git a/images/b_edit.png b/images/b_edit.png
old mode 100755
new mode 100644
diff --git a/images/calendar.png b/images/calendar.png
old mode 100755
new mode 100644
diff --git a/images/camera-icon.gif b/images/camera-icon.gif
old mode 100755
new mode 100644
diff --git a/images/connect-bg.png b/images/connect-bg.png
old mode 100755
new mode 100644
diff --git a/images/content-types.png b/images/content-types.png
old mode 100755
new mode 100644
diff --git a/images/default-group-mm.png b/images/default-group-mm.png
old mode 100755
new mode 100644
diff --git a/images/default-profile-mm.jpg b/images/default-profile-mm.jpg
old mode 100755
new mode 100644
diff --git a/images/default-profile-sm.jpg b/images/default-profile-sm.jpg
old mode 100755
new mode 100644
diff --git a/images/default-profile.jpg b/images/default-profile.jpg
old mode 100755
new mode 100644
diff --git a/images/diaspora.png b/images/diaspora.png
old mode 100755
new mode 100644
diff --git a/images/dislike.gif b/images/dislike.gif
old mode 100755
new mode 100644
diff --git a/images/document.gif b/images/document.gif
old mode 100755
new mode 100644
diff --git a/images/ff-128.jpg b/images/ff-128.jpg
old mode 100755
new mode 100644
diff --git a/images/ff-16.jpg b/images/ff-16.jpg
old mode 100755
new mode 100644
diff --git a/images/ff-256.jpg b/images/ff-256.jpg
old mode 100755
new mode 100644
diff --git a/images/ff-32.jpg b/images/ff-32.jpg
old mode 100755
new mode 100644
diff --git a/images/ff-64.jpg b/images/ff-64.jpg
old mode 100755
new mode 100644
diff --git a/images/ff.xcf b/images/ff.xcf
old mode 100755
new mode 100644
diff --git a/images/friendica-128.jpg b/images/friendica-128.jpg
old mode 100755
new mode 100644
diff --git a/images/friendica-128.png b/images/friendica-128.png
old mode 100755
new mode 100644
diff --git a/images/friendica-16.jpg b/images/friendica-16.jpg
old mode 100755
new mode 100644
diff --git a/images/friendica-16.png b/images/friendica-16.png
old mode 100755
new mode 100644
diff --git a/images/friendica-1600.png b/images/friendica-1600.png
old mode 100755
new mode 100644
diff --git a/images/friendica-256.jpg b/images/friendica-256.jpg
old mode 100755
new mode 100644
diff --git a/images/friendica-256.png b/images/friendica-256.png
old mode 100755
new mode 100644
diff --git a/images/friendica-32.jpg b/images/friendica-32.jpg
old mode 100755
new mode 100644
diff --git a/images/friendica-32.png b/images/friendica-32.png
old mode 100755
new mode 100644
diff --git a/images/friendica-48.png b/images/friendica-48.png
old mode 100755
new mode 100644
diff --git a/images/friendica-64.jpg b/images/friendica-64.jpg
old mode 100755
new mode 100644
diff --git a/images/friendica-64.png b/images/friendica-64.png
old mode 100755
new mode 100644
diff --git a/images/friendica-96.png b/images/friendica-96.png
old mode 100755
new mode 100644
diff --git a/images/friendica.svg b/images/friendica.svg
old mode 100755
new mode 100644
diff --git a/images/friendika-128.jpg b/images/friendika-128.jpg
old mode 100755
new mode 100644
diff --git a/images/friendika-128.png b/images/friendika-128.png
old mode 100755
new mode 100644
diff --git a/images/friendika-16.jpg b/images/friendika-16.jpg
old mode 100755
new mode 100644
diff --git a/images/friendika-16.png b/images/friendika-16.png
old mode 100755
new mode 100644
diff --git a/images/friendika-1600.png b/images/friendika-1600.png
old mode 100755
new mode 100644
diff --git a/images/friendika-256.jpg b/images/friendika-256.jpg
old mode 100755
new mode 100644
diff --git a/images/friendika-256.png b/images/friendika-256.png
old mode 100755
new mode 100644
diff --git a/images/friendika-32.jpg b/images/friendika-32.jpg
old mode 100755
new mode 100644
diff --git a/images/friendika-32.png b/images/friendika-32.png
old mode 100755
new mode 100644
diff --git a/images/friendika-48.png b/images/friendika-48.png
old mode 100755
new mode 100644
diff --git a/images/friendika-64.jpg b/images/friendika-64.jpg
old mode 100755
new mode 100644
diff --git a/images/friendika-64.png b/images/friendika-64.png
old mode 100755
new mode 100644
diff --git a/images/friendika-96.png b/images/friendika-96.png
old mode 100755
new mode 100644
diff --git a/images/friendika.svg b/images/friendika.svg
old mode 100755
new mode 100644
diff --git a/images/globe.gif b/images/globe.gif
old mode 100755
new mode 100644
diff --git a/images/hide_off.png b/images/hide_off.png
old mode 100755
new mode 100644
diff --git a/images/hide_on.png b/images/hide_on.png
old mode 100755
new mode 100644
diff --git a/images/icons.png b/images/icons.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/add.png b/images/icons/10/add.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/delete.png b/images/icons/10/delete.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/edit.png b/images/icons/10/edit.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/feed.png b/images/icons/10/feed.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/gear.png b/images/icons/10/gear.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/group.png b/images/icons/10/group.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/info.png b/images/icons/10/info.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/link.png b/images/icons/10/link.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/lock.png b/images/icons/10/lock.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/menu.png b/images/icons/10/menu.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/notice.png b/images/icons/10/notice.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/notify_off.png b/images/icons/10/notify_off.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/notify_on.png b/images/icons/10/notify_on.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/play.png b/images/icons/10/play.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/plugin.png b/images/icons/10/plugin.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/star.png b/images/icons/10/star.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/unlock.png b/images/icons/10/unlock.png
old mode 100755
new mode 100644
diff --git a/images/icons/10/user.png b/images/icons/10/user.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/add.png b/images/icons/16/add.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/delete.png b/images/icons/16/delete.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/edit.png b/images/icons/16/edit.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/feed.png b/images/icons/16/feed.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/gear.png b/images/icons/16/gear.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/group.png b/images/icons/16/group.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/info.png b/images/icons/16/info.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/link.png b/images/icons/16/link.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/lock.png b/images/icons/16/lock.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/menu.png b/images/icons/16/menu.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/notice.png b/images/icons/16/notice.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/notify_off.png b/images/icons/16/notify_off.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/notify_on.png b/images/icons/16/notify_on.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/play.png b/images/icons/16/play.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/plugin.png b/images/icons/16/plugin.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/star.png b/images/icons/16/star.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/unlock.png b/images/icons/16/unlock.png
old mode 100755
new mode 100644
diff --git a/images/icons/16/user.png b/images/icons/16/user.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/add.png b/images/icons/22/add.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/delete.png b/images/icons/22/delete.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/edit.png b/images/icons/22/edit.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/feed.png b/images/icons/22/feed.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/gear.png b/images/icons/22/gear.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/group.png b/images/icons/22/group.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/info.png b/images/icons/22/info.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/link.png b/images/icons/22/link.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/lock.png b/images/icons/22/lock.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/menu.png b/images/icons/22/menu.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/notice.png b/images/icons/22/notice.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/notify_off.png b/images/icons/22/notify_off.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/notify_on.png b/images/icons/22/notify_on.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/play.png b/images/icons/22/play.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/plugin.png b/images/icons/22/plugin.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/star.png b/images/icons/22/star.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/unlock.png b/images/icons/22/unlock.png
old mode 100755
new mode 100644
diff --git a/images/icons/22/user.png b/images/icons/22/user.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/add.png b/images/icons/48/add.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/delete.png b/images/icons/48/delete.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/edit.png b/images/icons/48/edit.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/feed.png b/images/icons/48/feed.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/gear.png b/images/icons/48/gear.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/group.png b/images/icons/48/group.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/info.png b/images/icons/48/info.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/link.png b/images/icons/48/link.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/lock.png b/images/icons/48/lock.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/menu.png b/images/icons/48/menu.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/notice.png b/images/icons/48/notice.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/notify_off.png b/images/icons/48/notify_off.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/notify_on.png b/images/icons/48/notify_on.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/play.png b/images/icons/48/play.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/plugin.png b/images/icons/48/plugin.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/star.png b/images/icons/48/star.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/unlock.png b/images/icons/48/unlock.png
old mode 100755
new mode 100644
diff --git a/images/icons/48/user.png b/images/icons/48/user.png
old mode 100755
new mode 100644
diff --git a/images/icons/Makefile b/images/icons/Makefile
old mode 100755
new mode 100644
diff --git a/images/icons/add.png b/images/icons/add.png
old mode 100755
new mode 100644
diff --git a/images/icons/delete.png b/images/icons/delete.png
old mode 100755
new mode 100644
diff --git a/images/icons/edit.png b/images/icons/edit.png
old mode 100755
new mode 100644
diff --git a/images/icons/feed.png b/images/icons/feed.png
old mode 100755
new mode 100644
diff --git a/images/icons/gear.png b/images/icons/gear.png
old mode 100755
new mode 100644
diff --git a/images/icons/group.png b/images/icons/group.png
old mode 100755
new mode 100644
diff --git a/images/icons/info.png b/images/icons/info.png
old mode 100755
new mode 100644
diff --git a/images/icons/link.png b/images/icons/link.png
old mode 100755
new mode 100644
diff --git a/images/icons/lock.png b/images/icons/lock.png
old mode 100755
new mode 100644
diff --git a/images/icons/menu.png b/images/icons/menu.png
old mode 100755
new mode 100644
diff --git a/images/icons/notice.png b/images/icons/notice.png
old mode 100755
new mode 100644
diff --git a/images/icons/notify_off.png b/images/icons/notify_off.png
old mode 100755
new mode 100644
diff --git a/images/icons/notify_on.png b/images/icons/notify_on.png
old mode 100755
new mode 100644
diff --git a/images/icons/play.png b/images/icons/play.png
old mode 100755
new mode 100644
diff --git a/images/icons/plugin.png b/images/icons/plugin.png
old mode 100755
new mode 100644
diff --git a/images/icons/star.png b/images/icons/star.png
old mode 100755
new mode 100644
diff --git a/images/icons/unlock.png b/images/icons/unlock.png
old mode 100755
new mode 100644
diff --git a/images/icons/user.png b/images/icons/user.png
old mode 100755
new mode 100644
diff --git a/images/larrow.gif b/images/larrow.gif
old mode 100755
new mode 100644
diff --git a/images/larrw.gif b/images/larrw.gif
old mode 100755
new mode 100644
diff --git a/images/like.gif b/images/like.gif
old mode 100755
new mode 100644
diff --git a/images/link-icon.gif b/images/link-icon.gif
old mode 100755
new mode 100644
diff --git a/images/lock_icon.gif b/images/lock_icon.gif
old mode 100755
new mode 100644
diff --git a/images/logo.png b/images/logo.png
old mode 100755
new mode 100644
diff --git a/images/lrarrow.gif b/images/lrarrow.gif
old mode 100755
new mode 100644
diff --git a/images/mapicon.gif b/images/mapicon.gif
old mode 100755
new mode 100644
diff --git a/images/no.gif b/images/no.gif
old mode 100755
new mode 100644
diff --git a/images/noglobe.gif b/images/noglobe.gif
old mode 100755
new mode 100644
diff --git a/images/nosign.jpg b/images/nosign.jpg
old mode 100755
new mode 100644
diff --git a/images/onoff.jpg b/images/onoff.jpg
old mode 100755
new mode 100644
diff --git a/images/pause.gif b/images/pause.gif
old mode 100755
new mode 100644
diff --git a/images/pen.png b/images/pen.png
old mode 100755
new mode 100644
diff --git a/images/pencil.gif b/images/pencil.gif
old mode 100755
new mode 100644
diff --git a/images/penhover.png b/images/penhover.png
old mode 100755
new mode 100644
diff --git a/images/people.gif b/images/people.gif
old mode 100755
new mode 100644
diff --git a/images/play.gif b/images/play.gif
old mode 100755
new mode 100644
diff --git a/images/plugin.png b/images/plugin.png
old mode 100755
new mode 100644
diff --git a/images/rarrow.gif b/images/rarrow.gif
old mode 100755
new mode 100644
diff --git a/images/rarrw.gif b/images/rarrw.gif
old mode 100755
new mode 100644
diff --git a/images/recycle.gif b/images/recycle.gif
old mode 100755
new mode 100644
diff --git a/images/remote-link.gif b/images/remote-link.gif
old mode 100755
new mode 100644
diff --git a/images/rotator.gif b/images/rotator.gif
old mode 100755
new mode 100644
diff --git a/images/search_18.png b/images/search_18.png
old mode 100755
new mode 100644
diff --git a/images/selected.png b/images/selected.png
old mode 100755
new mode 100644
diff --git a/images/share.gif b/images/share.gif
old mode 100755
new mode 100644
diff --git a/images/show_all_off.png b/images/show_all_off.png
old mode 100755
new mode 100644
diff --git a/images/show_all_on.png b/images/show_all_on.png
old mode 100755
new mode 100644
diff --git a/images/show_off.png b/images/show_off.png
old mode 100755
new mode 100644
diff --git a/images/show_on.png b/images/show_on.png
old mode 100755
new mode 100644
diff --git a/images/smiley-Oo.gif b/images/smiley-Oo.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-brokenheart.gif b/images/smiley-brokenheart.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-cool.gif b/images/smiley-cool.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-cry.gif b/images/smiley-cry.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-embarassed.gif b/images/smiley-embarassed.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-foot-in-mouth.gif b/images/smiley-foot-in-mouth.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-frown.gif b/images/smiley-frown.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-heart.gif b/images/smiley-heart.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-innocent.gif b/images/smiley-innocent.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-kiss.gif b/images/smiley-kiss.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-laughing.gif b/images/smiley-laughing.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-money-mouth.gif b/images/smiley-money-mouth.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-sealed.gif b/images/smiley-sealed.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-smile.gif b/images/smiley-smile.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-surprised.gif b/images/smiley-surprised.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-thumbsup.gif b/images/smiley-thumbsup.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-tongue-out.gif b/images/smiley-tongue-out.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-undecided.gif b/images/smiley-undecided.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-wink.gif b/images/smiley-wink.gif
old mode 100755
new mode 100644
diff --git a/images/smiley-yell.gif b/images/smiley-yell.gif
old mode 100755
new mode 100644
diff --git a/images/spencil.gif b/images/spencil.gif
old mode 100755
new mode 100644
diff --git a/images/star.png b/images/star.png
old mode 100755
new mode 100644
diff --git a/images/tag.png b/images/tag.png
old mode 100755
new mode 100644
diff --git a/images/tag_b.png b/images/tag_b.png
old mode 100755
new mode 100644
diff --git a/images/tools.png b/images/tools.png
old mode 100755
new mode 100644
diff --git a/images/twopeople.png b/images/twopeople.png
old mode 100755
new mode 100644
diff --git a/images/unlock_icon.gif b/images/unlock_icon.gif
old mode 100755
new mode 100644
diff --git a/images/video.gif b/images/video.gif
old mode 100755
new mode 100644
diff --git a/images/youtube_icon.gif b/images/youtube_icon.gif
old mode 100755
new mode 100644
diff --git a/include/Contact.php b/include/Contact.php
old mode 100755
new mode 100644
index d9949b1ef..9ba1e8ae5
--- a/include/Contact.php
+++ b/include/Contact.php
@@ -23,16 +23,24 @@ function user_remove($uid) {
 	);
 
 	q("DELETE FROM `contact` WHERE `uid` = %d", intval($uid));
+	q("DELETE FROM `gcign` WHERE `uid` = %d", intval($uid));
 	q("DELETE FROM `group` WHERE `uid` = %d", intval($uid));
 	q("DELETE FROM `group_member` WHERE `uid` = %d", intval($uid));
 	q("DELETE FROM `intro` WHERE `uid` = %d", intval($uid));
 	q("DELETE FROM `event` WHERE `uid` = %d", intval($uid));
 	q("DELETE FROM `item` WHERE `uid` = %d", intval($uid));
+	q("DELETE FROM `item_id` WHERE `uid` = %d", intval($uid));
 	q("DELETE FROM `mail` WHERE `uid` = %d", intval($uid));
+	q("DELETE FROM `mailacct` WHERE `uid` = %d", intval($uid));
+	q("DELETE FROM `manage` WHERE `uid` = %d", intval($uid));
+	q("DELETE FROM `notify` WHERE `uid` = %d", intval($uid));
 	q("DELETE FROM `photo` WHERE `uid` = %d", intval($uid));
+	q("DELETE FROM `attach` WHERE `uid` = %d", intval($uid));
 	q("DELETE FROM `profile` WHERE `uid` = %d", intval($uid));
 	q("DELETE FROM `profile_check` WHERE `uid` = %d", intval($uid));
 	q("DELETE FROM `pconfig` WHERE `uid` = %d", intval($uid));
+	q("DELETE FROM `search` WHERE `uid` = %d", intval($uid));
+	q("DELETE FROM `spam` WHERE `uid` = %d", intval($uid));
 	q("DELETE FROM `user` WHERE `uid` = %d", intval($uid));
 	if($uid == local_user()) {
 		unset($_SESSION['authenticated']);
@@ -134,11 +142,11 @@ function contact_photo_menu($contact) {
 	$posts_link = $a->get_baseurl() . '/network/?cid=' . $contact['id'];
 
 	$menu = Array(
-		t("View status") => $status_link,
-		t("View profile") => $profile_link,
-		t("View photos") => $photos_link,		
-		t("View recent") => $posts_link, 
-		t("Edit contact") => $contact_url,
+		t("View Status") => $status_link,
+		t("View Profile") => $profile_link,
+		t("View Photos") => $photos_link,		
+		t("Network Posts") => $posts_link, 
+		t("Edit Contact") => $contact_url,
 		t("Send PM") => $pm_url,
 	);
 	
@@ -150,7 +158,7 @@ function contact_photo_menu($contact) {
 	$o = "";
 	foreach($menu as $k=>$v){
 		if ($v!="") {
-			if(($k !== t("View recent")) && ($k !== t("Send PM")))
+			if(($k !== t("Network Posts")) && ($k !== t("Send PM")) && ($k !== t('Edit Contact')))
 				$o .= "
  • $k
  • \n"; else $o .= "
  • $k
  • \n"; @@ -158,3 +166,36 @@ function contact_photo_menu($contact) { } return $o; }} + + +function random_profile() { + $r = q("select url from gcontact where url like '%%://%%/profile/%%' order by rand() limit 1"); + if(count($r)) + return dirname($r[0]['url']); + return ''; +} + + +function contacts_not_grouped($uid,$start = 0,$count = 0) { + + if(! $count) { + $r = q("select count(*) as total from contact where uid = %d and self = 0 and id not in (select distinct(`contact-id`) from group_member where uid = %d) ", + intval($uid), + intval($uid) + ); + + return $r; + + + } + + $r = q("select * from contact where uid = %d and self = 0 and id not in (select distinct(`contact-id`) from group_member where uid = %d) and blocked = 0 and pending = 0 limit %d, %d", + intval($uid), + intval($uid), + intval($start), + intval($count) + ); + + return $r; +} + diff --git a/include/EmailNotification.php b/include/EmailNotification.php old mode 100755 new mode 100644 diff --git a/include/Photo.php b/include/Photo.php old mode 100755 new mode 100644 diff --git a/include/Scrape.php b/include/Scrape.php old mode 100755 new mode 100644 index 9c237916b..b20d7d604 --- a/include/Scrape.php +++ b/include/Scrape.php @@ -446,7 +446,7 @@ function probe_url($url, $mode = PROBE_NORMAL) { $phost = substr($url,strpos($url,'@')+1); $profile = 'http://' . $phost; // fix nick character range - $vcard = array('fn' => $name, 'nick' => $name, 'photo' => gravatar_img($url)); + $vcard = array('fn' => $name, 'nick' => $name, 'photo' => avatar_img($url)); $notify = 'smtp ' . random_string(); $poll = 'email ' . random_string(); $priority = 0; @@ -593,7 +593,7 @@ function probe_url($url, $mode = PROBE_NORMAL) { logger('probe_url: fetch feed: ' . $poll . ' returns: ' . $xml, LOGGER_DATA); $a = get_app(); - logger('probe_url: scrape_feed: headers: ' . $a->get_curl_headers(), $LOGGER_DATA); + logger('probe_url: scrape_feed: headers: ' . $a->get_curl_headers(), LOGGER_DATA); $feed->set_raw_data($xml); @@ -655,7 +655,7 @@ function probe_url($url, $mode = PROBE_NORMAL) { } if((! $vcard['photo']) && strlen($email)) - $vcard['photo'] = gravatar_img($email); + $vcard['photo'] = avatar_img($email); if($poll === $profile) $lnk = $feed->get_permalink(); if(isset($lnk) && strlen($lnk)) diff --git a/include/acl_selectors.php b/include/acl_selectors.php old mode 100755 new mode 100644 diff --git a/include/api.php b/include/api.php old mode 100755 new mode 100644 index 065f14cff..f9be68c3d --- a/include/api.php +++ b/include/api.php @@ -121,6 +121,7 @@ if (strpos($a->query_string, ".json")>0) $type="json"; if (strpos($a->query_string, ".rss")>0) $type="rss"; if (strpos($a->query_string, ".atom")>0) $type="atom"; + if (strpos($a->query_string, ".as")>0) $type="as"; $r = call_user_func($info['func'], $a, $type); if ($r===false) return; @@ -144,6 +145,12 @@ header ("Content-Type: application/atom+xml"); return ''."\n".$r; break; + case "as": + //header ("Content-Type: application/json"); + //foreach($r as $rr) + // return json_encode($rr); + return json_encode($r); + break; } //echo "
    "; var_dump($r); die();
    @@ -560,8 +567,17 @@
     		$_REQUEST['profile_uid'] = local_user();
     		if(requestdata('parent'))
     			$_REQUEST['type'] = 'net-comment';
    -		else
    +		else {
     			$_REQUEST['type'] = 'wall';
    +                        if(x($_FILES,'media')) {
    +		                // upload the image if we have one
    +		                $_REQUEST['hush']='yeah'; //tell wall_upload function to return img info instead of echo
    +			        require_once('mod/wall_upload.php');
    +			        $media = wall_upload_post($a);
    +		                if(strlen($media)>0)
    +				        $_REQUEST['body'] .= "\n\n".$media;
    +			        }
    +		}
     
     		// set this so that the item_post() function is quiet and doesn't redirect or emit json
     
    @@ -737,6 +753,13 @@
     			case "atom":
     			case "rss":
     				$data = api_rss_extra($a, $data, $user_info);
    +				break;
    +			case "as":
    +				$as = api_format_as($a, $ret, $user_info);
    +				$as['title'] = $a->config['sitename']." Home Timeline";
    +				$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
    +				return($as);
    +				break;
     		}
     				
     		return  api_apply_template("timeline", $type, $data);
    @@ -744,6 +767,85 @@
     	api_register_func('api/statuses/home_timeline','api_statuses_home_timeline', true);
     	api_register_func('api/statuses/friends_timeline','api_statuses_home_timeline', true);
     
    +	function api_statuses_public_timeline(&$a, $type){
    +		if (local_user()===false) return false;
    +				
    +		$user_info = api_get_user($a);
    +		// get last newtork messages
    +
    +
    +		// params
    +		$count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
    +		$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
    +		if ($page<0) $page=0;
    +		$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
    +		$max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0);
    +		//$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
    +		
    +		$start = $page*$count;
    +
    +		//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
    +
    +		if ($max_id > 0)
    +			$sql_extra = 'AND `item`.`id` <= '.intval($max_id);
    +
    +		/*$r = q("SELECT `item`.*, `item`.`id` AS `item_id`, 
    +			`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
    +			`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
    +			`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
    +			FROM `item`, `contact`
    +			WHERE `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
    +			AND `item`.`allow_cid` = ''  AND `item`.`allow_gid` = '' 
    +			AND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = '' 
    +			AND `item`.`private` = 0 AND `item`.`wall` = 1 AND `user`.`hidewall` = 0
    +			AND `contact`.`id` = `item`.`contact-id`
    +			AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
    +			$sql_extra
    +			AND `item`.`id`>%d
    +			ORDER BY `item`.`received` DESC LIMIT %d ,%d ",
    +			intval($since_id),
    +			intval($start),	intval($count)
    +		);*/
    +	        $r = q("SELECT `item`.*, `item`.`id` AS `item_id`, 
    +	                `contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
    +        	        `contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`, 
    +                	`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`,
    +                	`user`.`nickname`, `user`.`hidewall`
    +                	FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
    +                	LEFT JOIN `user` ON `user`.`uid` = `item`.`uid`
    +                	WHERE `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0
    +                	AND `item`.`allow_cid` = ''  AND `item`.`allow_gid` = '' 
    +                	AND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = '' 
    +                	AND `item`.`private` = 0 AND `item`.`wall` = 1 AND `user`.`hidewall` = 0 
    +                	AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
    +			$sql_extra
    +			AND `item`.`id`>%d
    +                	ORDER BY `received` DESC LIMIT %d, %d ",
    +			intval($since_id),
    +                	intval($start),
    +                	intval($count));
    +
    +		$ret = api_format_items($r,$user_info);
    +
    +		
    +		$data = array('$statuses' => $ret);
    +		switch($type){
    +			case "atom":
    +			case "rss":
    +				$data = api_rss_extra($a, $data, $user_info);
    +				break;
    +			case "as":
    +				$as = api_format_as($a, $ret, $user_info);
    +				$as['title'] = $a->config['sitename']." Public Timeline";
    +				$as['link']['url'] = $a->get_baseurl()."/";
    +				return($as);
    +				break;
    +		}
    +				
    +		return  api_apply_template("timeline", $type, $data);
    +	}
    +	api_register_func('api/statuses/public_timeline','api_statuses_public_timeline', true);
    +
     	/**
     	 * 
     	 */
    @@ -784,8 +886,152 @@
     	}
     	api_register_func('api/statuses/show','api_statuses_show', true);
     
    -	//api_register_func('api/statuses/mentions','api_statuses_mentions', true);
    -	//api_register_func('api/statuses/replies','api_statuses_mentions', true);
    +
    +	/**
    +	 * 
    +	 */
    +	function api_statuses_repeat(&$a, $type){
    +		if (local_user()===false) return false;
    +
    +		$user_info = api_get_user($a);
    +
    +		// params
    +		$id = intval($a->argv[3]);
    +
    +		logger('API: api_statuses_repeat: '.$id);		
    +
    +		//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
    +
    +		$r = q("SELECT `item`.*, `item`.`id` AS `item_id`, `contact`.`nick` as `reply_author`,
    +			`contact`.`name`, `contact`.`photo`, `contact`.`url` as `reply_url`, `contact`.`rel`,
    +			`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
    +			`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
    +			FROM `item`, `contact`
    +			WHERE `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
    +			AND `contact`.`id` = `item`.`contact-id`
    +			AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
    +			$sql_extra
    +			AND `item`.`id`=%d",
    +			intval($id)
    +		);
    +
    +		$_REQUEST['body'] = html_entity_decode("♲ ", ENT_QUOTES, 'UTF-8')."[url=".$r[0]['reply_url']."]".$r[0]['reply_author']."[/url] \n".$r[0]['body'];
    +		$_REQUEST['profile_uid'] = local_user();
    +		$_REQUEST['type'] = 'wall';
    +		$_REQUEST['api_source'] = true;
    +
    +		require_once('mod/item.php');
    +		item_post($a);
    +
    +		if ($type == 'xml')
    +			$ok = "true";
    +		else
    +			$ok = "ok";
    +
    +		return api_apply_template('test', $type, array('$ok' => $ok));
    +	}
    +	api_register_func('api/statuses/retweet','api_statuses_repeat', true);
    +
    +	/**
    +	 * 
    +	 */
    +	function api_statuses_destroy(&$a, $type){
    +		if (local_user()===false) return false;
    +
    +		$user_info = api_get_user($a);
    +
    +		// params
    +		$id = intval($a->argv[3]);
    +
    +		logger('API: api_statuses_destroy: '.$id);	
    +
    +		require_once('include/items.php');
    +		drop_item($id, false);
    +
    +		if ($type == 'xml')
    +			$ok = "true";
    +		else
    +			$ok = "ok";
    +
    +		return api_apply_template('test', $type, array('$ok' => $ok));
    +	}
    +	api_register_func('api/statuses/destroy','api_statuses_destroy', true);
    +
    +	/**
    +	 * 
    +	 * http://developer.twitter.com/doc/get/statuses/mentions
    +	 * 
    +	 */
    +	function api_statuses_mentions(&$a, $type){
    +		if (local_user()===false) return false;
    +				
    +		$user_info = api_get_user($a);
    +		// get last newtork messages
    +
    +
    +		// params
    +		$count = (x($_REQUEST,'count')?$_REQUEST['count']:20);
    +		$page = (x($_REQUEST,'page')?$_REQUEST['page']-1:0);
    +		if ($page<0) $page=0;
    +		$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
    +		$max_id = (x($_REQUEST,'max_id')?$_REQUEST['max_id']:0);
    +		//$since_id = 0;//$since_id = (x($_REQUEST,'since_id')?$_REQUEST['since_id']:0);
    +		
    +		$start = $page*$count;
    +
    +		//$include_entities = (x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:false);
    +
    +		$myurl = $a->get_baseurl() . '/profile/'. $a->user['nickname'];
    +		$myurl = substr($myurl,strpos($myurl,'://')+3);
    +		$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
    +		$diasp_url = str_replace('/profile/','/u/',$myurl);
    +		$sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where ( `author-link` regexp '%s' or `tag` regexp '%s' or tag regexp '%s' )) ",
    +			dbesc($myurl . '$'),
    +			dbesc($myurl . '\\]'),
    +			dbesc($diasp_url . '\\]')
    +		);
    +
    +		if ($max_id > 0)
    +			$sql_extra .= ' AND `item`.`id` <= '.intval($max_id);
    +
    +		$r = q("SELECT `item`.*, `item`.`id` AS `item_id`, 
    +			`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
    +			`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
    +			`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
    +			FROM `item`, `contact`
    +			WHERE `item`.`uid` = %d
    +			AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
    +			AND `contact`.`id` = `item`.`contact-id`
    +			AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
    +			$sql_extra
    +			AND `item`.`id`>%d
    +			ORDER BY `item`.`received` DESC LIMIT %d ,%d ",
    +			intval($user_info['uid']),
    +			intval($since_id),
    +			intval($start),	intval($count)
    +		);
    +
    +		$ret = api_format_items($r,$user_info);
    +
    +		
    +		$data = array('$statuses' => $ret);
    +		switch($type){
    +			case "atom":
    +			case "rss":
    +				$data = api_rss_extra($a, $data, $user_info);
    +				break;
    +			case "as":
    +				$as = api_format_as($a, $ret, $user_info);
    +				$as["title"] = $a->config['sitename']." Mentions";
    +				$as['link']['url'] = $a->get_baseurl()."/";
    +				return($as);
    +				break;
    +		}
    +				
    +		return  api_apply_template("timeline", $type, $data);
    +	}
    +	api_register_func('api/statuses/mentions','api_statuses_mentions', true);
    +	api_register_func('api/statuses/replies','api_statuses_mentions', true);
     
     
     	function api_statuses_user_timeline(&$a, $type){
    @@ -898,6 +1144,70 @@
     
     	api_register_func('api/favorites','api_favorites', true);
     
    +	function api_format_as($a, $ret, $user_info) {
    +
    +		$as = array();
    +		$as['title'] = $a->config['sitename']." Public Timeline";
    +		$items = array();
    +		foreach ($ret as $item) {
    +			$singleitem["actor"]["displayName"] = $item["user"]["name"];
    +			$singleitem["actor"]["id"] = $item["user"]["contact_url"];
    +			$avatar[0]["url"] = $item["user"]["profile_image_url"];
    +			$avatar[0]["rel"] = "avatar";
    +			$avatar[0]["type"] = "";
    +			$avatar[0]["width"] = 96;
    +			$avatar[0]["height"] = 96;
    +			$avatar[1]["url"] = $item["user"]["profile_image_url"];
    +			$avatar[1]["rel"] = "avatar";
    +			$avatar[1]["type"] = "";
    +			$avatar[1]["width"] = 48;
    +			$avatar[1]["height"] = 48;
    +			$avatar[2]["url"] = $item["user"]["profile_image_url"];
    +			$avatar[2]["rel"] = "avatar";
    +			$avatar[2]["type"] = "";
    +			$avatar[2]["width"] = 24;
    +			$avatar[2]["height"] = 24;
    +			$singleitem["actor"]["avatarLinks"] = $avatar;
    +
    +			$singleitem["actor"]["image"]["url"] = $item["user"]["profile_image_url"];
    +			$singleitem["actor"]["image"]["rel"] = "avatar";
    +			$singleitem["actor"]["image"]["type"] = "";
    +			$singleitem["actor"]["image"]["width"] = 96;
    +			$singleitem["actor"]["image"]["height"] = 96;
    +			$singleitem["actor"]["type"] = "person";
    +			$singleitem["actor"]["url"] = $item["person"]["contact_url"];
    +			$singleitem["actor"]["statusnet:profile_info"]["local_id"] = $item["user"]["id"];
    +			$singleitem["actor"]["statusnet:profile_info"]["following"] = $item["user"]["following"] ? "true" : "false";
    +			$singleitem["actor"]["statusnet:profile_info"]["blocking"] = "false";
    +			$singleitem["actor"]["contact"]["preferredUsername"] = $item["user"]["screen_name"];
    +			$singleitem["actor"]["contact"]["displayName"] = $item["user"]["name"];
    +			$singleitem["actor"]["contact"]["addresses"] = "";
    +
    +			$singleitem["body"] = $item["text"];
    +			$singleitem["object"]["displayName"] = $item["text"];
    +			$singleitem["object"]["id"] = $item["url"];
    +			$singleitem["object"]["type"] = "note";
    +			$singleitem["object"]["url"] = $item["url"];
    +			//$singleitem["context"] =;
    +			$singleitem["postedTime"] = date("c", strtotime($item["published"]));
    +			$singleitem["provider"]["objectType"] = "service";
    +			$singleitem["provider"]["displayName"] = "Test";
    +			$singleitem["provider"]["url"] = "http://test.tld";
    +			$singleitem["title"] = $item["text"];
    +			$singleitem["verb"] = "post";
    +			$singleitem["statusnet:notice_info"]["local_id"] = $item["id"];
    +				$singleitem["statusnet:notice_info"]["source"] = $item["source"];
    +				$singleitem["statusnet:notice_info"]["favorite"] = "false";
    +				$singleitem["statusnet:notice_info"]["repeated"] = "false";
    +				//$singleitem["original"] = $item;
    +				$items[] = $singleitem;
    +		}
    +		$as['items'] = $items;
    +		$as['link']['url'] = $a->get_baseurl()."/".$user_info["screen_name"]."/all";
    +		$as['link']['rel'] = "alternate";
    +		$as['link']['type'] = "text/html";
    +		return($as);
    +	}
     	
     	function api_format_items($r,$user_info) {
     
    @@ -932,8 +1242,17 @@
     				$in_reply_to_status_id = 0;
     			}
     
    +			// Workaround for ostatus messages where the title is identically to the body
    +			$statusbody = trim(html2plain(bbcode($item['body']), 0));
    +			$statustitle = trim($item['title']);
    +
    +			if (($statustitle != '') and (strpos($statusbody, $statustitle) !== false))
    +				$statustext = trim($statusbody);
    +			else
    +				$statustext = trim($statustitle."\n\n".$statusbody);
    +
     			$status = array(
    -				'text'		=> trim($item['title']." \n".html2plain(bbcode($item['body']), 0)),
    +				'text'		=> $statustext,
     				'truncated' => False,
     				'created_at'=> api_date($item['created']),
     				'in_reply_to_status_id' => $in_reply_to_status_id,
    @@ -944,8 +1263,8 @@
     				'geo' => '',
     				'favorited' => $item['starred'] ? true : false,
     				'user' =>  $status_user ,
    -				'statusnet_html'		=> bbcode($item['body']),
    -				'statusnet_conversation_id'	=> 0,
    +				'statusnet_html'		=> trim(bbcode($item['body'])),
    +				'statusnet_conversation_id'	=> $item['parent'],
     			);
     
     			// Seesmic doesn't like the following content
    @@ -1309,12 +1628,10 @@
     
     /*
     Not implemented by now:
    -statuses/public_timeline
    -statuses/mentions
    -statuses/replies
    +favorites
    +favorites/create
    +favorites/destroy
     statuses/retweets_of_me
    -statuses/destroy
    -statuses/retweet
     friendships/create
     friendships/destroy
     friendships/exists
    @@ -1322,9 +1639,6 @@ friendships/show
     account/update_location
     account/update_profile_background_image
     account/update_profile_image
    -favorites
    -favorites/create
    -favorites/destroy
     blocks/create
     blocks/destroy
     oauth/authorize
    diff --git a/include/attach.php b/include/attach.php
    old mode 100755
    new mode 100644
    diff --git a/include/auth.php b/include/auth.php
    old mode 100755
    new mode 100644
    diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php
    old mode 100755
    new mode 100644
    diff --git a/include/bbcode.php b/include/bbcode.php
    index 9befbd0f7..85d310b75 100644
    --- a/include/bbcode.php
    +++ b/include/bbcode.php
    @@ -230,7 +230,8 @@ function bbcode($Text,$preserve_nl = false) {
                     	             $Text);
     
     	// [img=widthxheight]image source[/img]
    -	$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '', $Text);
    +	//$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '', $Text);
    +	$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '', $Text);
     
     	// Images
     	// [img]pathtoimage[/img]
    @@ -297,6 +298,9 @@ function bbcode($Text,$preserve_nl = false) {
     	$Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim',$Text);
     	$Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim',$Text);
     
    +
    +	$Text = preg_replace('/\[\&\;([#a-z0-9]+)\;\]/','&$1;',$Text);
    +
     	// fix any escaped ampersands that may have been converted into links
     	$Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism",'<$1$2=$3&$4>',$Text);
     	if(strlen($saved_image))
    diff --git a/include/cache.php b/include/cache.php
    old mode 100755
    new mode 100644
    diff --git a/include/config.php b/include/config.php
    old mode 100755
    new mode 100644
    index 2cddda0b8..4cff38090
    --- a/include/config.php
    +++ b/include/config.php
    @@ -80,6 +80,7 @@ function set_config($family,$key,$value) {
     	
     	// manage array value
     	$dbvalue = (is_array($value)?serialize($value):$value);
    +	$dbvalue = (is_bool($value) ? intval($value) : $value);
     
     	if(get_config($family,$key,true) === false) {
     		$a->config[$family][$key] = $value;
    diff --git a/include/contact_selectors.php b/include/contact_selectors.php
    old mode 100755
    new mode 100644
    diff --git a/include/contact_widgets.php b/include/contact_widgets.php
    old mode 100755
    new mode 100644
    index 7346b95af..96b02f293
    --- a/include/contact_widgets.php
    +++ b/include/contact_widgets.php
    @@ -12,6 +12,7 @@ function follow_widget() {
     }
     
     function findpeople_widget() {
    +	require_once('include/Contact.php');
     
     	$a = get_app();
     
    @@ -32,6 +33,7 @@ function findpeople_widget() {
     		'$findthem' => t('Find'),
     		'$suggest' => t('Friend Suggestions'),
     		'$similar' => t('Similar Interests'),
    +		'$random' => t('Random Profile'),
     		'$inv' => t('Invite Friends')
     	));
     
    @@ -103,3 +105,31 @@ function fileas_widget($baseurl,$selected = '') {
     	));
     }
     
    +function categories_widget($baseurl,$selected = '') {
    +	$a = get_app();
    +
    +	$saved = get_pconfig($a->profile['profile_uid'],'system','filetags');
    +	if(! strlen($saved))
    +		return;
    +
    +	$matches = false;
    +	$terms = array();
    +        $cnt = preg_match_all('/<(.*?)>/',$saved,$matches,PREG_SET_ORDER);
    +        if($cnt) {
    +                foreach($matches as $mtch) {
    +		        $unescaped = xmlify(file_tag_decode($mtch[1]));
    +			$terms[] = array('name' => $unescaped,'selected' => (($selected == $unescaped) ? '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,
    +
    +	));
    +}
    +
    diff --git a/include/conversation.php b/include/conversation.php
    old mode 100755
    new mode 100644
    index 5a922b2b5..1b869b91e
    --- a/include/conversation.php
    +++ b/include/conversation.php
    @@ -342,7 +342,6 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
     					'body' => template_escape($body),
     					'text' => strip_tags(template_escape($body)),
     					'ago' => (($item['app']) ? sprintf( t('%s from %s'),relative_date($item['created']),$item['app']) : relative_date($item['created'])),
    -					'lock' => $lock,
     					'location' => template_escape($location),
     					'indent' => '',
     					'owner_name' => template_escape($owner_name),
    @@ -400,6 +399,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
     			}
     
     			$comments_collapsed = false;
    +			$comments_seen = 0;
     			$comment_lastcollapsed = false;
     			$comment_firstcollapsed = false;
     			$blowhard = 0;
    @@ -559,10 +559,10 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
     					}
     				}
     
    -				$edpost = (((($profile_owner == local_user()) && ($toplevelpost) && (intval($item['wall']) == 1)) || ($mode === 'notes'))
    -						? array($a->get_baseurl($ssl_state)."/editpost/".$item['id'], t("Edit"))
    -						: False);
    -
    +				if(local_user() && link_compare($a->contact['url'],$item['author-link']))
    +					$edpost = array($a->get_baseurl($ssl_state)."/editpost/".$item['id'], t("Edit"));
    +				else
    +					$edpost = false;
     
     				$drop = '';
     				$dropping = false;
    @@ -626,10 +626,6 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
     				else
     					$profile_avatar = (((strlen($item['author-avatar'])) && $diff_author) ? $item['author-avatar'] : $thumb);
     
    -
    -
    -
    -
     				$like    = ((x($alike,$item['id'])) ? format_like($alike[$item['id']],$alike[$item['id'] . '-l'],'like',$item['id']) : '');
     				$dislike = ((x($dlike,$item['id'])) ? format_like($dlike[$item['id']],$dlike[$item['id'] . '-l'],'dislike',$item['id']) : '');
     
    @@ -713,7 +709,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
     	}
     
     	$page_template = get_markup_template("conversation.tpl");
    -	$o .= replace_macros($page_template, array(
    +	$o = replace_macros($page_template, array(
     		'$baseurl' => $a->get_baseurl($ssl_state),
     		'$mode' => $mode,
     		'$user' => $a->user,
    @@ -810,11 +806,11 @@ function item_photo_menu($item){
     	}
     
     	$menu = Array(
    -		t("View status") => $status_link,
    -		t("View profile") => $profile_link,
    -		t("View photos") => $photos_link,
    -		t("View recent") => $posts_link, 
    -		t("Edit contact") => $contact_url,
    +		t("View Status") => $status_link,
    +		t("View Profile") => $profile_link,
    +		t("View Photos") => $photos_link,
    +		t("Network Posts") => $posts_link, 
    +		t("Edit Contact") => $contact_url,
     		t("Send PM") => $pm_url,
     	);
     	
    @@ -974,6 +970,8 @@ function status_editor($a,$x, $notes_cid = 0, $popup=false) {
     		'$shortnoloc' => t('clear location'),
     		'$title' => "",
     		'$placeholdertitle' => t('Set title'),
    +		'$category' => "",
    +		'$placeholdercategory' => t('Categories (comma-separated list)'),
     		'$wait' => t('Please wait'),
     		'$permset' => t('Permission settings'),
     		'$shortpermset' => t('permissions'),
    @@ -1076,7 +1074,6 @@ function find_thread_parent_index($arr,$x) {
     }
     
     function render_location_google($item) {
    -	$location = '';
     	$location = (($item['location']) ? '' . $item['location'] . '' : '');
     	$coord = (($item['coord']) ? '' . $item['coord'] . '' : '');
     	if($coord) {
    @@ -1087,4 +1084,3 @@ function render_location_google($item) {
     	}
     	return $location;
     }
    -
    diff --git a/include/cronhooks.php b/include/cronhooks.php
    old mode 100755
    new mode 100644
    diff --git a/include/crypto.php b/include/crypto.php
    old mode 100755
    new mode 100644
    diff --git a/include/datetime.php b/include/datetime.php
    old mode 100755
    new mode 100644
    index 6d395fe3f..f4dcfce62
    --- a/include/datetime.php
    +++ b/include/datetime.php
    @@ -80,6 +80,16 @@ function field_timezone($name='timezone', $label='', $current = 'America/Los_Ang
     if(! function_exists('datetime_convert')) {
     function datetime_convert($from = 'UTC', $to = 'UTC', $s = 'now', $fmt = "Y-m-d H:i:s") {
     
    +	// Defaults to UTC if nothing is set, but throws an exception if set to empty string.
    +	// Provide some sane defaults regardless.
    +
    +	if($from === '')
    +		$from = 'UTC';
    +	if($to === '')
    +		$to = 'UTC';
    +	if($s === '')
    +		$s = 'now';
    +
     	// Slight hackish adjustment so that 'zero' datetime actually returns what is intended
     	// otherwise we end up with -0001-11-30 ...
     	// add 32 days so that we at least get year 00, and then hack around the fact that 
    diff --git a/include/dba.php b/include/dba.php
    old mode 100755
    new mode 100644
    index 76cc0bc7b..44a663eac
    --- a/include/dba.php
    +++ b/include/dba.php
    @@ -260,6 +260,4 @@ function dbesc_array(&$arr) {
     	if(is_array($arr) && count($arr)) {
     		array_walk($arr,'dbesc_array_cb');
     	}
    -}}		
    -
    -
    +}}
    diff --git a/include/delivery.php b/include/delivery.php
    old mode 100755
    new mode 100644
    index 532dcd699..794b8f27a
    --- a/include/delivery.php
    +++ b/include/delivery.php
    @@ -321,6 +321,14 @@ function delivery_run($argv, $argc){
     						$x[0]['writable'] = 1;
     					}
     
    +					$ssl_policy = get_config('system','ssl_policy');
    +					fix_contact_ssl_policy($x[0],$ssl_policy);
    +
    +					// If we are setup as a soapbox we aren't accepting input from this person
    +
    +					if($x[0]['page-flags'] == PAGE_SOAPBOX)
    +						break;
    +
     					require_once('library/simplepie/simplepie.inc');
     					logger('mod-delivery: local delivery');
     					local_delivery($x[0],$atom);
    diff --git a/include/diaspora.php b/include/diaspora.php
    old mode 100755
    new mode 100644
    index 104ccadf2..afd86957b
    --- a/include/diaspora.php
    +++ b/include/diaspora.php
    @@ -9,6 +9,12 @@ require_once('include/queue_fn.php');
     
     function diaspora_dispatch_public($msg) {
     
    +	$enabled = intval(get_config('system','diaspora_enabled'));
    +	if(! $enabled) {
    +		logger('mod-diaspora: disabled');
    +		return;
    +	}
    +
     	$r = q("SELECT `user`.* FROM `user` WHERE `user`.`uid` IN ( SELECT `contact`.`uid` FROM `contact` WHERE `contact`.`network` = '%s' AND `contact`.`addr` = '%s' ) AND `account_expired` = 0 ",
     		dbesc(NETWORK_DIASPORA),
     		dbesc($msg['author'])
    @@ -29,6 +35,12 @@ function diaspora_dispatch($importer,$msg) {
     
     	$ret = 0;
     
    +	$enabled = intval(get_config('system','diaspora_enabled'));
    +	if(! $enabled) {
    +		logger('mod-diaspora: disabled');
    +		return;
    +	}
    +
     	// php doesn't like dashes in variable names
     
     	$msg['message'] = str_replace(
    @@ -1160,7 +1172,7 @@ function diaspora_comment($importer,$xml,$msg) {
     		proc_run('php','include/notifier.php','comment',$message_id);
     	}
     
    -	$myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ",
    +	$myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0 ",
     		dbesc($parent_item['uri']),
     		intval($importer['uid'])
     	);
    @@ -1920,6 +1932,7 @@ function diaspora_send_status($item,$owner,$contact,$public_batch = false) {
     
     	$images = array();
     
    +	$title = $item['title'];
     	$body = $item['body'];
     
     /*
    @@ -1944,9 +1957,12 @@ function diaspora_send_status($item,$owner,$contact,$public_batch = false) {
     		}
     	}	
     */
    -
     	$body = xmlify(html_entity_decode(bb2diaspora($body)));
     
    +	if(strlen($title))
    +		$body = xmlify('**' . html_entity_decode($title) . '**' . "\n") . $body;
    +
    +
     	if($item['attach']) {
     		$cnt = preg_match_all('/href=\"(.*?)\"(.*?)title=\"(.*?)\"/ism',$item['attach'],$matches,PREG_SET_ORDER);
     		if(cnt) {
    @@ -2267,6 +2283,11 @@ function diaspora_send_mail($item,$owner,$contact) {
     
     function diaspora_transmit($owner,$contact,$slap,$public_batch) {
     
    +	$enabled = intval(get_config('system','diaspora_enabled'));
    +	if(! $enabled) {
    +		return 200;
    +	}
    +
     	$a = get_app();
     	$logid = random_string(4);
     	$dest_url = (($public_batch) ? $contact['batch'] : $contact['notify']);
    diff --git a/include/directory.php b/include/directory.php
    old mode 100755
    new mode 100644
    diff --git a/include/email.php b/include/email.php
    old mode 100755
    new mode 100644
    diff --git a/include/enotify.php b/include/enotify.php
    old mode 100755
    new mode 100644
    diff --git a/include/event.php b/include/event.php
    old mode 100755
    new mode 100644
    diff --git a/include/expire.php b/include/expire.php
    old mode 100755
    new mode 100644
    diff --git a/include/fcontact.php b/include/fcontact.php
    old mode 100755
    new mode 100644
    diff --git a/include/group.php b/include/group.php
    old mode 100755
    new mode 100644
    index 4a35912e5..edb547de6
    --- a/include/group.php
    +++ b/include/group.php
    @@ -212,6 +212,7 @@ function group_side($every="contacts",$each="group",$edit = false, $group_id = 0
     		'$title'		=> t('Groups'),
     		'$edittext'     => t('Edit group'),
     		'$createtext' 	=> t('Create a new group'),
    +		'$ungrouped'    => (($every === 'contacts') ? t('Contacts not in any group') : ''),
     		'$groups'		=> $groups,
     		'$add'			=> t('add'),
     	));
    diff --git a/include/html2bbcode.php b/include/html2bbcode.php
    old mode 100755
    new mode 100644
    diff --git a/include/html2plain.php b/include/html2plain.php
    index fe0e3326e..21261327d 100644
    --- a/include/html2plain.php
    +++ b/include/html2plain.php
    @@ -83,12 +83,15 @@ function collecturls($message) {
     	$urls = array();
     	foreach ($result as $treffer) {
     		// A list of some links that should be ignored
    -		$list = array("/user/", "/tag/", "/profile/", "/search?search=", "mailto:", "/u/", "/node/",
    +		$list = array("/user/", "/tag/", "/group/", "/profile/", "/search?search=", "mailto:", "/u/", "/node/",
     				"//facebook.com/profile.php?id=", "//plus.google.com/");
     		foreach ($list as $listitem)
     			if (strpos($treffer[1], $listitem) !== false)
     				$ignore = true;
     
    +		if ((strpos($treffer[1], "//plus.google.com/") !== false) and (strpos($treffer[1], "/posts") !== false))
    +				$ignore = false;
    +
     		if (!$ignore)
     			$urls[$treffer[1]] = $treffer[1];
     	}
    @@ -154,7 +157,7 @@ function html2plain($html, $wraplength = 75, $compact = false)
     	//node2bbcode($doc, 'ol', array(), "\n[list=1]", "[/list]\n");
     	node2bbcode($doc, 'li', array(), "\n* ", "\n");
     
    -	node2bbcode($doc, 'hr', array(), str_repeat("-", 70), "");
    +	node2bbcode($doc, 'hr', array(), "\n".str_repeat("-", 70)."\n", "");
     
     	node2bbcode($doc, 'tr', array(), "\n", "");
     	node2bbcode($doc, 'td', array(), "\t", "");
    diff --git a/include/items.php b/include/items.php
    old mode 100755
    new mode 100644
    index ee6960534..07f62ece5
    --- a/include/items.php
    +++ b/include/items.php
    @@ -19,9 +19,15 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
     				$converse = true;
     			if($a->argv[$x] == 'starred')
     				$starred = true;
    +			if($a->argv[$x] === 'category' && $a->argc > ($x + 1) && strlen($a->argv[$x+1]))
    +				$category = $a->argv[$x+1];
     		}
    +
    +
     	}
     
    +	
    +
     	// default permissions - anonymous user
     
     	$sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' AND `deny_cid`  = '' AND `deny_gid`  = '' ";
    @@ -101,6 +107,10 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
     	if(! strlen($last_update))
     		$last_update = 'now -30 days';
     
    +	if(isset($category)) {
    +		$sql_extra .= file_tag_file_query('item',$category,'category');
    +	}
    +
     	if($public_feed) {
     		if(! $converse)
     			$sql_extra .= " AND `contact`.`self` = 1 ";
    @@ -578,20 +588,21 @@ function get_atom_elements($feed,$item) {
     
     	if($rawobj) {
     		$res['object'] = '' . "\n";
    -		if($rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
    -			$res['object-type'] = $rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'];
    -			$res['object'] .= '' . $rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '' . "\n";
    +		$child = $rawobj[0]['child'];
    +		if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
    +			$res['object-type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'];
    +			$res['object'] .= '' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '' . "\n";
     		}	
    -		if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
    -			$res['object'] .= '' . $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '' . "\n";
    -		if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
    -			$res['object'] .= '' . encode_rel_links($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '' . "\n";
    -		if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
    -			$res['object'] .= '' . $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '' . "\n";
    -		if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) {
    -			$body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data'];
    +		if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
    +			$res['object'] .= '' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '' . "\n";
    +		if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
    +			$res['object'] .= '' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '' . "\n";
    +		if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'title') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
    +			$res['object'] .= '' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '' . "\n";
    +		if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'content') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) {
    +			$body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data'];
     			if(! $body)
    -				$body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
    +				$body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
     			// preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events
     			$res['object'] .= '' . xmlify($body) . '' . "\n";
     			if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) {
    @@ -616,20 +627,20 @@ function get_atom_elements($feed,$item) {
     
     	if($rawobj) {
     		$res['target'] = '' . "\n";
    -		if($rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
    -			$res['target'] .= '' . $rawobj[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '' . "\n";
    +		$child = $rawobj[0]['child'];
    +		if($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) {
    +			$res['target'] .= '' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '' . "\n";
     		}	
    -		if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
    -			$res['target'] .= '' . $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '' . "\n";
    -
    -		if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
    -			$res['target'] .= '' . encode_rel_links($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '' . "\n";
    -		if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
    -			$res['target'] .= '' . $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '' . "\n";
    -		if($rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) {
    -			$body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data'];
    +		if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'])
    +			$res['target'] .= '' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '' . "\n";
    +		if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link'])
    +			$res['target'] .= '' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '' . "\n";
    +		if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'])
    +			$res['target'] .= '' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '' . "\n";
    +		if(x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) {
    +			$body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data'];
     			if(! $body)
    -				$body = $rawobj[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
    +				$body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data'];
     			// preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events
     			$res['target'] .= '' . xmlify($body) . '' . "\n";
     			if((strpos($body,'<') !== false) || (strpos($body,'>') !== false)) {
    @@ -1465,7 +1476,7 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0)
     					if(! $item['deleted'])
     						logger('consume_feed: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
     
    -					if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTVITY_OBJ_TAGTERM)) {
    +					if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
     						$xo = parse_xml_string($item['object'],false);
     						$xt = parse_xml_string($item['target'],false);
     						if($xt->type === ACTIVITY_OBJ_NOTE) {
    @@ -1856,6 +1867,8 @@ function local_delivery($importer,$data) {
     	$feed->enable_order_by_date(false);
     	$feed->init();
     
    +/*
    +	// Currently unsupported - needs a lot of work
     	$reloc = $feed->get_feed_tags( NAMESPACE_DFRN, 'relocate' );
     	if(isset($reloc[0]['child'][NAMESPACE_DFRN])) {
     		$base = $reloc[0]['child'][NAMESPACE_DFRN];
    @@ -1880,6 +1893,7 @@ function local_delivery($importer,$data) {
     		// schedule a scan?
     
     	}
    +*/
     
     	// handle friend suggestion notification
     
    @@ -2078,7 +2092,7 @@ function local_delivery($importer,$data) {
     
     					logger('local_delivery: deleting item ' . $item['id'] . ' uri=' . $item['uri'], LOGGER_DEBUG);
     
    -					if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTVITY_OBJ_TAGTERM)) {
    +					if(($item['verb'] === ACTIVITY_TAG) && ($item['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
     						$xo = parse_xml_string($item['object'],false);
     						$xt = parse_xml_string($item['target'],false);
     
    @@ -2216,6 +2230,34 @@ function local_delivery($importer,$data) {
     				$datarray = get_atom_elements($feed,$item);
     
     
    +				$r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
    +					dbesc($item_id),
    +					intval($importer['importer_uid'])
    +				);
    +
    +				// Update content if 'updated' changes
    +
    +				if(count($r)) {
    +					$iid = $r[0]['id'];
    +					if((x($datarray,'edited') !== false) && (datetime_convert('UTC','UTC',$datarray['edited']) !== $r[0]['edited'])) {  
    +						logger('received updated comment' , LOGGER_DEBUG);
    +						$r = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `tag` = '%s', `edited` = '%s' WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
    +							dbesc($datarray['title']),
    +							dbesc($datarray['body']),
    +							dbesc($datarray['tag']),
    +							dbesc(datetime_convert('UTC','UTC',$datarray['edited'])),
    +							dbesc($item_id),
    +							intval($importer['importer_uid'])
    +						);
    +
    +						proc_run('php',"include/notifier.php","comment-import",$iid);
    +
    +					}
    +
    +					continue;
    +				}
    +
    +
     				// TODO: make this next part work against both delivery threads of a community post
     
     //				if((! link_compare($datarray['author-link'],$importer['url'])) && (! $community)) {
    @@ -2435,9 +2477,9 @@ function local_delivery($importer,$data) {
     
     				// find out if our user is involved in this conversation and wants to be notified.
     			
    -				if($datarray['type'] != 'activity') {
    +				if(!x($datarray['type']) || $datarray['type'] != 'activity') {
     
    -					$myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ",
    +					$myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0",
     						dbesc($parent_uri),
     						intval($importer['importer_uid'])
     					);
    @@ -2971,12 +3013,23 @@ function item_expire($uid,$days) {
     		if($expire_items==0 && $item['type']!='note')
     			continue;
     
    +
     		$r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `id` = %d LIMIT 1",
     			dbesc(datetime_convert()),
     			dbesc(datetime_convert()),
     			intval($item['id'])
     		);
     
    +		$r = q("DELETE FROM item_id where iid in (select id from item where parent = %d) and uid = %d",
    +			intval($item['id']),
    +			intval($uid)
    +		);
    +
    +		$r = q("DELETE FROM sign where iid in (select id from item where parent = %d) and uid = %d",
    +			intval($item['id']),
    +			intval($uid)
    +		);
    +
     		// kill the kids
     
     		$r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ",
    @@ -2996,7 +3049,7 @@ function item_expire($uid,$days) {
     function drop_items($items) {
     	$uid = 0;
     
    -	if((! local_user()) && (! $remote_user()))
    +	if(! local_user() && ! remote_user())
     		return;
     
     	if(count($items)) {
    diff --git a/include/message.php b/include/message.php
    old mode 100755
    new mode 100644
    diff --git a/include/nav.php b/include/nav.php
    old mode 100755
    new mode 100644
    diff --git a/include/network.php b/include/network.php
    old mode 100755
    new mode 100644
    index 9e1ed2091..4bec4a172
    --- a/include/network.php
    +++ b/include/network.php
    @@ -172,7 +172,7 @@ function post_url($url,$params, $headers = null, &$redirects = 0, $timeout = 0)
             $url_parsed = @parse_url($newurl);
             if (isset($url_parsed)) {
                 $redirects++;
    -            return fetch_url($newurl,$binary,$redirects,$timeout);
    +            return fetch_url($newurl,false,$redirects,$timeout);
             }
         }
     	$a->set_curl_code($http_code);
    @@ -206,6 +206,7 @@ function xml_status($st, $message = '') {
     if(! function_exists('http_status_exit')) {
     function http_status_exit($val) {
     
    +    $err = '';
     	if($val >= 400)
     		$err = 'Error';
     	if($val >= 200 && $val < 300)
    @@ -452,7 +453,7 @@ function lrdd($uri, $debug = false) {
     			logger('lrdd: parse error: ' . $e);
     		}
     
    -		if($dom) {
    +		if(isset($dom) && $dom) {
     			$items = $dom->getElementsByTagName('link');
     			foreach($items as $item) {
     				$x = $item->getAttribute('rel');
    @@ -587,13 +588,14 @@ function fetch_xrd_links($url) {
     
     if(! function_exists('validate_url')) {
     function validate_url(&$url) {
    -	// no naked subdomains
    -	if(strpos($url,'.') === false)
    +	
    +	// no naked subdomains (allow localhost for tests)
    +	if(strpos($url,'.') === false && strpos($url,'/localhost/') === false)
     		return false;
     	if(substr($url,0,4) != 'http')
     		$url = 'http://' . $url;
     	$h = @parse_url($url);
    -
    +	
     	if(($h) && (dns_get_record($h['host'], DNS_A + DNS_CNAME + DNS_PTR))) {
     		return true;
     	}
    @@ -692,18 +694,23 @@ function allowed_email($email) {
     }}
     
     
    -if(! function_exists('gravatar_img')) {
    -function gravatar_img($email) {
    -	$size = 175;
    -	$opt = 'identicon';   // psuedo-random geometric pattern if not found
    -	$rating = 'pg';
    -	$hash = md5(trim(strtolower($email)));
    -	
    -	$url = 'http://www.gravatar.com/avatar/' . $hash . '.jpg' 
    -		. '?s=' . $size . '&d=' . $opt . '&r=' . $rating;
    +if(! function_exists('avatar_img')) {
    +function avatar_img($email) {
     
    -	logger('gravatar: ' . $email . ' ' . $url);
    -	return $url;
    +	$a = get_app();
    +
    +	$avatar['size'] = 175;
    +	$avatar['email'] = $email;
    +	$avatar['url'] = '';
    +	$avatar['success'] = false;
    +
    +	call_hooks('avatar_lookup', $avatar);
    +
    +	if(! $avatar['success'])
    +		$avatar['url'] = $a->get_baseurl() . '/images/person-175.jpg';
    +
    +	logger('Avatar: ' . $avatar['email'] . ' ' . $avatar['url'], LOGGER_DEBUG);
    +	return $avatar['url'];
     }}
     
     
    @@ -824,3 +831,48 @@ function scale_external_images($s,$include_link = true) {
     	}
     	return $s;
     }
    +
    +
    +function fix_contact_ssl_policy(&$contact,$new_policy) {
    +
    +	$ssl_changed = false;
    +	if((intval($new_policy) == SSL_POLICY_SELFSIGN || $new_policy === 'self') && strstr($contact['url'],'https:')) {
    +		$ssl_changed = true;
    +		$contact['url']     = 	str_replace('https:','http:',$contact['url']);
    +		$contact['request'] = 	str_replace('https:','http:',$contact['request']);
    +		$contact['notify']  = 	str_replace('https:','http:',$contact['notify']);
    +		$contact['poll']    = 	str_replace('https:','http:',$contact['poll']);
    +		$contact['confirm'] = 	str_replace('https:','http:',$contact['confirm']);
    +		$contact['poco']    = 	str_replace('https:','http:',$contact['poco']);
    +	}
    +
    +	if((intval($new_policy) == SSL_POLICY_FULL || $new_policy === 'full') && strstr($contact['url'],'http:')) {
    +		$ssl_changed = true;
    +		$contact['url']     = 	str_replace('http:','https:',$contact['url']);
    +		$contact['request'] = 	str_replace('http:','https:',$contact['request']);
    +		$contact['notify']  = 	str_replace('http:','https:',$contact['notify']);
    +		$contact['poll']    = 	str_replace('http:','https:',$contact['poll']);
    +		$contact['confirm'] = 	str_replace('http:','https:',$contact['confirm']);
    +		$contact['poco']    = 	str_replace('http:','https:',$contact['poco']);
    +	}
    +
    +	if($ssl_changed) {
    +		q("update contact set 
    +			url = '%s', 
    +			request = '%s',
    +			notify = '%s',
    +			poll = '%s',
    +			confirm = '%s',
    +			poco = '%s'
    +			where id = %d limit 1",
    +			dbesc($contact['url']),
    +			dbesc($contact['request']),
    +			dbesc($contact['notify']),
    +			dbesc($contact['poll']),
    +			dbesc($contact['confirm']),
    +			dbesc($contact['poco']),
    +			intval($contact['id'])
    +		);
    +	}
    +}
    +
    diff --git a/include/notifier.php b/include/notifier.php
    old mode 100755
    new mode 100644
    index d63ad7ae7..ca7c7b92e
    --- a/include/notifier.php
    +++ b/include/notifier.php
    @@ -537,6 +537,17 @@ function notifier_run($argv, $argc){
     								$x[0]['writable'] = 1;
     							}
     
    +							// if contact's ssl policy changed, which we just determined
    +							// is on our own server, update our contact links
    +							
    +							$ssl_policy = get_config('system','ssl_policy');
    +							fix_contact_ssl_policy($x[0],$ssl_policy);
    +
    +							// If we are setup as a soapbox we aren't accepting input from this person
    +
    +							if($x[0]['page-flags'] == PAGE_SOAPBOX)
    +								break;
    +
     							require_once('library/simplepie/simplepie.inc');
     							logger('mod-delivery: local delivery');
     							local_delivery($x[0],$atom);
    diff --git a/include/oauth.php b/include/oauth.php
    old mode 100755
    new mode 100644
    diff --git a/include/oembed.php b/include/oembed.php
    old mode 100755
    new mode 100644
    diff --git a/include/pgettext.php b/include/pgettext.php
    old mode 100755
    new mode 100644
    index 83e76ba9d..a079a4687
    --- a/include/pgettext.php
    +++ b/include/pgettext.php
    @@ -49,6 +49,7 @@ function get_language() {
     	if(isset($preferred))
     		return $preferred;
     
    +    $a = get_app();
     	return ((isset($a->config['system']['language'])) ? $a->config['system']['language'] : 'en');
     }}
     
    diff --git a/include/pidfile.php b/include/pidfile.php
    new file mode 100644
    index 000000000..47df8d1f4
    --- /dev/null
    +++ b/include/pidfile.php
    @@ -0,0 +1,32 @@
    +_file = "$dir/$name.pid";
    +
    +		if (file_exists($this->_file)) {
    +			$pid = trim(file_get_contents($this->_file));
    +			if (posix_kill($pid, 0)) {
    +				$this->_running = true;
    +			}
    +		}
    +
    +		if (! $this->_running) {
    +			$pid = getmypid();
    +			file_put_contents($this->_file, $pid);
    +		}
    +	}
    +
    +	public function __destruct() {
    +		if ((! $this->_running) && file_exists($this->_file)) {
    +			unlink($this->_file);
    +		}
    +	}
    +
    +	public function is_already_running() {
    +		return $this->_running;
    +	}
    +}
    +?>
    diff --git a/include/plugin.php b/include/plugin.php
    old mode 100755
    new mode 100644
    index e37ae8435..8196e8756
    --- a/include/plugin.php
    +++ b/include/plugin.php
    @@ -17,7 +17,12 @@ function uninstall_plugin($plugin){
     }}
     
     if (! function_exists('install_plugin')){
    -function install_plugin($plugin){
    +function install_plugin($plugin) {
    +
    +	// silently fail if plugin was removed
    +
    +	if(! file_exists('addon/' . $plugin . '/' . $plugin . '.php'))
    +		return false;
     	logger("Addons: installing " . $plugin);
     	$t = @filemtime('addon/' . $plugin . '/' . $plugin . '.php');
     	@include_once('addon/' . $plugin . '/' . $plugin . '.php');
    @@ -32,9 +37,11 @@ function install_plugin($plugin){
     			intval($t),
     			$plugin_admin
     		);
    +		return true;
     	}
     	else {
     		logger("Addons: FAILED installing " . $plugin);
    +		return false;
     	}
     
     }}
    diff --git a/include/poller.php b/include/poller.php
    old mode 100755
    new mode 100644
    index 90a97867c..499483d00
    --- a/include/poller.php
    +++ b/include/poller.php
    @@ -25,10 +25,20 @@ function poller_run($argv, $argc){
     	require_once('include/Contact.php');
     	require_once('include/email.php');
     	require_once('include/socgraph.php');
    +	require_once('include/pidfile.php');
     
     	load_config('config');
     	load_config('system');
     
    +	$lockpath = get_config('system','lockpath');
    +	if ($lockpath != '') {
    +		$pidfile = new pidfile($lockpath, 'poller.lck');
    +		if($pidfile->is_already_running()) {
    +			logger("poller: Already running");
    +			exit;
    +		}
    +	}
    +
     	$a->set_baseurl(get_config('system','url'));
     
     	load_hooks();
    diff --git a/include/profile_advanced.php b/include/profile_advanced.php
    old mode 100755
    new mode 100644
    index 004a58524..bb9850cd0
    --- a/include/profile_advanced.php
    +++ b/include/profile_advanced.php
    @@ -2,7 +2,7 @@
     
     function advanced_profile(&$a) {
     
    -	$o .= '';
    +	$o = '';
     
     	$o .= '

    ' . t('Profile') . '

    '; @@ -69,13 +69,12 @@ function advanced_profile(&$a) { if($txt = prepare_text($a->profile['work'])) $profile['work'] = array( t('Work/employment:'), $txt); if($txt = prepare_text($a->profile['education'])) $profile['education'] = array( t('School/education:'), $txt ); - } - - - return replace_macros($tpl, array( - '$title' => t('Profile'), - '$profile' => $profile, - )); + return replace_macros($tpl, array( + '$title' => t('Profile'), + '$profile' => $profile, + )); + } + return ''; } diff --git a/include/profile_selectors.php b/include/profile_selectors.php old mode 100755 new mode 100644 index 92579f64a..a2cef959d --- a/include/profile_selectors.php +++ b/include/profile_selectors.php @@ -30,7 +30,7 @@ function sexpref_selector($current="",$suffix="") { function marital_selector($current="",$suffix="") { $o = ''; - $select = array('', t('Single'), t('Lonely'), t('Available'), t('Unavailable'), t('Dating'), t('Unfaithful'), t('Sex Addict'), t('Friends'), t('Friends/Benefits'), t('Casual'), t('Engaged'), t('Married'), t('Partners'), t('Cohabiting'), t('Happy'), t('Not Looking'), t('Swinger'), t('Betrayed'), t('Separated'), t('Unstable'), t('Divorced'), t('Widowed'), t('Uncertain'), t('Complicated'), t('Don\'t care'), t('Ask me') ); + $select = array('', t('Single'), t('Lonely'), t('Available'), t('Unavailable'), t('Has crush'), t('Infatuated'), t('Dating'), t('Unfaithful'), t('Sex Addict'), t('Friends'), t('Friends/Benefits'), t('Casual'), t('Engaged'), t('Married'), t('Imaginarily married'), t('Partners'), t('Cohabiting'), t('Common law'), t('Happy'), t('Not looking'), t('Swinger'), t('Betrayed'), t('Separated'), t('Unstable'), t('Divorced'), t('Imaginarily divorced'), t('Widowed'), t('Uncertain'), t('It\'s complicated'), t('Don\'t care'), t('Ask me') ); $o .= "'; + $langs = glob('view/*/strings.php'); + + $lang_options = array(); + $selected = ""; + if(is_array($langs) && count($langs)) { $langs[] = ''; if(! in_array('view/en/strings.php',$langs)) @@ -1069,17 +1081,22 @@ function lang_selector() { asort($langs); foreach($langs as $l) { if($l == '') { - $default_selected = ((! x($_SESSION,'language')) ? ' selected="selected" ' : ''); - $o .= ''; + $lang_options[""] = t('default'); continue; } $ll = substr($l,5); $ll = substr($ll,0,strrpos($ll,'/')); - $selected = (($ll === $lang && (x($_SESSION, 'language'))) ? ' selected="selected" ' : ''); - $o .= ''; + $selected = (($ll === $lang && (x($_SESSION, 'language'))) ? $ll : $selected); + $lang_options[$ll]=$ll; } } - $o .= ''; + + $tpl = get_markup_template("lang_selector.tpl"); + $o = replace_macros($tpl, array( + '$title' => t('Select an alternate language'), + '$langs' => array($lang_options, $selected), + + )); return $o; }} @@ -1314,6 +1331,118 @@ function file_tag_file_query($table,$s,$type = 'file') { return " AND " . (($table) ? dbesc($table) . '.' : '') . "file regexp '" . dbesc($str) . "' "; } +// ex. given music,video return