Merge develop into 0308-Notifications-restructure

Conflicts:
	mod/notifications.php
This commit is contained in:
rabuzarus 2016-08-03 12:53:38 +02:00
commit ae905cbd1b
69 changed files with 16425 additions and 15260 deletions

13
.gitignore vendored
View file

@ -42,3 +42,16 @@ nbproject
#ignore local folder
/local/
#other stuff
.directory
.gitignore
/view/theme/Friendiboot
/view/theme/Viereinhalb
/view/theme/blog
/view/theme/boheme
/view/theme/clean
/view/theme/suckerberg
/addon/frio_hovercard

156
boot.php
View file

@ -38,7 +38,7 @@ define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_CODENAME', 'Asparagus');
define ( 'FRIENDICA_VERSION', '3.5-dev' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
define ( 'DB_UPDATE_VERSION', 1199 );
define ( 'DB_UPDATE_VERSION', 1200 );
/**
* @brief Constant with a HTML line break.
@ -386,6 +386,17 @@ define ( 'GRAVITY_LIKE', 3);
define ( 'GRAVITY_COMMENT', 6);
/* @}*/
/**
* @name Priority
*
* Process priority for the worker
* @{
*/
define('PRIORITY_HIGH', 1);
define('PRIORITY_MEDIUM', 2);
define('PRIORITY_LOW', 3);
/* @}*/
// Normally this constant is defined - but not if "pcntl" isn't installed
if (!defined("SIGTERM"))
@ -1241,13 +1252,34 @@ class App {
logger("killed stale process");
// Calling a new instance
if ($task != "")
proc_run('php', $task);
proc_run(PRIORITY_MEDIUM, $task);
}
return true;
}
}
return false;
}
function proc_run($args) {
// Add the php path if it is a php call
if (count($args) && $args[0] === 'php')
$args[0] = ((x($this->config,'php_path')) && (strlen($this->config['php_path'])) ? $this->config['php_path'] : 'php');
// add baseurl to args. cli scripts can't construct it
$args[] = $this->get_baseurl();
for($x = 0; $x < count($args); $x ++)
$args[$x] = escapeshellarg($args[$x]);
$cmdline = implode($args," ");
if(get_config('system','proc_windows'))
proc_close(proc_open('cmd /c start /b ' . $cmdline,array(),$foo,dirname(__FILE__)));
else
proc_close(proc_open($cmdline." &",array(),$foo,dirname(__FILE__)));
}
}
/**
@ -1363,7 +1395,7 @@ function check_db() {
$build = DB_UPDATE_VERSION;
}
if($build != DB_UPDATE_VERSION)
proc_run('php', 'include/dbupdate.php');
proc_run(PRIORITY_HIGH, 'include/dbupdate.php');
}
@ -1736,10 +1768,11 @@ function get_max_import_size() {
* @brief Wrap calls to proc_close(proc_open()) and call hook
* so plugins can take part in process :)
*
* @param string $cmd program to run
* @param (string|integer) $cmd program to run or priority
*
* next args are passed as $cmd command line
* e.g.: proc_run("ls","-la","/tmp");
* or: proc_run(PRIORITY_HIGH, "include/notifier.php", "drop", $drop_id);
*
* @note $cmd and string args are surrounded with ""
*
@ -1753,7 +1786,7 @@ function proc_run($cmd){
$args = func_get_args();
$newargs = array();
if(! count($args))
if (!count($args))
return;
// expand any arrays
@ -1763,8 +1796,7 @@ function proc_run($cmd){
foreach($arg as $n) {
$newargs[] = $n;
}
}
else
} else
$newargs[] = $arg;
}
@ -1773,77 +1805,55 @@ function proc_run($cmd){
$arr = array('args' => $args, 'run_cmd' => true);
call_hooks("proc_run", $arr);
if(! $arr['run_cmd'])
if (!$arr['run_cmd'] OR !count($args))
return;
if(count($args) && $args[0] === 'php') {
if (get_config("system", "worker")) {
$argv = $args;
array_shift($argv);
$parameters = json_encode($argv);
$found = q("SELECT `id` FROM `workerqueue` WHERE `parameter` = '%s'",
dbesc($parameters));
$funcname = str_replace(".php", "", basename($argv[0]))."_run";
// Define the processes that have priority over any other process
/// @todo Better check for priority processes
$high_priority = array("delivery_run", "notifier_run", "pubsubpublish_run");
$low_priority = array("queue_run", "gprobe_run", "discover_poco_run");
if (in_array($funcname, $high_priority))
$priority = 1;
elseif (in_array($funcname, $low_priority))
$priority = 3;
else
$priority = 2;
if (!$found)
q("INSERT INTO `workerqueue` (`function`, `parameter`, `created`, `priority`)
VALUES ('%s', '%s', '%s', %d)",
dbesc($funcname),
dbesc($parameters),
dbesc(datetime_convert()),
intval($priority));
// Should we quit and wait for the poller to be called as a cronjob?
if (get_config("system", "worker_dont_fork"))
return;
// Checking number of workers
$workers = q("SELECT COUNT(*) AS `workers` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
// Get number of allowed number of worker threads
$queues = intval(get_config("system", "worker_queues"));
if ($queues == 0)
$queues = 4;
// If there are already enough workers running, don't fork another one
if ($workers[0]["workers"] >= $queues)
return;
// Now call the poller to execute the jobs that we just added to the queue
$args = array("php", "include/poller.php", "no_cron");
}
$args[0] = ((x($a->config,'php_path')) && (strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php');
if (!get_config("system", "worker") OR
(($args[0] != 'php') AND !is_int($args[0]))) {
$a->proc_run($args);
return;
}
// add baseurl to args. cli scripts can't construct it
$args[] = $a->get_baseurl();
for($x = 0; $x < count($args); $x ++)
$args[$x] = escapeshellarg($args[$x]);
$cmdline = implode($args," ");
if(get_config('system','proc_windows'))
proc_close(proc_open('cmd /c start /b ' . $cmdline,array(),$foo,dirname(__FILE__)));
if (is_int($args[0]))
$priority = $args[0];
else
proc_close(proc_open($cmdline." &",array(),$foo,dirname(__FILE__)));
$priority = PRIORITY_MEDIUM;
$argv = $args;
array_shift($argv);
$parameters = json_encode($argv);
$found = q("SELECT `id` FROM `workerqueue` WHERE `parameter` = '%s'",
dbesc($parameters));
if (!$found)
q("INSERT INTO `workerqueue` (`parameter`, `created`, `priority`)
VALUES ('%s', '%s', %d)",
dbesc($parameters),
dbesc(datetime_convert()),
intval($priority));
// Should we quit and wait for the poller to be called as a cronjob?
if (get_config("system", "worker_dont_fork"))
return;
// Checking number of workers
$workers = q("SELECT COUNT(*) AS `workers` FROM `workerqueue` WHERE `executed` != '0000-00-00 00:00:00'");
// Get number of allowed number of worker threads
$queues = intval(get_config("system", "worker_queues"));
if ($queues == 0)
$queues = 4;
// If there are already enough workers running, don't fork another one
if ($workers[0]["workers"] >= $queues)
return;
// Now call the poller to execute the jobs that we just added to the queue
$args = array("php", "include/poller.php", "no_cron");
$a->proc_run($args);
}
function current_theme(){

View file

@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 3.5-dev (Asparagus)
-- DB_UPDATE_VERSION 1199
-- DB_UPDATE_VERSION 1200
-- ------------------------------------------
@ -522,6 +522,7 @@ CREATE TABLE IF NOT EXISTS `item` (
INDEX `uid_title` (`uid`,`title`),
INDEX `uid_thrparent` (`uid`,`thr-parent`),
INDEX `uid_parenturi` (`uid`,`parent-uri`),
INDEX `uid_contactid_id` (`uid`,`contact-id`,`id`),
INDEX `uid_contactid_created` (`uid`,`contact-id`,`created`),
INDEX `gcontactid_uid_created` (`gcontact-id`,`uid`,`created`),
INDEX `authorid_created` (`author-id`,`created`),
@ -532,7 +533,7 @@ CREATE TABLE IF NOT EXISTS `item` (
INDEX `uid_wall_created` (`uid`,`wall`,`created`),
INDEX `resource-id` (`resource-id`),
INDEX `uid_type` (`uid`,`type`),
INDEX `uid_starred` (`uid`,`starred`),
INDEX `uid_starred_id` (`uid`,`starred`,`id`),
INDEX `contactid_allowcid_allowpid_denycid_denygid` (`contact-id`,`allow_cid`(10),`allow_gid`(10),`deny_cid`(10),`deny_gid`(10)),
INDEX `uid_wall_parent_created` (`uid`,`wall`,`parent`,`created`),
INDEX `uid_type_changed` (`uid`,`type`,`changed`),

View file

@ -45,10 +45,10 @@ function user_remove($uid) {
// don't delete yet, will be done later when contacts have deleted my stuff
// q("DELETE FROM `user` WHERE `uid` = %d", intval($uid));
q("UPDATE `user` SET `account_removed` = 1, `account_expires_on` = UTC_TIMESTAMP() WHERE `uid` = %d", intval($uid));
proc_run('php', "include/notifier.php", "removeme", $uid);
proc_run(PRIORITY_HIGH, "include/notifier.php", "removeme", $uid);
// Send an update to the directory
proc_run('php', "include/directory.php", $r[0]['url']);
proc_run(PRIORITY_LOW, "include/directory.php", $r[0]['url']);
if($uid == local_user()) {
unset($_SESSION['authenticated']);
@ -275,7 +275,7 @@ function get_contact_details_by_url($url, $uid = -1, $default = array()) {
if ((($profile["addr"] == "") OR ($profile["name"] == "")) AND ($profile["gid"] != 0) AND
in_array($profile["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS)))
proc_run('php',"include/update_gcontact.php", $profile["gid"]);
proc_run(PRIORITY_LOW, "include/update_gcontact.php", $profile["gid"]);
// Show contact details of Diaspora contacts only if connected
if (($profile["cid"] == 0) AND ($profile["network"] == NETWORK_DIASPORA)) {
@ -631,11 +631,11 @@ function posts_from_contact($a, $contact_id) {
$r = q("SELECT `item`.`uri`, `item`.*, `item`.`id` AS `item_id`,
`author-name` AS `name`, `owner-avatar` AS `photo`,
`owner-link` AS `url`, `owner-avatar` AS `thumb`
FROM `item` FORCE INDEX (`uid_contactid_created`)
FROM `item` FORCE INDEX (`uid_contactid_id`)
WHERE `item`.`uid` = %d AND `contact-id` = %d
AND `author-link` IN ('%s', '%s')
AND NOT `deleted` AND NOT `moderated` AND `visible`
ORDER BY `item`.`created` DESC LIMIT %d, %d",
ORDER BY `item`.`id` DESC LIMIT %d, %d",
intval(local_user()),
intval($contact_id),
dbesc(str_replace("https://", "http://", $contact["url"])),

View file

@ -481,11 +481,11 @@ function acl_lookup(&$a, $out_type = 'json') {
if ($type=='' || $type=='g'){
$r = q("SELECT `group`.`id`, `group`.`name`, GROUP_CONCAT(DISTINCT `group_member`.`contact-id` SEPARATOR ',') AS uids
FROM `group`,`group_member`
WHERE `group`.`deleted` = 0 AND `group`.`uid` = %d
AND `group_member`.`gid`=`group`.`id`
FROM `group`
INNER JOIN `group_member` ON `group_member`.`gid`=`group`.`id` AND `group_member`.`uid` = `group`.`uid`
WHERE NOT `group`.`deleted` AND `group`.`uid` = %d
$sql_extra
GROUP BY `group`.`id`
GROUP BY `group`.`name`
ORDER BY `group`.`name`
LIMIT %d,%d",
intval(local_user()),

File diff suppressed because it is too large Load diff

View file

@ -70,53 +70,48 @@ function cron_run(&$argv, &$argc){
// run queue delivery process in the background
proc_run('php',"include/queue.php");
proc_run(PRIORITY_LOW,"include/queue.php");
// run the process to discover global contacts in the background
proc_run('php',"include/discover_poco.php");
proc_run(PRIORITY_LOW,"include/discover_poco.php");
// run the process to update locally stored global contacts in the background
proc_run('php',"include/discover_poco.php", "checkcontact");
proc_run(PRIORITY_LOW,"include/discover_poco.php", "checkcontact");
// expire any expired accounts
// Expire and remove user entries
cron_expire_and_remove_users();
q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
AND `account_expires_on` != '0000-00-00 00:00:00'
AND `account_expires_on` < UTC_TIMESTAMP() ");
// If the worker is active, split the jobs in several sub processes
if (get_config("system", "worker")) {
// Check OStatus conversations
proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "ostatus_mentions");
// delete user and contact records for recently removed accounts
// Check every conversation
proc_run(PRIORITY_MEDIUM, "include/cronjobs.php", "ostatus_conversations");
$r = q("SELECT * FROM `user` WHERE `account_removed` = 1 AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
if ($r) {
foreach($r as $user) {
q("DELETE FROM `contact` WHERE `uid` = %d", intval($user['uid']));
q("DELETE FROM `user` WHERE `uid` = %d", intval($user['uid']));
}
// Call possible post update functions
proc_run(PRIORITY_LOW, "include/cronjobs.php", "post_update");
// update nodeinfo data
proc_run(PRIORITY_LOW, "include/cronjobs.php", "nodeinfo");
} else {
// Check OStatus conversations
// Check only conversations with mentions (for a longer time)
ostatus::check_conversations(true);
// Check every conversation
ostatus::check_conversations(false);
// Call possible post update functions
// see include/post_update.php for more details
post_update();
// update nodeinfo data
nodeinfo_cron();
}
$abandon_days = intval(get_config('system','account_abandon_days'));
if($abandon_days < 1)
$abandon_days = 0;
// Check OStatus conversations
// Check only conversations with mentions (for a longer time)
ostatus::check_conversations(true);
// Check every conversation
ostatus::check_conversations(false);
// Call possible post update functions
// see include/post_update.php for more details
post_update();
// update nodeinfo data
nodeinfo_cron();
/// @TODO Regenerate usage statistics
// q("ANALYZE TABLE `item`");
// once daily run birthday_updates and then expire in background
$d1 = get_config('system','last_expire_day');
@ -126,11 +121,11 @@ function cron_run(&$argv, &$argc){
update_contact_birthdays();
proc_run('php',"include/discover_poco.php", "suggestions");
proc_run(PRIORITY_LOW,"include/discover_poco.php", "suggestions");
set_config('system','last_expire_day',$d2);
proc_run('php','include/expire.php');
proc_run(PRIORITY_LOW,'include/expire.php');
}
// Clear cache entries
@ -142,28 +137,64 @@ function cron_run(&$argv, &$argc){
// Repair entries in the database
cron_repair_database();
// Poll contacts
cron_poll_contacts($argc, $argv);
logger('cron: end');
set_config('system','last_cron', time());
return;
}
/**
* @brief Expire and remove user entries
*/
function cron_expire_and_remove_users() {
// expire any expired accounts
q("UPDATE user SET `account_expired` = 1 where `account_expired` = 0
AND `account_expires_on` != '0000-00-00 00:00:00'
AND `account_expires_on` < UTC_TIMESTAMP() ");
// delete user and contact records for recently removed accounts
$r = q("SELECT * FROM `user` WHERE `account_removed` AND `account_expires_on` < UTC_TIMESTAMP() - INTERVAL 3 DAY");
if ($r) {
foreach($r as $user) {
q("DELETE FROM `contact` WHERE `uid` = %d", intval($user['uid']));
q("DELETE FROM `user` WHERE `uid` = %d", intval($user['uid']));
}
}
}
/**
* @brief Poll contacts for unreceived messages
*
* @param Integer $argc Number of command line arguments
* @param Array $argv Array of command line arguments
*/
function cron_poll_contacts($argc, $argv) {
$manual_id = 0;
$generation = 0;
$force = false;
$restart = false;
if(($argc > 1) && ($argv[1] == 'force'))
if (($argc > 1) && ($argv[1] == 'force'))
$force = true;
if(($argc > 1) && ($argv[1] == 'restart')) {
if (($argc > 1) && ($argv[1] == 'restart')) {
$restart = true;
$generation = intval($argv[2]);
if(! $generation)
if (!$generation)
killme();
}
if(($argc > 1) && intval($argv[1])) {
if (($argc > 1) && intval($argv[1])) {
$manual_id = intval($argv[1]);
$force = true;
}
$interval = intval(get_config('system','poll_interval'));
if(! $interval)
if (!$interval)
$interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
// If we are using the worker we don't need a delivery interval
@ -180,6 +211,10 @@ function cron_run(&$argv, &$argc){
// and which have a polling address and ignore Diaspora since
// we are unable to match those posts with a Diaspora GUID and prevent duplicates.
$abandon_days = intval(get_config('system','account_abandon_days'));
if($abandon_days < 1)
$abandon_days = 0;
$abandon_sql = (($abandon_days)
? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days))
: ''
@ -200,11 +235,11 @@ function cron_run(&$argv, &$argc){
dbesc(NETWORK_MAIL2)
);
if(! count($contacts)) {
if (!count($contacts)) {
return;
}
foreach($contacts as $c) {
foreach ($contacts as $c) {
$res = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
intval($c['id'])
@ -266,24 +301,18 @@ function cron_run(&$argv, &$argc){
$update = true;
break;
}
if(!$update)
if (!$update)
continue;
}
logger("Polling ".$contact["network"]." ".$contact["id"]." ".$contact["nick"]." ".$contact["name"]);
proc_run('php','include/onepoll.php',$contact['id']);
proc_run(PRIORITY_MEDIUM,'include/onepoll.php',$contact['id']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
}
logger('cron: end');
set_config('system','last_cron', time());
return;
}
/**

View file

@ -31,6 +31,17 @@ function cronhooks_run(&$argv, &$argc){
return;
}
load_hooks();
if (($argc == 2) AND is_array($a->hooks) AND array_key_exists("cron", $a->hooks)) {
foreach ($a->hooks["cron"] as $hook)
if ($hook[1] == $argv[1]) {
logger("Calling cron hook '".$hook[1]."'", LOGGER_DEBUG);
call_single_hook($a, $name, $hook, $data);
}
return;
}
$last = get_config('system','last_cronhook');
$poll_interval = intval(get_config('system','cronhook_interval'));
@ -47,13 +58,17 @@ function cronhooks_run(&$argv, &$argc){
$a->set_baseurl(get_config('system','url'));
load_hooks();
logger('cronhooks: start');
$d = datetime_convert();
call_hooks('cron', $d);
if (get_config("system", "worker") AND is_array($a->hooks) AND array_key_exists("cron", $a->hooks)) {
foreach ($a->hooks["cron"] as $hook) {
logger("Calling cronhooks for '".$hook[1]."'", LOGGER_DEBUG);
proc_run(PRIORITY_MEDIUM, "include/cronhooks.php", $hook[1]);
}
} else
call_hooks('cron', $d);
logger('cronhooks: end');

78
include/cronjobs.php Normal file
View file

@ -0,0 +1,78 @@
<?php
if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
$directory = dirname($_SERVER["argv"][0]);
if (substr($directory, 0, 1) != "/")
$directory = $_SERVER["PWD"]."/".$directory;
$directory = realpath($directory."/..");
chdir($directory);
}
require_once("boot.php");
function cronjobs_run(&$argv, &$argc){
global $a, $db;
if(is_null($a)) {
$a = new App;
}
if(is_null($db)) {
@include(".htconfig.php");
require_once("include/dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
};
require_once('include/session.php');
require_once('include/datetime.php');
require_once('include/ostatus.php');
require_once('include/post_update.php');
require_once('mod/nodeinfo.php');
load_config('config');
load_config('system');
$a->set_baseurl(get_config('system','url'));
// No parameter set? So return
if ($argc <= 1)
return;
// Check OStatus conversations
// Check only conversations with mentions (for a longer time)
if ($argv[1] == 'ostatus_mentions') {
ostatus::check_conversations(true);
return;
}
// Check every conversation
if ($argv[1] == 'ostatus_conversations') {
ostatus::check_conversations(false);
return;
}
// Call possible post update functions
// see include/post_update.php for more details
if ($argv[1] == 'post_update') {
post_update();
return;
}
// update nodeinfo data
if ($argv[1] == 'nodeinfo') {
nodeinfo_cron();
return;
}
return;
}
if (array_search(__file__,get_included_files())===0){
cronjobs_run($_SERVER["argv"],$_SERVER["argc"]);
killme();
}

View file

@ -858,6 +858,7 @@ function db_definition() {
"uid_title" => array("uid","title"),
"uid_thrparent" => array("uid","thr-parent"),
"uid_parenturi" => array("uid","parent-uri"),
"uid_contactid_id" => array("uid","contact-id","id"),
"uid_contactid_created" => array("uid","contact-id","created"),
"gcontactid_uid_created" => array("gcontact-id","uid","created"),
"authorid_created" => array("author-id","created"),
@ -868,7 +869,7 @@ function db_definition() {
"uid_wall_created" => array("uid","wall","created"),
"resource-id" => array("resource-id"),
"uid_type" => array("uid","type"),
"uid_starred" => array("uid","starred"),
"uid_starred_id" => array("uid","starred", "id"),
"contactid_allowcid_allowpid_denycid_denygid" => array("contact-id","allow_cid(10)","allow_gid(10)","deny_cid(10)","deny_gid(10)"),
"uid_wall_parent_created" => array("uid","wall","parent","created"),
"uid_type_changed" => array("uid","type","changed"),

View file

@ -270,7 +270,7 @@ function new_contact($uid,$url,$interactive = false) {
// pull feed and consume it, which should subscribe to the hub.
proc_run('php',"include/onepoll.php","$contact_id", "force");
proc_run(PRIORITY_MEDIUM, "include/onepoll.php", $contact_id, "force");
// create a follow slap

View file

@ -818,7 +818,7 @@ function zrl_init(&$a) {
}
}
proc_run('php','include/gprobe.php',bin2hex($tmp_str));
proc_run(PRIORITY_LOW, 'include/gprobe.php',bin2hex($tmp_str));
$arr = array('zrl' => $tmp_str, 'url' => $a->cmd);
call_hooks('zrl_init',$arr);
}

View file

@ -917,7 +917,7 @@ function item_store($arr,$force_parent = false, $notify = false, $dontcache = fa
check_item_notification($current_post, $uid);
if ($notify)
proc_run('php', "include/notifier.php", $notify_type, $current_post);
proc_run(PRIORITY_HIGH, "include/notifier.php", $notify_type, $current_post);
return $current_post;
}
@ -1156,7 +1156,7 @@ function tag_deliver($uid,$item_id) {
);
update_thread($item_id);
proc_run('php','include/notifier.php','tgroup',$item_id);
proc_run(PRIORITY_HIGH,'include/notifier.php', 'tgroup', $item_id);
}
@ -1763,7 +1763,7 @@ function item_expire($uid, $days, $network = "", $force = false) {
drop_item($item['id'],false);
}
proc_run('php',"include/notifier.php","expire","$uid");
proc_run(PRIORITY_HIGH,"include/notifier.php", "expire", $uid);
}
@ -1785,7 +1785,7 @@ function drop_items($items) {
// multiple threads may have been deleted, send an expire notification
if($uid)
proc_run('php',"include/notifier.php","expire","$uid");
proc_run(PRIORITY_HIGH,"include/notifier.php", "expire", $uid);
}
@ -1998,7 +1998,7 @@ function drop_item($id,$interactive = true) {
// send the notification upstream/downstream as the case may be
proc_run('php',"include/notifier.php","drop","$drop_id");
proc_run(PRIORITY_HIGH,"include/notifier.php", "drop", $drop_id);
if(! $interactive)
return $owner;

View file

@ -153,7 +153,7 @@ function do_like($item_id, $verb) {
);
$like_item_id = $like_item['id'];
proc_run('php',"include/notifier.php","like","$like_item_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "like", $like_item_id);
return true;
}
@ -245,7 +245,7 @@ EOT;
call_hooks('post_local_end', $arr);
proc_run('php',"include/notifier.php","like","$post_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "like", $post_id);
return true;
}

View file

@ -150,7 +150,7 @@ function send_message($recipient=0, $body='', $subject='', $replyto=''){
}
if($post_id) {
proc_run('php',"include/notifier.php","mail","$post_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "mail", $post_id);
return intval($post_id);
} else {
return -3;

View file

@ -16,7 +16,7 @@ require_once('include/salmon.php');
/*
* The notifier is typically called with:
*
* proc_run('php', "include/notifier.php", COMMAND, ITEM_ID);
* proc_run(PRIORITY_HIGH, "include/notifier.php", COMMAND, ITEM_ID);
*
* where COMMAND is one of the following:
*
@ -355,7 +355,7 @@ function notifier_run(&$argv, &$argc){
// a delivery fork. private groups (forum_mode == 2) do not uplink
if((intval($parent['forum_mode']) == 1) && (! $top_level) && ($cmd !== 'uplink')) {
proc_run('php','include/notifier.php','uplink',$item_id);
proc_run(PRIORITY_HIGH,'include/notifier.php','uplink',$item_id);
}
$conversants = array();
@ -538,7 +538,7 @@ function notifier_run(&$argv, &$argc){
$this_batch[] = $contact['id'];
if(count($this_batch) >= $deliveries_per_process) {
proc_run('php','include/delivery.php',$cmd,$item_id,$this_batch);
proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$this_batch);
$this_batch = array();
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
@ -548,7 +548,7 @@ function notifier_run(&$argv, &$argc){
// be sure to pick up any stragglers
if(count($this_batch))
proc_run('php','include/delivery.php',$cmd,$item_id,$this_batch);
proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$this_batch);
}
// send salmon slaps to mentioned remote tags (@foo@example.com) in OStatus posts
@ -619,7 +619,7 @@ function notifier_run(&$argv, &$argc){
if((! $mail) && (! $fsuggest) && (! $followup)) {
logger('notifier: delivery agent: '.$rr['name'].' '.$rr['id'].' '.$rr['network'].' '.$target_item["guid"]);
proc_run('php','include/delivery.php',$cmd,$item_id,$rr['id']);
proc_run(PRIORITY_HIGH,'include/delivery.php',$cmd,$item_id,$rr['id']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
@ -659,7 +659,7 @@ function notifier_run(&$argv, &$argc){
}
// Handling the pubsubhubbub requests
proc_run('php','include/pubsubpublish.php');
proc_run(PRIORITY_HIGH,'include/pubsubpublish.php');
}
logger('notifier: calling hooks', LOGGER_DEBUG);

View file

@ -1971,7 +1971,7 @@ class ostatus {
OR (`item`.`network` = '%s' AND ((`thread`.`network` IN ('%s', '%s')) OR (`thritem`.`network` IN ('%s', '%s')))) AND `thread`.`mention`)
AND ((`item`.`owner-link` IN ('%s', '%s') AND (`item`.`parent` = `item`.`id`))
OR (`item`.`author-link` IN ('%s', '%s')))
ORDER BY `item`.`received` DESC
ORDER BY `item`.`id` DESC
LIMIT 0, 300",
intval($owner["uid"]), dbesc($check_date), dbesc(NETWORK_DFRN),
//dbesc(NETWORK_OSTATUS), dbesc(NETWORK_OSTATUS),

View file

@ -205,37 +205,41 @@ function load_hooks() {
* @param string $name of the hook to call
* @param string|array &$data to transmit to the callback handler
*/
if(! function_exists('call_hooks')) {
function call_hooks($name, &$data = null) {
$stamp1 = microtime(true);
$a = get_app();
#logger($name, LOGGER_ALL);
if (is_array($a->hooks) && array_key_exists($name, $a->hooks))
foreach ($a->hooks[$name] as $hook)
call_single_hook($a, $name, $hook, $data);
}
if((is_array($a->hooks)) && (array_key_exists($name,$a->hooks))) {
foreach($a->hooks[$name] as $hook) {
// Don't run a theme's hook if the user isn't using the theme
if(strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/'.current_theme()) === false)
continue;
/**
* @brief Calls a single hook.
*
* @param string $name of the hook to call
* @param array $hook Hook data
* @param string|array &$data to transmit to the callback handler
*/
function call_single_hook($a, $name, $hook, &$data = null) {
// Don't run a theme's hook if the user isn't using the theme
if (strpos($hook[0], 'view/theme/') !== false && strpos($hook[0], 'view/theme/'.current_theme()) === false)
return;
@include_once($hook[0]);
if(function_exists($hook[1])) {
$func = $hook[1];
//logger($name." => ".$hook[0].":".$func."()", LOGGER_DEBUG);
$func($a,$data);
}
else {
// remove orphan hooks
q("DELETE FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s'",
dbesc($name),
dbesc($hook[0]),
dbesc($hook[1])
);
}
}
@include_once($hook[0]);
if (function_exists($hook[1])) {
$func = $hook[1];
$func($a, $data);
} else {
// remove orphan hooks
q("DELETE FROM `hook` WHERE `hook` = '%s' AND `file` = '%s' AND `function` = '%s'",
dbesc($name),
dbesc($hook[0]),
dbesc($hook[1])
);
}
}}
}
//check if an app_menu hook exist for plugin $name.
//Return true if the plugin is an app

View file

@ -46,10 +46,10 @@ function poller_run(&$argv, &$argc){
if(($argc <= 1) OR ($argv[1] != "no_cron")) {
// Run the cron job that calls all other jobs
proc_run("php","include/cron.php");
proc_run(PRIORITY_MEDIUM, "include/cron.php");
// Run the cronhooks job separately from cron for being able to use a different timing
proc_run("php","include/cronhooks.php");
proc_run(PRIORITY_MEDIUM, "include/cronhooks.php");
// Cleaning dead processes
poller_kill_stale_workers();
@ -270,11 +270,34 @@ function poller_too_much_workers() {
$slope = $maxworkers / pow($maxsysload, $exponent);
$queues = ceil($slope * pow(max(0, $maxsysload - $load), $exponent));
if (Config::get("system", "worker_fastlane", false) AND ($queues > 0) AND ($active >= $queues)) {
$s = q("SELECT COUNT(*) AS `total` FROM `workerqueue` WHERE `priority` = %d AND `executed` = '0000-00-00 00:00:00'",
intval(PRIORITY_HIGH));
$high_waiting = $s[0]["total"];
$s = q("SELECT COUNT(*) AS `total` FROM `workerqueue` WHERE `priority` = %d AND `executed` != '0000-00-00 00:00:00'",
intval(PRIORITY_HIGH));
$high_running = $s[0]["total"];
/// @todo define maximum number of fastlanes
if (($high_waiting > 0) AND ($high_running == 0)) {
logger("There are ".$high_waiting." high priority jobs waiting but none is executed. Open a fastlane.", LOGGER_DEBUG);
$queues = $active + 1;
}
}
$s = q("SELECT COUNT(*) AS `total` FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00'");
$entries = $s[0]["total"];
logger("Current load: ".$load." - maximum: ".$maxsysload." - current queues: ".$active."/".$entries." - maximum: ".$queues."/".$maxqueues, LOGGER_DEBUG);
// Are there fewer workers running as possible? Then fork a new one.
if (!get_config("system", "worker_dont_fork") AND ($queues > ($active + 1)) AND ($entries > 1)) {
logger("Active workers: ".$active."/".$queues." Fork a new worker.", LOGGER_DEBUG);
$args = array("php", "include/poller.php", "no_cron");
$a = get_app();
$a->proc_run($args);
}
}
return($active >= $queues);

View file

@ -48,7 +48,7 @@ function queue_run(&$argv, &$argc){
logger('queue: start');
// Handling the pubsubhubbub requests
proc_run('php','include/pubsubpublish.php');
proc_run(PRIORITY_HIGH,'include/pubsubpublish.php');
$interval = ((get_config('system','delivery_interval') === false) ? 2 : intval(get_config('system','delivery_interval')));
@ -60,7 +60,7 @@ function queue_run(&$argv, &$argc){
if($r) {
foreach($r as $rr) {
logger('queue: deliverq');
proc_run('php','include/delivery.php',$rr['cmd'],$rr['item'],$rr['contact']);
proc_run(PRIORITY_HIGH,'include/delivery.php',$rr['cmd'],$rr['item'],$rr['contact']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}

View file

@ -1507,7 +1507,7 @@ function get_gcontact_id($contact) {
if ($doprobing) {
logger("Last Contact: ". $last_contact_str." - Last Failure: ".$last_failure_str." - Checking: ".$contact["url"], LOGGER_DEBUG);
proc_run('php', 'include/gprobe.php', bin2hex($contact["url"]));
proc_run(PRIORITY_LOW, 'include/gprobe.php', bin2hex($contact["url"]));
}
if ((count($r) > 1) AND ($gcontact_id > 0) AND ($contact["url"] != ""))

View file

@ -872,7 +872,8 @@ function contact_block() {
$micropro = Null;
} else {
$r = q("SELECT `id`, `uid`, `addr`, `url`, `name`, `thumb`, `network` FROM `contact`
// Splitting the query in two parts makes it much faster
$r = q("SELECT `id` FROM `contact`
WHERE `uid` = %d AND NOT `self` AND NOT `blocked` AND NOT `pending`
AND NOT `hidden` AND NOT `archive`
AND `network` IN ('%s', '%s', '%s') ORDER BY RAND() LIMIT %d",
@ -882,11 +883,19 @@ function contact_block() {
dbesc(NETWORK_DIASPORA),
intval($shown)
);
if(count($r)) {
$contacts = sprintf( tt('%d Contact','%d Contacts', $total),$total);
$micropro = Array();
foreach($r as $rr) {
$micropro[] = micropro($rr,true,'mpfriend');
if ($r) {
$contacts = "";
foreach ($r AS $contact)
$contacts[] = $contact["id"];
$r = q("SELECT `id`, `uid`, `addr`, `url`, `name`, `thumb`, `network` FROM `contact` WHERE `id` IN (%s)",
dbesc(implode(",", $contacts)));
if(count($r)) {
$contacts = sprintf( tt('%d Contact','%d Contacts', $total),$total);
$micropro = Array();
foreach($r as $rr) {
$micropro[] = micropro($rr,true,'mpfriend');
}
}
}
}

View file

@ -287,7 +287,7 @@ function import_account(&$a, $file) {
}
// send relocate messages
proc_run('php', 'include/notifier.php', 'relocate', $newuid);
proc_run(PRIORITY_HIGH, 'include/notifier.php', 'relocate', $newuid);
info(t("Done. You can now login with your username and password"));
goaway($a->get_baseurl() . "/login");

View file

@ -27,8 +27,11 @@ class xml {
foreach ($namespaces AS $nskey => $nsvalue)
$key .= " xmlns".($nskey == "" ? "":":").$nskey.'="'.$nsvalue.'"';
$root = new SimpleXMLElement("<".$key."/>");
self::from_array($value, $root, $remove_header, $namespaces, false);
if (is_array($value)) {
$root = new SimpleXMLElement("<".$key."/>");
self::from_array($value, $root, $remove_header, $namespaces, false);
} else
$root = new SimpleXMLElement("<".$key.">".xmlify($value)."</".$key.">");
$dom = dom_import_simplexml($root)->ownerDocument;
$dom->formatOutput = true;
@ -44,6 +47,20 @@ class xml {
}
foreach($array as $key => $value) {
if (!isset($element) AND isset($xml))
$element = $xml;
if (is_integer($key)) {
if (isset($element)) {
if (is_scalar($value)) {
$element[0] = $value;
} else {
/// @todo: handle nested array values
}
}
continue;
}
if (substr($key, 0, 11) == "@attributes") {
if (!isset($element) OR !is_array($value))
continue;
@ -55,7 +72,7 @@ class xml {
else
$namespace = NULL;
$element->addAttribute ($attr_key, $attr_value, $namespace);
$element->addAttribute($attr_key, $attr_value, $namespace);
}
continue;
@ -64,6 +81,8 @@ class xml {
$element_parts = explode(":", $key);
if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
$namespace = $namespaces[$element_parts[0]];
elseif (isset($namespaces[""]))
$namespace = $namespaces[""];
else
$namespace = NULL;
@ -131,11 +150,11 @@ class xml {
/**
* @brief Convert an XML document to a normalised, case-corrected array
* used by webfinger
*
*
* @param object $xml_element The XML document
* @param integer $recursion_depth recursion counter for internal use - default 0
* @param integer $recursion_depth recursion counter for internal use - default 0
* internal use, recursion counter
*
*
* @return array | sring The array from the xml element or the string
*/
public static function element_to_array($xml_element, &$recursion_depth=0) {
@ -181,23 +200,23 @@ class xml {
/**
* @brief Convert the given XML text to an array in the XML structure.
*
*
* xml::to_array() will convert the given XML text to an array in the XML structure.
* Link: http://www.bin-co.com/php/scripts/xml2array/
* Portions significantly re-written by mike@macgirvin.com for Friendica
* (namespaces, lowercase tags, get_attribute default changed, more...)
*
*
* Examples: $array = xml::to_array(file_get_contents('feed.xml'));
* $array = xml::to_array(file_get_contents('feed.xml', true, 1, 'attribute'));
*
*
* @param object $contents The XML text
* @param boolean $namespaces True or false include namespace information
* in the returned array as array elements.
* @param integer $get_attributes 1 or 0. If this is 1 the function will get the attributes as well as the tag values -
* @param integer $get_attributes 1 or 0. If this is 1 the function will get the attributes as well as the tag values -
* this results in a different array structure in the return value.
* @param string $priority Can be 'tag' or 'attribute'. This will change the way the resulting
* array sturcture. For 'tag', the tags are given more importance.
*
*
* @return array The parsed XML in an array form. Use print_r() to see the resulting array structure.
*/
public static function to_array($contents, $namespaces = true, $get_attributes=1, $priority = 'attribute') {

View file

@ -4,6 +4,7 @@
// Attribution: http://www.krisbailey.com
// license: unknown
// modified: Mike Macgrivin mike@macgirvin.com 6-oct-2010 to support Salmon auto-discovery
// modified: Tobias Diekershoff 28-jul-2016 adding an intval in line 162 to make PHP7 happy
// from openssl public keys
@ -159,7 +160,7 @@ class ASN_BASE {
}
$length = $tempLength;
}
$data = substr($string, $p, $length);
$data = substr($string, $p, intval($length));
$parsed[] = self::parseASNData($type, $data, $level, $maxLevels);
$p = $p + $length;
}

View file

@ -549,7 +549,7 @@ function admin_page_site_post(&$a) {
$users = q("SELECT `uid` FROM `user` WHERE `account_removed` = 0 AND `account_expired` = 0");
foreach ($users as $user) {
proc_run('php', 'include/notifier.php', 'relocate', $user['uid']);
proc_run(PRIORITY_HIGH, 'include/notifier.php', 'relocate', $user['uid']);
}
info("Relocation started. Could take a while to complete.");

View file

@ -237,7 +237,7 @@ function _contact_update($contact_id) {
intval($contact_id));
} else
// pull feed and consume it, which should subscribe to the hub.
proc_run('php',"include/onepoll.php","$contact_id", "force");
proc_run(PRIORITY_MEDIUM, "include/onepoll.php", $contact_id, "force");
}
function _contact_update_profile($contact_id) {
@ -434,7 +434,8 @@ function contacts_content(&$a) {
$a->page['aside'] = '';
return replace_macros(get_markup_template('contact_drop_confirm.tpl'), array(
'$contact' => _contact_detail_for_template($orig_record[0]),
'$header' => t('Drop contact'),
'$contact' => _contact_detail_for_template($orig_record[0]),
'$method' => 'get',
'$message' => t('Do you really want to delete this contact?'),
'$extra_inputs' => $inputs,

View file

@ -224,7 +224,7 @@ function content_content(&$a, $update = 0) {
$simple_update
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
$sql_extra $sql_nets
ORDER BY `item`.`received` DESC $pager_sql ",
ORDER BY `item`.`id` DESC $pager_sql ",
intval($_SESSION['uid'])
);

View file

@ -487,7 +487,7 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
$i = item_store($arr);
if($i)
proc_run('php',"include/notifier.php","activity","$i");
proc_run(PRIORITY_HIGH, "include/notifier.php", "activity", $i);
}
}
}
@ -784,7 +784,7 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
$i = item_store($arr);
if($i)
proc_run('php',"include/notifier.php","activity","$i");
proc_run(PRIORITY_HIGH, "include/notifier.php", "activity", $i);
}
}

View file

@ -156,7 +156,7 @@ function dirfind_content(&$a, $prefix = "") {
}
// Add found profiles from the global directory to the local directory
proc_run('php','include/discover_poco.php', "dirsearch", urlencode($search));
proc_run(PRIORITY_LOW, 'include/discover_poco.php', "dirsearch", urlencode($search));
} else {
$p = (($a->pager['page'] != 1) ? '&p=' . $a->pager['page'] : '');

View file

@ -177,7 +177,7 @@ function events_post(&$a) {
$item_id = event_store($datarray);
if(! $cid)
proc_run('php',"include/notifier.php","event","$item_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "event", $item_id);
goaway($_SESSION['return_url']);
}

View file

@ -57,7 +57,7 @@ function fsuggest_post(&$a) {
intval($fsuggest_id),
intval(local_user())
);
proc_run('php', 'include/notifier.php', 'suggest' , $fsuggest_id);
proc_run(PRIORITY_HIGH, 'include/notifier.php', 'suggest', $fsuggest_id);
}
info( t('Friend suggestion sent.') . EOL);

View file

@ -783,7 +783,7 @@ function item_post(&$a) {
// update filetags in pconfig
file_tag_update_pconfig($uid,$categories_old,$categories_new,'category');
proc_run('php', "include/notifier.php", 'edit_post', "$post_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", 'edit_post', $post_id);
if((x($_REQUEST,'return')) && strlen($return_path)) {
logger('return: ' . $return_path);
goaway($a->get_baseurl() . "/" . $return_path );
@ -1032,7 +1032,7 @@ function item_post(&$a) {
// Currently the only realistic fixes are to use a reliable server - which precludes shared hosting,
// or cut back on plugins which do remote deliveries.
proc_run('php', "include/notifier.php", $notify_type, "$post_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", $notify_type, $post_id);
logger('post_complete');

View file

@ -95,13 +95,13 @@ function mood_init(&$a) {
intval($uid),
intval($item_id)
);
proc_run('php',"include/notifier.php","tag","$item_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "tag", $item_id);
}
call_hooks('post_local_end', $arr);
proc_run('php',"include/notifier.php","like","$post_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "like", $post_id);
return;
}

View file

@ -306,7 +306,7 @@ function photos_post(&$a) {
// send the notification upstream/downstream as the case may be
if($rr['visible'])
proc_run('php',"include/notifier.php","drop","$drop_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "drop", $drop_id);
}
}
}
@ -376,7 +376,7 @@ function photos_post(&$a) {
$drop_id = intval($i[0]['id']);
if($i[0]['visible'])
proc_run('php',"include/notifier.php","drop","$drop_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "drop", $drop_id);
}
}
@ -719,7 +719,7 @@ function photos_post(&$a) {
$item_id = item_store($arr);
if($item_id) {
proc_run('php',"include/notifier.php","tag","$item_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "tag", $item_id);
}
}
@ -935,7 +935,7 @@ function photos_post(&$a) {
$item_id = item_store($arr);
if($visible)
proc_run('php', "include/notifier.php", 'wall-new', $item_id);
proc_run(PRIORITY_HIGH, "include/notifier.php", 'wall-new', $item_id);
call_hooks('photo_post_end',intval($item_id));

View file

@ -131,13 +131,13 @@ function poke_init(&$a) {
// intval($uid),
// intval($item_id)
//);
proc_run('php',"include/notifier.php","tag","$item_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "tag", $item_id);
}
call_hooks('post_local_end', $arr);
proc_run('php',"include/notifier.php","like","$post_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "like", $post_id);
return;
}

View file

@ -125,7 +125,7 @@ function profile_photo_post(&$a) {
// Update global directory in background
$url = $a->get_baseurl() . '/profile/' . $a->user['nickname'];
if($url && strlen(get_config('system','directory')))
proc_run('php',"include/directory.php","$url");
proc_run(PRIORITY_LOW, "include/directory.php", $url);
require_once('include/profile_update.php');
profile_change();
@ -224,7 +224,7 @@ function profile_photo_content(&$a) {
// Update global directory in background
$url = $_SESSION['my_url'];
if($url && strlen(get_config('system','directory')))
proc_run('php',"include/directory.php","$url");
proc_run(PRIORITY_LOW, "include/directory.php", $url);
goaway($a->get_baseurl() . '/profiles');
return; // NOTREACHED

View file

@ -496,7 +496,7 @@ function profiles_post(&$a) {
// Update global directory in background
$url = $_SESSION['my_url'];
if($url && strlen(get_config('system','directory')))
proc_run('php',"include/directory.php","$url");
proc_run(PRIORITY_LOW, "include/directory.php", $url);
require_once('include/profile_update.php');
profile_change();
@ -587,9 +587,8 @@ function profile_activity($changed, $value) {
$arr['deny_gid'] = $a->user['deny_gid'];
$i = item_store($arr);
if($i) {
proc_run('php',"include/notifier.php","activity","$i");
}
if($i)
proc_run(PRIORITY_HIGH, "include/notifier.php", "activity", $i);
}

View file

@ -64,7 +64,7 @@ function register_post(&$a) {
if($netpublish && $a->config['register_policy'] != REGISTER_APPROVE) {
$url = $a->get_baseurl() . '/profile/' . $user['nickname'];
proc_run('php',"include/directory.php","$url");
proc_run(PRIORITY_LOW, "include/directory.php", $url);
}
$using_invites = get_config('system','invitation_only');

View file

@ -37,7 +37,7 @@ function user_allow($hash) {
if(count($r) && $r[0]['net-publish']) {
$url = $a->get_baseurl() . '/profile/' . $user[0]['nickname'];
if($url && strlen(get_config('system','directory')))
proc_run('php',"include/directory.php","$url");
proc_run(PRIORITY_LOW, "include/directory.php", $url);
}
push_lang($register[0]['language']);

View file

@ -352,7 +352,7 @@ function settings_post(&$a) {
check_form_security_token_redirectOnErr('/settings', 'settings');
if (x($_POST,'resend_relocate')) {
proc_run('php', 'include/notifier.php', 'relocate', local_user());
proc_run(PRIORITY_HIGH, 'include/notifier.php', 'relocate', local_user());
info(t("Relocate message has been send to your contacts"));
goaway('settings');
}
@ -614,7 +614,7 @@ function settings_post(&$a) {
// Update global directory in background
$url = $_SESSION['my_url'];
if($url && strlen(get_config('system','directory')))
proc_run('php',"include/directory.php","$url");
proc_run(PRIORITY_LOW, "include/directory.php", $url);
}
require_once('include/profile_update.php');

View file

@ -211,7 +211,7 @@ EOT;
call_hooks('post_local_end', $arr);
proc_run('php',"include/notifier.php","tag","$post_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "tag", $post_id);
killme();

View file

@ -167,7 +167,7 @@ function videos_post(&$a) {
$drop_id = intval($i[0]['id']);
if($i[0]['visible'])
proc_run('php',"include/notifier.php","drop","$drop_id");
proc_run(PRIORITY_HIGH, "include/notifier.php", "drop", $drop_id);
}
}

View file

@ -1,6 +1,6 @@
<?php
define('UPDATE_VERSION' , 1199);
define('UPDATE_VERSION' , 1200);
/**
*
@ -1595,7 +1595,7 @@ function update_1169() {
if (!$r)
return UPDATE_FAILED;
proc_run('php',"include/threadupdate.php");
proc_run(PRIORITY_LOW, "include/threadupdate.php");
return UPDATE_SUCCESS;
}
@ -1636,7 +1636,7 @@ function update_1178() {
set_config('system','community_page_style', CP_NO_COMMUNITY_PAGE);
// Update the central item storage with uid=0
proc_run('php',"include/threadupdate.php");
proc_run(PRIORITY_LOW, "include/threadupdate.php");
return UPDATE_SUCCESS;
}
@ -1644,7 +1644,7 @@ function update_1178() {
function update_1180() {
// Fill the new fields in the term table.
proc_run('php',"include/tagupdate.php");
proc_run(PRIORITY_LOW, "include/tagupdate.php");
return UPDATE_SUCCESS;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,67 +0,0 @@
<config>
<site>
<name>{{$config.site.name}}</name>
<server>{{$config.site.server}}</server>
<theme>default</theme>
<path></path>
<logo>{{$config.site.logo}}</logo>
<fancy>true</fancy>
<language>en</language>
<email>{{$config.site.email}}</email>
<broughtby></broughtby>
<broughtbyurl></broughtbyurl>
<timezone>UTC</timezone>
<closed>{{$config.site.closed}}</closed>
<inviteonly>false</inviteonly>
<private>{{$config.site.private}}</private>
<textlimit>{{$config.site.textlimit}}</textlimit>
<ssl>{{$config.site.ssl}}</ssl>
<sslserver>{{$config.site.sslserver}}</sslserver>
<shorturllength>30</shorturllength>
</site>
<license>
<type>cc</type>
<owner></owner>
<url>http://creativecommons.org/licenses/by/3.0/</url>
<title>Creative Commons Attribution 3.0</title>
<image>http://i.creativecommons.org/l/by/3.0/80x15.png</image>
</license>
<nickname>
<featured></featured>
</nickname>
<profile>
<biolimit></biolimit>
</profile>
<group>
<desclimit></desclimit>
</group>
<notice>
<contentlimit></contentlimit>
</notice>
<throttle>
<enabled>false</enabled>
<count>20</count>
<timespan>600</timespan>
</throttle>
<xmpp>
<enabled>false</enabled>
<server>INVALID SERVER</server>
<port>5222</port>
<user>update</user>
</xmpp>
<integration>
<source>StatusNet</source>
</integration>
<attachments>
<uploads>false</uploads>
<file_quota>0</file_quota>
</attachments>
</config>

View file

@ -1,6 +0,0 @@
{{* used in include/api.php 'api_statuses_friends' and 'api_statuses_followers' *}}
<users type="array">
{{foreach $users as $u}}
<user>{{include file="api_user_xml.tpl" user=$u}}</user>
{{/foreach}}
</users>

View file

@ -1,21 +0,0 @@
<photo>
<id>{{$photo.id}}</id>
<created>{{$photo.created}}</created>
<edited>{{$photo.edited}}</edited>
<title>{{$photo.title}}</title>
<desc>{{$photo.desc}}</desc>
<album>{{$photo.album}}</album>
<filename>{{$photo.filename}}</filename>
<type>{{$photo.type}}</type>
<height>{{$photo.height}}</height>
<width>{{$photo.width}}</width>
<datasize>{{$photo.datasize}}</datasize>
<profile>1</profile>
<links type="array">{{foreach $photo.link as $scale => $url}}
<link type="{{$photo.type}}" scale="{{$scale}}" href="{{$url}}" />
{{/foreach}}</links>
{{if $photo.data}}
<data encode="base64">{{$photo.data}}</data>
{{/if}}
</photo>

View file

@ -1,5 +0,0 @@
<photos type="array">
{{foreach $photos as $photo}}
<photo id="{{$photo.id}}" album="{{$photo.album}}" filename="{{$photo.filename}}" type="{{$photo.type}}">{{$photo.thumb}}</photo>
{{/foreach}}</photos>

View file

@ -1,7 +0,0 @@
<hash>
<remaining-hits type="integer">{{$hash.remaining_hits}}</remaining-hits>
<hourly-limit type="integer">{{$hash.hourly_limit}}</hourly-limit>
<reset-time type="datetime">{{$hash.reset_time}}</reset-time>
<reset_time_in_seconds type="integer">{{$hash.resettime_in_seconds}}</reset_time_in_seconds>
</hash>

View file

@ -1,25 +0,0 @@
{{* shared structure for statuses. includers must define root element *}}
<text>{{$status.text}}</text>
<truncated>{{$status.truncated}}</truncated>
<created_at>{{$status.created_at}}</created_at>
<in_reply_to_status_id>{{$status.in_reply_to_status_id}}</in_reply_to_status_id>
<source>{{$status.source}}</source>
<id>{{$status.id}}</id>
<in_reply_to_user_id>{{$status.in_reply_to_user_id}}</in_reply_to_user_id>
<in_reply_to_screen_name>{{$status.in_reply_to_screen_name}}</in_reply_to_screen_name>
<geo>{{$status.geo}}</geo>
<favorited>{{$status.favorited}}</favorited>
<user>{{include file="api_user_xml.tpl" user=$status.user}}</user>
<friendica:owner>{{include file="api_user_xml.tpl" user=$status.friendica_owner}}</friendica:owner>
<statusnet:html>{{$status.statusnet_html}}</statusnet:html>
<statusnet:conversation_id>{{$status.statusnet_conversation_id}}</statusnet:conversation_id>
<url>{{$status.url}}</url>
<coordinates>{{$status.coordinates}}</coordinates>
<place>{{$status.place}}</place>
<contributors>{{$status.contributors}}</contributors>
{{if $status.retweeted_status}}<retweeted_status>{{include file="api_single_status_xml.tpl" status=$status.retweeted_status}}</retweeted_status>{{/if}}
<friendica:activities>
{{foreach $status.friendica_activities as $k=>$v}}
<friendica:{{$k}}>{{$v|count}}</friendica:{{$k}}>
{{/foreach}}
</friendica:activities>

View file

@ -1,8 +0,0 @@
{{* used in api.php to return a single status *}}
<status
xmlns:statusnet="http://status.net/schema/api/1/"
xmlns:friendica="http://friendi.ca/schema/api/1/">
{{if $status}}
{{include file="api_single_status_xml.tpl" status=$status}}
{{/if}}
</status>

View file

@ -1,2 +0,0 @@
<ok>{{$ok}}</ok>

View file

@ -1,91 +0,0 @@
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:georss="http://www.georss.org/georss" xmlns:activity="http://activitystrea.ms/spec/1.0/" xmlns:media="http://purl.org/syndication/atommedia" xmlns:poco="http://portablecontacts.net/spec/1.0" xmlns:ostatus="http://ostatus.org/schema/1.0" xmlns:statusnet="http://status.net/schema/api/1/">
<generator uri="http://status.net" version="0.9.7">StatusNet</generator>
<id>{{$rss.self}}</id>
<title>Friendica</title>
<subtitle>Friendica API feed</subtitle>
<logo>{{$rss.logo}}</logo>
<updated>{{$rss.atom_updated}}</updated>
<link type="text/html" rel="alternate" href="{{$rss.alternate}}"/>
<link type="application/atom+xml" rel="self" href="{{$rss.self}}"/>
<author>
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
<uri>{{$user.url}}</uri>
<name>{{$user.name}}</name>
<link rel="alternate" type="text/html" href="{{$user.url}}"/>
<link rel="avatar" type="image/jpeg" media:width="106" media:height="106" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="96" media:height="96" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="48" media:height="48" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="24" media:height="24" href="{{$user.profile_image_url}}"/>
<georss:point></georss:point>
<poco:preferredUsername>{{$user.screen_name}}</poco:preferredUsername>
<poco:displayName>{{$user.name}}</poco:displayName>
<poco:urls>
<poco:type>homepage</poco:type>
<poco:value>{{$user.url}}</poco:value>
<poco:primary>true</poco:primary>
</poco:urls>
<statusnet:profile_info local_id="{{$user.id}}"></statusnet:profile_info>
</author>
<!--Deprecation warning: activity:subject is present only for backward compatibility. It will be removed in the next version of StatusNet.-->
<activity:subject>
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
<id>{{$user.contact_url}}</id>
<title>{{$user.name}}</title>
<link rel="alternate" type="text/html" href="{{$user.url}}"/>
<link rel="avatar" type="image/jpeg" media:width="106" media:height="106" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="96" media:height="96" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="48" media:height="48" href="{{$user.profile_image_url}}"/>
<link rel="avatar" type="image/jpeg" media:width="24" media:height="24" href="{{$user.profile_image_url}}"/>
<poco:preferredUsername>{{$user.screen_name}}</poco:preferredUsername>
<poco:displayName>{{$user.name}}</poco:displayName>
<poco:urls>
<poco:type>homepage</poco:type>
<poco:value>{{$user.url}}</poco:value>
<poco:primary>true</poco:primary>
</poco:urls>
<statusnet:profile_info local_id="{{$user.id}}"></statusnet:profile_info>
</activity:subject>
{{foreach $statuses as $status}}
<entry>
<activity:object-type>{{$status.objecttype}}</activity:object-type>
<id>{{$status.message_id}}</id>
<title>{{$status.text}}</title>
<content type="html">{{$status.statusnet_html}}</content>
<link rel="alternate" type="text/html" href="{{$status.url}}"/>
<activity:verb>{{$status.verb}}</activity:verb>
<published>{{$status.published}}</published>
<updated>{{$status.updated}}</updated>
<link rel="self" type="application/atom+xml" href="{{$status.self}}"/>
<link rel="edit" type="application/atom+xml" href="{{$status.edit}}"/>
<statusnet:notice_info local_id="{{$status.id}}" source="{{$status.source}}" >
</statusnet:notice_info>
<author>
<activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
<uri>{{$status.user.url}}</uri>
<name>{{$status.user.name}}</name>
<link rel="alternate" type="text/html" href="{{$status.user.url}}"/>
<link rel="avatar" type="image/jpeg" media:width="48" media:height="48" href="{{$status.user.profile_image_url}}"/>
<georss:point/>
<poco:preferredUsername>{{$status.user.screen_name}}</poco:preferredUsername>
<poco:displayName>{{$status.user.name}}</poco:displayName>
<poco:address/>
<poco:urls>
<poco:type>homepage</poco:type>
<poco:value>{{$status.user.url}}</poco:value>
<poco:primary>true</poco:primary>
</poco:urls>
</author>
<link rel="ostatus:conversation" type="text/html" href="{{$status.url}}"/>
</entry>
{{/foreach}}
</feed>

View file

@ -1,27 +0,0 @@
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:georss="http://www.georss.org/georss" xmlns:twitter="http://api.twitter.com">
<channel>
<title>Friendica</title>
<link>{{$rss.alternate}}</link>
<atom:link type="application/rss+xml" rel="self" href="{{$rss.self}}"/>
<description>Friendica timeline</description>
<language>{{$rss.language}}</language>
<ttl>40</ttl>
<image>
<link>{{$user.link}}</link>
<title>{{$user.name}}'s items</title>
<url>{{$user.profile_image_url}}</url>
</image>
{{foreach $statuses as $status}}
<item>
<title>{{$status.user.name}}: {{$status.text}}</title>
<description>{{$status.text}}</description>
<pubDate>{{$status.created_at}}</pubDate>
<guid>{{$status.url}}</guid>
<link>{{$status.url}}</link>
<twitter:source>{{$status.source}}</twitter:source>
</item>
{{/foreach}}
</channel>
</rss>

View file

@ -1,10 +0,0 @@
<statuses type="array"
xmlns:statusnet="http://status.net/schema/api/1/"
xmlns:friendica="http://friendi.ca/schema/api/1/">
{{foreach $statuses as $status}}
<status>
{{include file="api_single_status_xml.tpl" status=$status}}
</status>
{{/foreach}}
</statuses>

View file

@ -1,47 +0,0 @@
{{* includer template MUST provide root element *}}
<id>{{$user.id}}</id>
<name>{{$user.name}}</name>
<screen_name>{{$user.screen_name}}</screen_name>
<location>{{$user.location}}</location>
<description>{{$user.description}}</description>
<profile_image_url>{{$user.profile_image_url}}</profile_image_url>
<url>{{$user.url}}</url>
<protected>{{$user.protected}}</protected>
<followers_count>{{$user.followers_count}}</followers_count>
<friends_count>{{$user.friends_count}}</friends_count>
<created_at>{{$user.created_at}}</created_at>
<favourites_count>{{$user.favourites_count}}</favourites_count>
<utc_offset>{{$user.utc_offset}}</utc_offset>
<time_zone>{{$user.time_zone}}</time_zone>
<statuses_count>{{$user.statuses_count}}</statuses_count>
<following>{{$user.following}}</following>
<profile_background_color>{{$user.profile_background_color}}</profile_background_color>
<profile_text_color>{{$user.profile_text_color}}</profile_text_color>
<profile_link_color>{{$user.profile_link_color}}</profile_link_color>
<profile_sidebar_fill_color>{{$user.profile_sidebar_fill_color}}</profile_sidebar_fill_color>
<profile_sidebar_border_color>{{$user.profile_sidebar_border_color}}</profile_sidebar_border_color>
<profile_background_image_url>{{$user.profile_background_image_url}}</profile_background_image_url>
<profile_background_tile>{{$user.profile_background_tile}}</profile_background_tile>
<profile_use_background_image>{{$user.profile_use_background_image}}</profile_use_background_image>
<notifications>{{$user.notifications}}</notifications>
<geo_enabled>{{$user.geo_enabled}}</geo_enabled>
<verified>{{$user.verified}}</verified>
<lang>{{$user.lang}}</lang>
<contributors_enabled>{{$user.contributors_enabled}}</contributors_enabled>
<status>{{if $user.status}}
<created_at>{{$user.status.created_at}}</created_at>
<id>{{$user.status.id}}</id>
<text>{{$user.status.text}}</text>
<source>{{$user.status.source}}</source>
<truncated>{{$user.status.truncated}}</truncated>
<in_reply_to_status_id>{{$user.status.in_reply_to_status_id}}</in_reply_to_status_id>
<in_reply_to_user_id>{{$user.status.in_reply_to_user_id}}</in_reply_to_user_id>
<favorited>{{$user.status.favorited}}</favorited>
<in_reply_to_screen_name>{{$user.status.in_reply_to_screen_name}}</in_reply_to_screen_name>
<geo>{{$user.status.geo}}</geo>
<coordinates>{{$user.status.coordinates}}</coordinates>
<place>{{$user.status.place}}</place>
<contributors>{{$user.status.contributors}}</contributors>
{{/if}}</status>

View file

@ -1,4 +1,4 @@
<h1>{{"Drop contact"|t}}</h1>
<h1>{{$header}}</h1>
{{include file="contact_template.tpl" no_contacts_checkbox=True}}

View file

@ -4,11 +4,11 @@
<p class="intro-desc">{{$str_notifytype}} {{$notify_type}}</p>
<img id="photo-{{$contact_id}}" class="intro-photo" src="{{$photo}}" width="175" height=175" title="{{$fullname|escape:'html'}}" alt="{{$fullname|escape:'html'}}" />
<dl><dt>{{$url_label}}</dt><dd><a target="blank" href="{{$zrl}}">{{$url}}</a></dd></dl>
{{if $location}}<dl><dt>{{$location_label}}</dt><dd>{{$location}}</dd></dl>{{/if}}
{{if $gender}}<dl><dt>{{$gender_label}}</dt><dd>{{$gender}}</dd></dl>{{/if}}
{{if $keywords}}<dl><dt>{{$keywords_label}}</dt><dd>{{$keywords}}</dd></dl>{{/if}}
{{if $about}}<dl><dt>{{$about_label}}</dt><dd>{{$about}}</dd></dl>{{/if}}
<dl><dt>{{$lbl_url}}</dt><dd><a target="blank" href="{{$zrl}}">{{$url}}</a></dd></dl>
{{if $location}}<dl><dt>{{$lbl_location}}</dt><dd>{{$location}}</dd></dl>{{/if}}
{{if $gender}}<dl><dt>{{$lbl_gender}}</dt><dd>{{$gender}}</dd></dl>{{/if}}
{{if $keywords}}<dl><dt>{{$lbl_keywords}}</dt><dd>{{$keywords}}</dd></dl>{{/if}}
{{if $about}}<dl><dt>{{$lbl_about}}</dt><dd>{{$about}}</dd></dl>{{/if}}
<div class="intro-knowyou">{{$lbl_knowyou}} {{$knowyou}}</div>
<div class="intro-note" id="intro-note-{{$contact_id}}">{{$note}}</div>
<div class="intro-wrapper-end" id="intro-wrapper-end-{{$contact_id}}"></div>

View file

@ -1908,6 +1908,14 @@ ul li:hover .contact-wrapper a.contact-action-link:hover {
#directory-search-wrapper{
padding: 10px 0;
}
#contact-drop-confirm .contact-actions,
#contact-drop-confirm .contact-photo-overlay,
#contact-drop-confirm .contact-photo-menu {
display: none;
}
#contact-drop-confirm #confirm-form {
margin-top: 20px;
}
/* contact-edit */
#contact-edit-actions {

View file

@ -0,0 +1,14 @@
<form action="{{$confirm_url}}" id="confirm-form" method="{{$method}}">
<div id="confirm-message">{{$message}}</div>
{{foreach $extra_inputs as $input}}
<input type="hidden" name="{{$input.name}}" value="{{$input.value|escape:'html'}}" />
{{/foreach}}
<div class="form-group pull-right settings-submit-wrapper" >
<button type="submit" name="{{$confirm_name}}" id="confirm-submit-button" class="btn btn-primary confirm-button" value="{{$confirm|escape:'html'}}">{{$confirm|escape:'html'}}</button>
<button type="submit" name="canceled" id="confirm-cancel-button" class="btn confirm-button" data-dismiss="modal">{{$cancel|escape:'html'}}</button>
</div>
</form>

View file

@ -0,0 +1,9 @@
<div id="contact-drop-confirm">
<h2 class="heading">{{$header}}</h2>
{{include file="contact_template.tpl" no_contacts_checkbox=True}}
{{include file="confirm.tpl"}}
<div class="clear"></div>
</div>

View file

@ -91,7 +91,7 @@
{{if $keywords}}
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<hr class="profile-separator">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 text-muted">{$keywords_label}}</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 text-muted">{{$keywords_label}}</div>
<div class="col-lg-8 col-md-8 col-sm-8 col-xs-12">{{$keywords}}</div>
</div>
{{/if}}

View file

@ -52,7 +52,7 @@
{{if $contact.photo_menu.poke}}<a class="contact-action-link" onclick="addToModal('{{$contact.photo_menu.poke.1}}')" data-toggle="tooltip" title="{{$contact.photo_menu.poke.0}}"><i class="fa fa-heartbeat" aria-hidden="true"></i></a>{{/if}}
{{if $contact.photo_menu.network}}<a class="contact-action-link" href="{{$contact.photo_menu.network.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.network.0}}"><i class="fa fa-cloud" aria-hidden="true"></i></a>{{/if}}
{{if $contact.photo_menu.edit}}<a class="contact-action-link" href="{{$contact.photo_menu.edit.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.edit.0}}"><i class="fa fa-pencil" aria-hidden="true"></i></a>{{/if}}
{{if $contact.photo_menu.drop}}<a class="contact-action-link" href="{{$contact.photo_menu.drop.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.drop.0}}"><i class="fa fa-user-times" aria-hidden="true"></i></a>{{/if}}
{{if $contact.photo_menu.drop}}<a class="contact-action-link" onclick="addToModal('{{$contact.photo_menu.drop.1}}')" data-toggle="tooltip" title="{{$contact.photo_menu.drop.0}}"><i class="fa fa-user-times" aria-hidden="true"></i></a>{{/if}}
{{if $contact.photo_menu.follow}}<a class="contact-action-link" href="{{$contact.photo_menu.follow.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.follow.0}}"><i class="fa fa-user-plus" aria-hidden="true"></i></a>{{/if}}
{{if $contact.photo_menu.hide}}<a class="contact-action-link" href="{{$contact.photo_menu.hide.1}}" data-toggle="tooltip" title="{{$contact.photo_menu.hide.0}}"><i class="fa fa-times" aria-hidden="true"></i></a>{{/if}}
</div>

View file

@ -20,12 +20,12 @@
<div class="intro-desc"><span class="intro-desc-label">{{$str_notifytype}}</span>{{$notify_type}}</div>
{{* Additional information of the contact *}}
<div class="intro-url"><span class="intro-url-label">{{$url_label}}:&nbsp;</span><a href="{{$zrl}}">{{$url}}</a></div>
<div class="intro-url"><span class="intro-url-label">{{$lbl_url}}:&nbsp;</span><a href="{{$zrl}}">{{$url}}</a></div>
{{if $network}}<div class="intro-network"><span class="intro-network-label">{{$lbl_network}}</span>&nbsp;{{$network}}</div>{{/if}}
{{if $location}}<div class="intro-location"><span class="intro-location-label">{{$location_label}}</span>&nbsp;{{$location}}</div>{{/if}}
{{if $gender}}<div class="intro-gender"><span class="intro-gender-label">{{$gender_label}}</span>&nbsp;{{$gender}}</div>{{/if}}
{{if $keywords}}<div class="intro-keywords"><span class="intro-keywords-label">{{$keywords_label}}</span>&nbsp;{{$keywords}}</div>{{/if}}
{{if $about}}<div class="intro-about"><span class="intro-about-label">{{$about_label}}</span>&nbsp;{{$about}}</div>{{/if}}
{{if $location}}<div class="intro-location"><span class="intro-location-label">{{$lbl_location}}</span>&nbsp;{{$location}}</div>{{/if}}
{{if $gender}}<div class="intro-gender"><span class="intro-gender-label">{{$lbl_gender}}</span>&nbsp;{{$gender}}</div>{{/if}}
{{if $keywords}}<div class="intro-keywords"><span class="intro-keywords-label">{{$lbl_keywords}}</span>&nbsp;{{$keywords}}</div>{{/if}}
{{if $about}}<div class="intro-about"><span class="intro-about-label">{{$lbl_about}}</span>&nbsp;{{$about}}</div>{{/if}}
<div class="intro-knowyou"><span class="intro-knowyou-label">{{$lbl_knowyou}}</span>{{$knowyou}}</div>
<div class="intro-note" id="intro-note-{{$contact_id}}">{{$note}}</div>