function proc_run($args) {
+ if (!function_exists("proc_open")) {
+ return;
+ }
+
// Add the php path if it is a php call
if (count($args) && ($args[0] === 'php' OR !is_string($args[0]))) {
* disable_email_validation (Boolean) - Disables the check if a mail address is in a valid format and can be resolved via DNS.
* disable_url_validation (Boolean) - Disables the DNS lookup of an URL.
* event_input_format - Default value is "ymd".
+* frontend_worker (Boolean) - Activates the frontend worker which acts as a replacement for running the poller via the command line.
+* frontend_worker_timeout - Value in minutes after we think that a frontend task was killed by the webserver. Default value is 10.
* ignore_cache (Boolean) - For development only. Disables the item cache.
* like_no_comment (Boolean) - Don't update the "commented" value of an item when it is liked.
* local_block (Boolean) - Used in conjunction with "block_public".
$r[0]['nickname']
);
+ /// @todo Should be done in a background job since this likely will run into a time out
// don't delete yet, will be done later when contacts have deleted my stuff
// q("DELETE FROM `contact` WHERE `uid` = %d", intval($uid));
q("DELETE FROM `gcign` WHERE `uid` = %d", intval($uid));
return;
}
- q("DELETE FROM `contact` WHERE `id` = %d",
- intval($id)
- );
- q("DELETE FROM `item` WHERE `contact-id` = %d ",
- intval($id)
- );
- q("DELETE FROM `photo` WHERE `contact-id` = %d ",
- intval($id)
- );
- q("DELETE FROM `mail` WHERE `contact-id` = %d ",
- intval($id)
- );
- q("DELETE FROM `event` WHERE `cid` = %d ",
- intval($id)
- );
- q("DELETE FROM `queue` WHERE `cid` = %d ",
- intval($id)
- );
+ q("DELETE FROM `contact` WHERE `id` = %d", intval($id));
+ // Delete the rest in the background
+ proc_run(PRIORITY_LOW, 'include/remove_contact.php', $id);
}
--- /dev/null
+<?php
+
+/**
+ * @file include/ParseUrl.php
+ * @brief Get informations about a given URL
+ */
+
+namespace Friendica;
+
+use \Friendica\Core\Config;
+
+require_once("include/network.php");
+require_once("include/Photo.php");
+require_once("include/oembed.php");
+require_once("include/xml.php");
+
+/**
+ * @brief Class with methods for extracting certain content from an url
+ */
+class ParseUrl {
+
+ /**
+ * @brief Search for chached embeddable data of an url otherwise fetch it
+ *
+ * @param type $url The url of the page which should be scraped
+ * @param type $no_guessing If true the parse doens't search for
+ * preview pictures
+ * @param type $do_oembed The false option is used by the function fetch_oembed()
+ * to avoid endless loops
+ *
+ * @return array which contains needed data for embedding
+ * string 'url' => The url of the parsed page
+ * string 'type' => Content type
+ * string 'title' => The title of the content
+ * string 'text' => The description for the content
+ * string 'image' => A preview image of the content (only available
+ * if $no_geuessing = false
+ * array'images' = Array of preview pictures
+ * string 'keywords' => The tags which belong to the content
+ *
+ * @see ParseUrl::getSiteinfo() for more information about scraping
+ * embeddable content
+ */
+ public static function getSiteinfoCached($url, $no_guessing = false, $do_oembed = true) {
+
+ if ($url == "") {
+ return false;
+ }
+
+ $r = q("SELECT * FROM `parsed_url` WHERE `url` = '%s' AND `guessing` = %d AND `oembed` = %d",
+ dbesc(normalise_link($url)), intval(!$no_guessing), intval($do_oembed));
+
+ if ($r) {
+ $data = $r[0]["content"];
+ }
+
+ if (!is_null($data)) {
+ $data = unserialize($data);
+ return $data;
+ }
+
+ $data = self::getSiteinfo($url, $no_guessing, $do_oembed);
+
+ q("INSERT INTO `parsed_url` (`url`, `guessing`, `oembed`, `content`, `created`) VALUES ('%s', %d, %d, '%s', '%s')
+ ON DUPLICATE KEY UPDATE `content` = '%s', `created` = '%s'",
+ dbesc(normalise_link($url)), intval(!$no_guessing), intval($do_oembed),
+ dbesc(serialize($data)), dbesc(datetime_convert()),
+ dbesc(serialize($data)), dbesc(datetime_convert()));
+
+ return $data;
+ }
+ /**
+ * @brief Parse a page for embeddable content information
+ *
+ * This method parses to url for meta data which can be used to embed
+ * the content. If available it prioritizes Open Graph meta tags.
+ * If this is not available it uses the twitter cards meta tags.
+ * As fallback it uses standard html elements with meta informations
+ * like \<title\>Awesome Title\</title\> or
+ * \<meta name="description" content="An awesome description"\>
+ *
+ * @param type $url The url of the page which should be scraped
+ * @param type $no_guessing If true the parse doens't search for
+ * preview pictures
+ * @param type $do_oembed The false option is used by the function fetch_oembed()
+ * to avoid endless loops
+ * @param type $count Internal counter to avoid endless loops
+ *
+ * @return array which contains needed data for embedding
+ * string 'url' => The url of the parsed page
+ * string 'type' => Content type
+ * string 'title' => The title of the content
+ * string 'text' => The description for the content
+ * string 'image' => A preview image of the content (only available
+ * if $no_geuessing = false
+ * array'images' = Array of preview pictures
+ * string 'keywords' => The tags which belong to the content
+ *
+ * @todo https://developers.google.com/+/plugins/snippet/
+ * @verbatim
+ * <meta itemprop="name" content="Awesome title">
+ * <meta itemprop="description" content="An awesome description">
+ * <meta itemprop="image" content="http://maple.libertreeproject.org/images/tree-icon.png">
+ *
+ * <body itemscope itemtype="http://schema.org/Product">
+ * <h1 itemprop="name">Shiny Trinket</h1>
+ * <img itemprop="image" src="{image-url}" />
+ * <p itemprop="description">Shiny trinkets are shiny.</p>
+ * </body>
+ * @endverbatim
+ */
+ public static function getSiteinfo($url, $no_guessing = false, $do_oembed = true, $count = 1) {
+
+ $a = get_app();
+
+ $siteinfo = array();
+
+ // Check if the URL does contain a scheme
+ $scheme = parse_url($url, PHP_URL_SCHEME);
+
+ if ($scheme == "") {
+ $url = "http://".trim($url, "/");
+ }
+
+ if ($count > 10) {
+ logger("parseurl_getsiteinfo: Endless loop detected for ".$url, LOGGER_DEBUG);
+ return($siteinfo);
+ }
+
+ $url = trim($url, "'");
+ $url = trim($url, '"');
+
+ $url = original_url($url);
+
+ $siteinfo["url"] = $url;
+ $siteinfo["type"] = "link";
+
+ $check_cert = Config::get("system", "verifyssl");
+
+ $stamp1 = microtime(true);
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_NOBODY, 1);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 3);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_USERAGENT, $a->get_useragent());
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, (($check_cert) ? 2 : false));
+
+ $header = curl_exec($ch);
+ $curl_info = @curl_getinfo($ch);
+ $http_code = $curl_info["http_code"];
+ curl_close($ch);
+
+ $a->save_timestamp($stamp1, "network");
+
+ if ((($curl_info["http_code"] == "301") || ($curl_info["http_code"] == "302") || ($curl_info["http_code"] == "303") || ($curl_info["http_code"] == "307"))
+ && (($curl_info["redirect_url"] != "") || ($curl_info["location"] != ""))) {
+ if ($curl_info["redirect_url"] != "") {
+ $siteinfo = self::getSiteinfo($curl_info["redirect_url"], $no_guessing, $do_oembed, ++$count);
+ } else {
+ $siteinfo = self::getSiteinfo($curl_info["location"], $no_guessing, $do_oembed, ++$count);
+ }
+ return($siteinfo);
+ }
+
+ // If the file is too large then exit
+ if ($curl_info["download_content_length"] > 1000000) {
+ return($siteinfo);
+ }
+
+ // If it isn't a HTML file then exit
+ if (($curl_info["content_type"] != "") && !strstr(strtolower($curl_info["content_type"]), "html")) {
+ return($siteinfo);
+ }
+
+ if ($do_oembed) {
+
+ $oembed_data = oembed_fetch_url($url);
+
+ if (!in_array($oembed_data->type, array("error", "rich"))) {
+ $siteinfo["type"] = $oembed_data->type;
+ }
+
+ if (($oembed_data->type == "link") && ($siteinfo["type"] != "photo")) {
+ if (isset($oembed_data->title)) {
+ $siteinfo["title"] = $oembed_data->title;
+ }
+ if (isset($oembed_data->description)) {
+ $siteinfo["text"] = trim($oembed_data->description);
+ }
+ if (isset($oembed_data->thumbnail_url)) {
+ $siteinfo["image"] = $oembed_data->thumbnail_url;
+ }
+ }
+ }
+
+ $stamp1 = microtime(true);
+
+ // Now fetch the body as well
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_NOBODY, 0);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_USERAGENT, $a->get_useragent());
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, (($check_cert) ? 2 : false));
+
+ $header = curl_exec($ch);
+ $curl_info = @curl_getinfo($ch);
+ $http_code = $curl_info["http_code"];
+ curl_close($ch);
+
+ $a->save_timestamp($stamp1, "network");
+
+ // Fetch the first mentioned charset. Can be in body or header
+ $charset = "";
+ if (preg_match('/charset=(.*?)['."'".'"\s\n]/', $header, $matches)) {
+ $charset = trim(trim(trim(array_pop($matches)), ';,'));
+ }
+
+ if ($charset == "") {
+ $charset = "utf-8";
+ }
+
+ $pos = strpos($header, "\r\n\r\n");
+
+ if ($pos) {
+ $body = trim(substr($header, $pos));
+ } else {
+ $body = $header;
+ }
+
+ if (($charset != "") && (strtoupper($charset) != "UTF-8")) {
+ logger("parseurl_getsiteinfo: detected charset ".$charset, LOGGER_DEBUG);
+ //$body = mb_convert_encoding($body, "UTF-8", $charset);
+ $body = iconv($charset, "UTF-8//TRANSLIT", $body);
+ }
+
+ $body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8");
+
+ $doc = new \DOMDocument();
+ @$doc->loadHTML($body);
+
+ \xml::deleteNode($doc, "style");
+ \xml::deleteNode($doc, "script");
+ \xml::deleteNode($doc, "option");
+ \xml::deleteNode($doc, "h1");
+ \xml::deleteNode($doc, "h2");
+ \xml::deleteNode($doc, "h3");
+ \xml::deleteNode($doc, "h4");
+ \xml::deleteNode($doc, "h5");
+ \xml::deleteNode($doc, "h6");
+ \xml::deleteNode($doc, "ol");
+ \xml::deleteNode($doc, "ul");
+
+ $xpath = new \DomXPath($doc);
+
+ $list = $xpath->query("//meta[@content]");
+ foreach ($list as $node) {
+ $attr = array();
+ if ($node->attributes->length) {
+ foreach ($node->attributes as $attribute) {
+ $attr[$attribute->name] = $attribute->value;
+ }
+ }
+
+ if (@$attr["http-equiv"] == "refresh") {
+ $path = $attr["content"];
+ $pathinfo = explode(";", $path);
+ $content = "";
+ foreach ($pathinfo as $value) {
+ if (substr(strtolower($value), 0, 4) == "url=") {
+ $content = substr($value, 4);
+ }
+ }
+ if ($content != "") {
+ $siteinfo = self::getSiteinfo($content, $no_guessing, $do_oembed, ++$count);
+ return($siteinfo);
+ }
+ }
+ }
+
+ $list = $xpath->query("//title");
+ if ($list->length > 0) {
+ $siteinfo["title"] = $list->item(0)->nodeValue;
+ }
+
+ //$list = $xpath->query("head/meta[@name]");
+ $list = $xpath->query("//meta[@name]");
+ foreach ($list as $node) {
+ $attr = array();
+ if ($node->attributes->length) {
+ foreach ($node->attributes as $attribute) {
+ $attr[$attribute->name] = $attribute->value;
+ }
+ }
+
+ $attr["content"] = trim(html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8"));
+
+ if ($attr["content"] != "") {
+ switch (strtolower($attr["name"])) {
+ case "fulltitle":
+ $siteinfo["title"] = $attr["content"];
+ break;
+ case "description":
+ $siteinfo["text"] = $attr["content"];
+ break;
+ case "thumbnail":
+ $siteinfo["image"] = $attr["content"];
+ break;
+ case "twitter:image":
+ $siteinfo["image"] = $attr["content"];
+ break;
+ case "twitter:image:src":
+ $siteinfo["image"] = $attr["content"];
+ break;
+ case "twitter:card":
+ if (($siteinfo["type"] == "") || ($attr["content"] == "photo")) {
+ $siteinfo["type"] = $attr["content"];
+ }
+ break;
+ case "twitter:description":
+ $siteinfo["text"] = $attr["content"];
+ break;
+ case "twitter:title":
+ $siteinfo["title"] = $attr["content"];
+ break;
+ case "dc.title":
+ $siteinfo["title"] = $attr["content"];
+ break;
+ case "dc.description":
+ $siteinfo["text"] = $attr["content"];
+ break;
+ case "keywords":
+ $keywords = explode(",", $attr["content"]);
+ break;
+ case "news_keywords":
+ $keywords = explode(",", $attr["content"]);
+ break;
+ }
+ }
+ if ($siteinfo["type"] == "summary") {
+ $siteinfo["type"] = "link";
+ }
+ }
+
+ if (isset($keywords)) {
+ $siteinfo["keywords"] = array();
+ foreach ($keywords as $keyword) {
+ if (!in_array(trim($keyword), $siteinfo["keywords"])) {
+ $siteinfo["keywords"][] = trim($keyword);
+ }
+ }
+ }
+
+ //$list = $xpath->query("head/meta[@property]");
+ $list = $xpath->query("//meta[@property]");
+ foreach ($list as $node) {
+ $attr = array();
+ if ($node->attributes->length) {
+ foreach ($node->attributes as $attribute) {
+ $attr[$attribute->name] = $attribute->value;
+ }
+ }
+
+ $attr["content"] = trim(html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8"));
+
+ if ($attr["content"] != "") {
+ switch (strtolower($attr["property"])) {
+ case "og:image":
+ $siteinfo["image"] = $attr["content"];
+ break;
+ case "og:title":
+ $siteinfo["title"] = $attr["content"];
+ break;
+ case "og:description":
+ $siteinfo["text"] = $attr["content"];
+ break;
+ }
+ }
+ }
+
+ if ((@$siteinfo["image"] == "") && !$no_guessing) {
+ $list = $xpath->query("//img[@src]");
+ foreach ($list as $node) {
+ $attr = array();
+ if ($node->attributes->length) {
+ foreach ($node->attributes as $attribute) {
+ $attr[$attribute->name] = $attribute->value;
+ }
+ }
+
+ $src = self::completeUrl($attr["src"], $url);
+ $photodata = get_photo_info($src);
+
+ if (($photodata) && ($photodata[0] > 150) && ($photodata[1] > 150)) {
+ if ($photodata[0] > 300) {
+ $photodata[1] = round($photodata[1] * (300 / $photodata[0]));
+ $photodata[0] = 300;
+ }
+ if ($photodata[1] > 300) {
+ $photodata[0] = round($photodata[0] * (300 / $photodata[1]));
+ $photodata[1] = 300;
+ }
+ $siteinfo["images"][] = array("src" => $src,
+ "width" => $photodata[0],
+ "height" => $photodata[1]);
+ }
+
+ }
+ } elseif ($siteinfo["image"] != "") {
+ $src = self::completeUrl($siteinfo["image"], $url);
+
+ unset($siteinfo["image"]);
+
+ $photodata = get_photo_info($src);
+
+ if (($photodata) && ($photodata[0] > 10) && ($photodata[1] > 10)) {
+ $siteinfo["images"][] = array("src" => $src,
+ "width" => $photodata[0],
+ "height" => $photodata[1]);
+ }
+ }
+
+ if ((@$siteinfo["text"] == "") && (@$siteinfo["title"] != "") && !$no_guessing) {
+ $text = "";
+
+ $list = $xpath->query("//div[@class='article']");
+ foreach ($list as $node) {
+ if (strlen($node->nodeValue) > 40) {
+ $text .= " ".trim($node->nodeValue);
+ }
+ }
+
+ if ($text == "") {
+ $list = $xpath->query("//div[@class='content']");
+ foreach ($list as $node) {
+ if (strlen($node->nodeValue) > 40) {
+ $text .= " ".trim($node->nodeValue);
+ }
+ }
+ }
+
+ // If none text was found then take the paragraph content
+ if ($text == "") {
+ $list = $xpath->query("//p");
+ foreach ($list as $node) {
+ if (strlen($node->nodeValue) > 40) {
+ $text .= " ".trim($node->nodeValue);
+ }
+ }
+ }
+
+ if ($text != "") {
+ $text = trim(str_replace(array("\n", "\r"), array(" ", " "), $text));
+
+ while (strpos($text, " ")) {
+ $text = trim(str_replace(" ", " ", $text));
+ }
+
+ $siteinfo["text"] = trim(html_entity_decode(substr($text, 0, 350), ENT_QUOTES, "UTF-8").'...');
+ }
+ }
+
+ logger("parseurl_getsiteinfo: Siteinfo for ".$url." ".print_r($siteinfo, true), LOGGER_DEBUG);
+
+ call_hooks("getsiteinfo", $siteinfo);
+
+ return($siteinfo);
+ }
+
+ /**
+ * @brief Convert tags from CSV to an array
+ *
+ * @param string $string Tags
+ * @return array with formatted Hashtags
+ */
+ public static function convertTagsToArray($string) {
+ $arr_tags = str_getcsv($string);
+ if (count($arr_tags)) {
+ // add the # sign to every tag
+ array_walk($arr_tags, array("self", "arrAddHashes"));
+
+ return $arr_tags;
+ }
+ }
+
+ /**
+ * @brief Add a hasht sign to a string
+ *
+ * This method is used as callback function
+ *
+ * @param string $tag The pure tag name
+ * @param int $k Counter for internal use
+ */
+ private static function arrAddHashes(&$tag, $k) {
+ $tag = "#" . $tag;
+ }
+
+ /**
+ * @brief Add a scheme to an url
+ *
+ * The src attribute of some html elements (e.g. images)
+ * can miss the scheme so we need to add the correct
+ * scheme
+ *
+ * @param string $url The url which possibly does have
+ * a missing scheme (a link to an image)
+ * @param string $scheme The url with a correct scheme
+ * (e.g. the url from the webpage which does contain the image)
+ *
+ * @return string The url with a scheme
+ */
+ private static function completeUrl($url, $scheme) {
+ $urlarr = parse_url($url);
+
+ // If the url does allready have an scheme
+ // we can stop the process here
+ if (isset($urlarr["scheme"])) {
+ return($url);
+ }
+
+ $schemearr = parse_url($scheme);
+
+ $complete = $schemearr["scheme"]."://".$schemearr["host"];
+
+ if (@$schemearr["port"] != "") {
+ $complete .= ":".$schemearr["port"];
+ }
+
+ if (strpos($urlarr["path"],"/") !== 0) {
+ $complete .= "/";
+ }
+
+ $complete .= $urlarr["path"];
+
+ if (@$urlarr["query"] != "") {
+ $complete .= "?".$urlarr["query"];
+ }
+
+ if (@$urlarr["fragment"] != "") {
+ $complete .= "#".$urlarr["fragment"];
+ }
+
+ return($complete);
+ }
+}
else
$conv_responses[$mode][$item['thr-parent']] ++;
+ if((local_user()) && (local_user() == $item['uid']) && ($item['self']))
+ $conv_responses[$mode][$item['thr-parent'] . '-self'] = 1;
+
$conv_responses[$mode][$item['thr-parent'] . '-l'][] = $url;
// there can only be one activity verb per item so if we found anything, we can stop looking
$ret[$v] = array();
$ret[$v]['count'] = ((x($conv_responses[$v],$item['uri'])) ? $conv_responses[$v][$item['uri']] : '');
$ret[$v]['list'] = ((x($conv_responses[$v],$item['uri'])) ? $conv_responses[$v][$item['uri'] . '-l'] : '');
+ $ret[$v]['self'] = ((x($conv_responses[$v],$item['uri'])) ? $conv_responses[$v][$item['uri'] . '-self'] : '0');
if(count($ret[$v]['list']) > MAX_LIKERS) {
$ret[$v]['list_part'] = array_slice($ret[$v]['list'], 0, MAX_LIKERS);
array_push($ret[$v]['list_part'], '<a href="#" data-toggle="modal" data-target="#' . $v . 'Modal-'
<?php
-/*
-html2bbcode.php
-Converter for HTML to BBCode
-Made by: ike@piratenpartei.de
-Originally made for the syncom project: http://wiki.piratenpartei.de/Syncom
- https://github.com/annando/Syncom
-*/
+/**
+ * @file include/html2bbcode.php
+ * @brief Converter for HTML to BBCode
+ *
+ * Made by: ike@piratenpartei.de
+ * Originally made for the syncom project: http://wiki.piratenpartei.de/Syncom
+ * https://github.com/annando/Syncom
+ */
+
+require_once("include/xml.php");
function node2bbcode(&$doc, $oldnode, $attributes, $startbb, $endbb)
{
return($replace);
}
-if(!function_exists('deletenode')) {
-function deletenode(&$doc, $node)
-{
- $xpath = new DomXPath($doc);
- $list = $xpath->query("//".$node);
- foreach ($list as $child)
- $child->parentNode->removeChild($child);
-}}
-
function _replace_code_cb($m){
return "<code>".str_replace("\n","<br>\n",$m[1]). "</code>";
}
@$doc->loadHTML($message);
- deletenode($doc, 'style');
- deletenode($doc, 'head');
- deletenode($doc, 'title');
- deletenode($doc, 'meta');
- deletenode($doc, 'xml');
- deletenode($doc, 'removeme');
+ xml::deleteNode($doc, 'style');
+ xml::deleteNode($doc, 'head');
+ xml::deleteNode($doc, 'title');
+ xml::deleteNode($doc, 'meta');
+ xml::deleteNode($doc, 'xml');
+ xml::deleteNode($doc, 'removeme');
$xpath = new DomXPath($doc);
$list = $xpath->query("//pre");
node2bbcode($doc, 'iframe', array('src'=>'/(.+)/'), '[iframe]$1', '[/iframe]');
node2bbcode($doc, 'code', array(), '[code]', '[/code]');
- node2bbcode($doc, 'key', array(), '[code]', '[/code]');
+ node2bbcode($doc, 'key', array(), '[code]', '[/code]');
$message = $doc->saveHTML();
<?php
+/**
+ * @file include/items.php
+ */
+
+use \Friendica\ParseUrl;
+
require_once('include/bbcode.php');
require_once('include/oembed.php');
require_once('include/salmon.php');
}
function query_page_info($url, $no_photos = false, $photo = "", $keywords = false, $keyword_blacklist = "") {
- require_once("mod/parse_url.php");
- $data = parseurl_getsiteinfo_cached($url, true);
+ $data = ParseUrl::getSiteinfoCached($url, true);
if ($photo != "")
$data["images"][0]["src"] = $photo;
<?php
+
+/**
+ * @file include/oembed.php
+ */
+
+use \Friendica\ParseUrl;
+use \Friendica\Core\Config;
+
function oembed_replacecb($matches){
$embedurl=$matches[1];
$j = oembed_fetch_url($embedurl);
$s = oembed_format_object($j);
+
return $s;
}
}
if ($txt==false || $txt=="") {
- $embedly = get_config("system", "embedly");
+ $embedly = Config::get("system", "embedly");
if ($embedly != "") {
// try embedly service
$ourl = "https://api.embed.ly/1/oembed?key=".$embedly."&url=".urlencode($embedurl);
// If fetching information doesn't work, then improve via internal functions
if (($j->type == "error") OR ($no_rich_type AND ($j->type == "rich"))) {
- require_once("mod/parse_url.php");
- $data = parseurl_getsiteinfo_cached($embedurl, true, false);
+ $data = ParseUrl::getSiteinfoCached($embedurl, true, false);
$j->type = $data["type"];
if ($j->type == "photo") {
function oembed_format_object($j){
require_once("mod/proxy.php");
- $a = get_app();
$embedurl = $j->embedurl;
$jhtml = oembed_iframe($j->embedurl,(isset($j->width) ? $j->width : null), (isset($j->height) ? $j->height : null) );
$ret="<span class='oembed ".$j->type."'>";
switch ($j->type) {
- case "video": {
+ case "video":
if (isset($j->thumbnail_url)) {
$tw = (isset($j->thumbnail_width) && intval($j->thumbnail_width)) ? $j->thumbnail_width:200;
$th = (isset($j->thumbnail_height) && intval($j->thumbnail_height)) ? $j->thumbnail_height:180;
$th=120; $tw = $th*$tr;
$tpl=get_markup_template('oembed_video.tpl');
$ret.=replace_macros($tpl, array(
- '$baseurl' => $a->get_baseurl(),
+ '$baseurl' => App::get_baseurl(),
'$embedurl'=>$embedurl,
'$escapedhtml'=>base64_encode($jhtml),
'$tw'=>$tw,
$ret=$jhtml;
}
//$ret.="<br>";
- }; break;
- case "photo": {
+ break;
+ case "photo":
$ret.= "<img width='".$j->width."' src='".proxy_url($j->url)."'>";
- }; break;
- case "link": {
- }; break;
- case "rich": {
+ break;
+ case "link":
+ break;
+ case "rich":
// not so safe..
- if (!get_config("system","no_oembed_rich_content"))
+ if (!Config::get("system","no_oembed_rich_content")) {
$ret.= proxy_parse_html($jhtml);
- }; break;
+ }
+ break;
}
// add link to source if not present in "rich" type
if ($j->type!='rich' || !strpos($j->html,$embedurl) ){
$ret .= "<h4>";
if (isset($j->title)) {
- if (isset($j->provider_name))
+ if (isset($j->provider_name)) {
$ret .= $j->provider_name.": ";
+ }
$embedlink = (isset($j->title))?$j->title:$embedurl;
$ret .= "<a href='$embedurl' rel='oembed'>$embedlink</a>";
- if (isset($j->author_name))
+ if (isset($j->author_name)) {
$ret.=" (".$j->author_name.")";
+ }
} elseif (isset($j->provider_name) OR isset($j->author_name)) {
$embedlink = "";
- if (isset($j->provider_name))
+ if (isset($j->provider_name)) {
$embedlink .= $j->provider_name;
+ }
if (isset($j->author_name)) {
- if ($embedlink != "")
+ if ($embedlink != "") {
$embedlink .= ": ";
+ }
$embedlink .= $j->author_name;
}
- if (trim($embedlink) == "")
+ if (trim($embedlink) == "") {
$embedlink = $embedurl;
+ }
$ret .= "<a href='$embedurl' rel='oembed'>$embedlink</a>";
}
}
$width = '100%';
- $a = get_app();
- $s = $a->get_baseurl() . '/oembed/'.base64url_encode($src);
+ $s = App::get_baseurl() . '/oembed/'.base64url_encode($src);
return '<iframe onload="resizeIframe(this);" class="embed_rich" height="' . $height . '" width="' . $width . '" src="' . $s . '" scrolling="no" frameborder="no">' . t('Embedded content') . '</iframe>';
}
function oembed_bbcode2html($text){
- $stopoembed = get_config("system","no_oembed");
+ $stopoembed = Config::get("system","no_oembed");
if ($stopoembed == true){
return preg_replace("/\[embed\](.+?)\[\/embed\]/is", "<!-- oembed $1 --><i>". t('Embedding disabled') ." : $1</i><!-- /oembed $1 -->" ,$text);
}
return "contains( normalize-space( @$attr ), ' $value ' ) or substring( normalize-space( @$attr ), 1, string-length( '$value' ) + 1 ) = '$value ' or substring( normalize-space( @$attr ), string-length( @$attr ) - string-length( '$value' ) ) = ' $value' or @$attr = '$value'";
}
-function oe_get_inner_html( $node ) {
- $innerHTML= '';
- $children = $node->childNodes;
- foreach ($children as $child) {
- $innerHTML .= $child->ownerDocument->saveXML( $child );
- }
- return $innerHTML;
+function oe_get_inner_html($node) {
+ $innerHTML= '';
+ $children = $node->childNodes;
+ foreach ($children as $child) {
+ $innerHTML .= $child->ownerDocument->saveXML($child);
+ }
+ return $innerHTML;
}
/**
*/
function oembed_html2bbcode($text) {
// start parser only if 'oembed' is in text
- if (strpos($text, "oembed")){
+ if (strpos($text, "oembed")) {
// convert non ascii chars to html entities
$html_text = mb_convert_encoding($text, 'HTML-ENTITIES', mb_detect_encoding($text));
// If it doesn't parse at all, just return the text.
$dom = @DOMDocument::loadHTML($html_text);
- if(! $dom)
+ if (! $dom) {
return $text;
+ }
$xpath = new DOMXPath($dom);
$attr = "oembed";
<?php
+/**
+ * @file include/plaintext.php
+ */
+
+use \Friendica\ParseUrl;
+
require_once("include/Photo.php");
+require_once("include/bbcode.php");
+require_once("include/html2plain.php");
+require_once("include/network.php");
/**
* @brief Fetches attachment data that were generated the old way
// if nothing is found, it maybe having an image.
if (!isset($post["type"])) {
- require_once("mod/parse_url.php");
- require_once("include/Photo.php");
-
$URLSearchString = "^\[\]";
if (preg_match_all("(\[url=([$URLSearchString]*)\]\s*\[img\]([$URLSearchString]*)\[\/img\]\s*\[\/url\])ism", $body, $pictures, PREG_SET_ORDER)) {
if (count($pictures) == 1) {
// Checking, if the link goes to a picture
- $data = parseurl_getsiteinfo_cached($pictures[0][1], true);
+ $data = ParseUrl::getSiteinfoCached($pictures[0][1], true);
// Workaround:
// Sometimes photo posts to the own album are not detected at the start.
// So we seem to cannot use the cache for these cases. That's strange.
if (($data["type"] != "photo") AND strstr($pictures[0][1], "/photos/"))
- $data = parseurl_getsiteinfo($pictures[0][1], true);
+ $data = ParseUrl::getSiteinfo($pictures[0][1], true);
if ($data["type"] == "photo") {
$post["type"] = "photo";
$post["text"] = trim($body);
}
} elseif (isset($post["url"]) AND ($post["type"] == "video")) {
- require_once("mod/parse_url.php");
- $data = parseurl_getsiteinfo_cached($post["url"], true);
+ $data = ParseUrl::getSiteinfoCached($post["url"], true);
if (isset($data["images"][0]))
$post["image"] = $data["images"][0]["src"];
* @return string The converted message
*/
function plaintext($a, $b, $limit = 0, $includedlinks = false, $htmlmode = 2, $target_network = "") {
- require_once("include/bbcode.php");
- require_once("include/html2plain.php");
- require_once("include/network.php");
// Remove the hash tags
$URLSearchString = "^\[\]";
require_once("boot.php");
-function poller_run(&$argv, &$argc){
+function poller_run($argv, $argc){
global $a, $db;
if(is_null($a)) {
$a->start_process();
- $mypid = getmypid();
-
if ($a->max_processes_reached())
return;
}
if(($argc <= 1) OR ($argv[1] != "no_cron")) {
- // Run the cron job that calls all other jobs
- proc_run(PRIORITY_MEDIUM, "include/cron.php");
-
- // Run the cronhooks job separately from cron for being able to use a different timing
- proc_run(PRIORITY_MEDIUM, "include/cronhooks.php");
-
- // Cleaning dead processes
- poller_kill_stale_workers();
+ poller_run_cron();
} else
// Sleep four seconds before checking for running processes again to avoid having too many workers
sleep(4);
if (poller_too_much_workers())
return;
- $cooldown = Config::get("system", "worker_cooldown", 0);
-
$starttime = time();
while ($r = poller_worker_process()) {
- // Quit when in maintenance
- if (get_config('system', 'maintenance', true))
+ // Count active workers and compare them with a maximum value that depends on the load
+ if (poller_too_much_workers()) {
return;
+ }
- // Constantly check the number of parallel database processes
- if ($a->max_processes_reached())
+ if (!poller_execute($r[0])) {
return;
+ }
- // Constantly check the number of available database connections to let the frontend be accessible at any time
- if (poller_max_connections_reached())
+ // Quit the poller once every hour
+ if (time() > ($starttime + 3600))
return;
+ }
- // Count active workers and compare them with a maximum value that depends on the load
- if (poller_too_much_workers())
- return;
+}
- $upd = q("UPDATE `workerqueue` SET `executed` = '%s', `pid` = %d WHERE `id` = %d AND `pid` = 0",
- dbesc(datetime_convert()),
- intval($mypid),
- intval($r[0]["id"]));
+/**
+ * @brief Execute a worker entry
+ *
+ * @param array $queue Workerqueue entry
+ *
+ * @return boolean "true" if further processing should be stopped
+ */
+function poller_execute($queue) {
- if (!$upd) {
- logger("Couldn't update queue entry ".$r[0]["id"]." - skip this execution", LOGGER_DEBUG);
- q("COMMIT");
- continue;
- }
+ $a = get_app();
- // Assure that there are no tasks executed twice
- $id = q("SELECT `pid`, `executed` FROM `workerqueue` WHERE `id` = %d", intval($r[0]["id"]));
- if (!$id) {
- logger("Queue item ".$r[0]["id"]." vanished - skip this execution", LOGGER_DEBUG);
- q("COMMIT");
- continue;
- } elseif ((strtotime($id[0]["executed"]) <= 0) OR ($id[0]["pid"] == 0)) {
- logger("Entry for queue item ".$r[0]["id"]." wasn't stored - skip this execution", LOGGER_DEBUG);
- q("COMMIT");
- continue;
- } elseif ($id[0]["pid"] != $mypid) {
- logger("Queue item ".$r[0]["id"]." is to be executed by process ".$id[0]["pid"]." and not by me (".$mypid.") - skip this execution", LOGGER_DEBUG);
- q("COMMIT");
- continue;
- }
+ $mypid = getmypid();
+
+ $cooldown = Config::get("system", "worker_cooldown", 0);
+
+ // Quit when in maintenance
+ if (get_config('system', 'maintenance', true)) {
+ return false;
+ }
+
+ // Constantly check the number of parallel database processes
+ if ($a->max_processes_reached()) {
+ return false;
+ }
+
+ // Constantly check the number of available database connections to let the frontend be accessible at any time
+ if (poller_max_connections_reached()) {
+ return false;
+ }
+
+ $upd = q("UPDATE `workerqueue` SET `executed` = '%s', `pid` = %d WHERE `id` = %d AND `pid` = 0",
+ dbesc(datetime_convert()),
+ intval($mypid),
+ intval($queue["id"]));
+
+ if (!$upd) {
+ logger("Couldn't update queue entry ".$queue["id"]." - skip this execution", LOGGER_DEBUG);
q("COMMIT");
+ return true;
+ }
- $argv = json_decode($r[0]["parameter"]);
+ // Assure that there are no tasks executed twice
+ $id = q("SELECT `pid`, `executed` FROM `workerqueue` WHERE `id` = %d", intval($queue["id"]));
+ if (!$id) {
+ logger("Queue item ".$queue["id"]." vanished - skip this execution", LOGGER_DEBUG);
+ q("COMMIT");
+ return true;
+ } elseif ((strtotime($id[0]["executed"]) <= 0) OR ($id[0]["pid"] == 0)) {
+ logger("Entry for queue item ".$queue["id"]." wasn't stored - skip this execution", LOGGER_DEBUG);
+ q("COMMIT");
+ return true;
+ } elseif ($id[0]["pid"] != $mypid) {
+ logger("Queue item ".$queue["id"]." is to be executed by process ".$id[0]["pid"]." and not by me (".$mypid.") - skip this execution", LOGGER_DEBUG);
+ q("COMMIT");
+ return true;
+ }
+ q("COMMIT");
- $argc = count($argv);
+ $argv = json_decode($queue["parameter"]);
- // Check for existance and validity of the include file
- $include = $argv[0];
+ $argc = count($argv);
- if (!validate_include($include)) {
- logger("Include file ".$argv[0]." is not valid!");
- q("DELETE FROM `workerqueue` WHERE `id` = %d", intval($r[0]["id"]));
- continue;
- }
+ // Check for existance and validity of the include file
+ $include = $argv[0];
- require_once($include);
+ if (!validate_include($include)) {
+ logger("Include file ".$argv[0]." is not valid!");
+ q("DELETE FROM `workerqueue` WHERE `id` = %d", intval($queue["id"]));
+ return true;
+ }
- $funcname = str_replace(".php", "", basename($argv[0]))."_run";
+ require_once($include);
- if (function_exists($funcname)) {
- logger("Process ".$mypid." - Prio ".$r[0]["priority"]." - ID ".$r[0]["id"].": ".$funcname." ".$r[0]["parameter"]);
+ $funcname = str_replace(".php", "", basename($argv[0]))."_run";
- // For better logging create a new process id for every worker call
- // But preserve the old one for the worker
- $old_process_id = $a->process_id;
- $a->process_id = uniqid("wrk", true);
+ if (function_exists($funcname)) {
+ logger("Process ".$mypid." - Prio ".$queue["priority"]." - ID ".$queue["id"].": ".$funcname." ".$queue["parameter"]);
- $funcname($argv, $argc);
+ // For better logging create a new process id for every worker call
+ // But preserve the old one for the worker
+ $old_process_id = $a->process_id;
+ $a->process_id = uniqid("wrk", true);
- $a->process_id = $old_process_id;
+ $funcname($argv, $argc);
- if ($cooldown > 0) {
- logger("Process ".$mypid." - Prio ".$r[0]["priority"]." - ID ".$r[0]["id"].": ".$funcname." - in cooldown for ".$cooldown." seconds");
- sleep($cooldown);
- }
+ $a->process_id = $old_process_id;
- logger("Process ".$mypid." - Prio ".$r[0]["priority"]." - ID ".$r[0]["id"].": ".$funcname." - done");
+ if ($cooldown > 0) {
+ logger("Process ".$mypid." - Prio ".$queue["priority"]." - ID ".$queue["id"].": ".$funcname." - in cooldown for ".$cooldown." seconds");
+ sleep($cooldown);
+ }
- q("DELETE FROM `workerqueue` WHERE `id` = %d", intval($r[0]["id"]));
- } else
- logger("Function ".$funcname." does not exist");
+ logger("Process ".$mypid." - Prio ".$queue["priority"]." - ID ".$queue["id"].": ".$funcname." - done");
- // Quit the poller once every hour
- if (time() > ($starttime + 3600))
- return;
+ q("DELETE FROM `workerqueue` WHERE `id` = %d", intval($queue["id"]));
+ } else {
+ logger("Function ".$funcname." does not exist");
}
+ return true;
}
/**
}
}
+/**
+ * @brief Checks if the number of active workers exceeds the given limits
+ *
+ * @return bool Are there too much workers running?
+ */
function poller_too_much_workers() {
return($active >= $queues);
}
+/**
+ * @brief Returns the number of active poller processes
+ *
+ * @return integer Number of active poller processes
+ */
function poller_active_workers() {
$workers = q("SELECT COUNT(*) AS `processes` FROM `process` WHERE `command` = 'poller.php'");
$r = q("SELECT `priority`
FROM `process`
- INNER JOIN `workerqueue` ON `workerqueue`.`pid` = `process`.`pid`
- WHERE `process`.`command` = 'poller.php'");
+ INNER JOIN `workerqueue` ON `workerqueue`.`pid` = `process`.`pid`");
// No active processes at all? Fine
if (!dbm::is_result($r))
*
* @return string SQL statement
*/
-
function poller_worker_process() {
q("START TRANSACTION;");
return $r;
}
+/**
+ * @brief Call the front end worker
+ */
+function call_worker() {
+ if (!get_config("system", "frontend_worker")) {
+ return;
+ }
+
+ $url = get_app()->get_baseurl()."/worker";
+ fetch_url($url, false, $redirects, 1);
+}
+
+/**
+ * @brief Call the front end worker if there aren't any active
+ */
+function call_worker_if_idle() {
+ if (!get_config("system", "frontend_worker")) {
+ return;
+ }
+
+ poller_run_cron();
+
+ clear_worker_processes();
+
+ $workers = q("SELECT COUNT(*) AS `processes` FROM `process` WHERE `command` = 'worker.php'");
+
+ if ($workers[0]["processes"] == 0) {
+ call_worker();
+ }
+}
+
+/**
+ * @brief Removes long running worker processes
+ */
+function clear_worker_processes() {
+ $timeout = Config::get("system", "frontend_worker_timeout", 10);
+
+ /// @todo We should clean up the corresponding workerqueue entries as well
+ q("DELETE FROM `process` WHERE `created` < '%s' AND `command` = 'worker.php'",
+ dbesc(datetime_convert('UTC','UTC',"now - ".$timeout." minutes")));
+}
+
+/**
+ * @brief Runs the cron processes
+ */
+function poller_run_cron() {
+ // Run the cron job that calls all other jobs
+ proc_run(PRIORITY_MEDIUM, "include/cron.php");
+
+ // Run the cronhooks job separately from cron for being able to use a different timing
+ proc_run(PRIORITY_MEDIUM, "include/cronhooks.php");
+
+ // Cleaning dead processes
+ poller_kill_stale_workers();
+}
+
if (array_search(__file__,get_included_files())===0){
poller_run($_SERVER["argv"],$_SERVER["argc"]);
--- /dev/null
+<?php
+/**
+ * @file include/remove_contact.php
+ * @brief Removes orphaned data from deleted contacts
+ */
+require_once("boot.php");
+
+function remove_contact_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);
+ }
+
+ load_config('config');
+ load_config('system');
+
+ if ($argc != 2) {
+ return;
+ }
+
+ $id = intval($argv[1]);
+
+ // Only delete if the contact doesn't exist (anymore)
+ $r = q("SELECT `id` FROM `contact` WHERE `id` = %d", intval($id));
+ if (dbm::is_result($r)) {
+ return;
+ }
+
+ q("DELETE FROM `item` WHERE `contact-id` = %d", intval($id));
+
+ q("DELETE FROM `photo` WHERE `contact-id` = %d", intval($id));
+
+ q("DELETE FROM `mail` WHERE `contact-id` = %d", intval($id));
+
+ q("DELETE FROM `event` WHERE `cid` = %d", intval($id));
+
+ q("DELETE FROM `queue` WHERE `cid` = %d", intval($id));
+}
+
+if (array_search(__file__, get_included_files()) === 0) {
+ remove_contact_run($_SERVER["argv"], $_SERVER["argc"]);
+ killme();
+}
+?>
<?php
+
/**
* @file include/xml.php
*/
/**
- * @brief This class contain functions to work with XML data
+ * @brief This class contain methods to work with XML data
*
*/
class xml {
public static function from_array($array, &$xml, $remove_header = false, $namespaces = array(), $root = true) {
if ($root) {
- foreach($array as $key => $value) {
- foreach ($namespaces AS $nskey => $nsvalue)
+ foreach ($array as $key => $value) {
+ foreach ($namespaces AS $nskey => $nsvalue) {
$key .= " xmlns".($nskey == "" ? "":":").$nskey.'="'.$nsvalue.'"';
+ }
if (is_array($value)) {
$root = new SimpleXMLElement("<".$key."/>");
self::from_array($value, $root, $remove_header, $namespaces, false);
- } else
+ } else {
$root = new SimpleXMLElement("<".$key.">".xmlify($value)."</".$key.">");
+ }
$dom = dom_import_simplexml($root)->ownerDocument;
$dom->formatOutput = true;
$xml_text = $dom->saveXML();
- if ($remove_header)
+ if ($remove_header) {
$xml_text = trim(substr($xml_text, 21));
+ }
return $xml_text;
}
}
foreach($array as $key => $value) {
- if (!isset($element) AND isset($xml))
+ if (!isset($element) AND isset($xml)) {
$element = $xml;
+ }
if (is_integer($key)) {
if (isset($element)) {
}
$element_parts = explode(":", $key);
- if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
+ if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]])) {
$namespace = $namespaces[$element_parts[0]];
- elseif (isset($namespaces[""])) {
+ } elseif (isset($namespaces[""])) {
$namespace = $namespaces[""];
- } else
+ } else {
$namespace = NULL;
+ }
// Remove undefined namespaces from the key
- if ((count($element_parts) > 1) AND is_null($namespace))
+ if ((count($element_parts) > 1) AND is_null($namespace)) {
$key = $element_parts[1];
+ }
if (substr($key, 0, 11) == "@attributes") {
- if (!isset($element) OR !is_array($value))
+ if (!isset($element) OR !is_array($value)) {
continue;
+ }
foreach ($value as $attr_key => $attr_value) {
$element_parts = explode(":", $attr_key);
- if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
+ if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]])) {
$namespace = $namespaces[$element_parts[0]];
- else
+ } else {
$namespace = NULL;
+ }
$element->addAttribute($attr_key, $attr_value, $namespace);
}
continue;
}
- if (!is_array($value))
+ if (!is_array($value)) {
$element = $xml->addChild($key, xmlify($value), $namespace);
- elseif (is_array($value)) {
+ } elseif (is_array($value)) {
$element = $xml->addChild($key, NULL, $namespace);
self::from_array($value, $element, $remove_header, $namespaces, false);
}
$target->addChild($elementname, xmlify($source));
else {
$child = $target->addChild($elementname);
- foreach ($source->children() AS $childfield => $childentry)
+ foreach ($source->children() AS $childfield => $childentry) {
self::copy($childentry, $child, $childfield);
+ }
}
}
return(null);
}
- if (!is_string($xml_element) &&
- !is_array($xml_element) &&
- (get_class($xml_element) == 'SimpleXMLElement')) {
- $xml_element_copy = $xml_element;
- $xml_element = get_object_vars($xml_element);
+ if (!is_string($xml_element)
+ && !is_array($xml_element)
+ && (get_class($xml_element) == 'SimpleXMLElement')) {
+ $xml_element_copy = $xml_element;
+ $xml_element = get_object_vars($xml_element);
}
if (is_array($xml_element)) {
return (trim(strval($xml_element_copy)));
}
- foreach($xml_element as $key=>$value) {
+ foreach ($xml_element as $key => $value) {
$recursion_depth++;
$result_array[strtolower($key)] =
*
* @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') {
- if(!$contents) return array();
+ public static function to_array($contents, $namespaces = true, $get_attributes = 1, $priority = 'attribute') {
+ if (!$contents) {
+ return array();
+ }
- if(!function_exists('xml_parser_create')) {
+ if (!function_exists('xml_parser_create')) {
logger('xml::to_array: parser function missing');
return array();
}
libxml_use_internal_errors(true);
libxml_clear_errors();
- if($namespaces)
+ if ($namespaces) {
$parser = @xml_parser_create_ns("UTF-8",':');
- else
+ } else {
$parser = @xml_parser_create();
+ }
- if(! $parser) {
+ if (! $parser) {
logger('xml::to_array: xml_parser_create: no resource');
return array();
}
@xml_parse_into_struct($parser, trim($contents), $xml_values);
@xml_parser_free($parser);
- if(! $xml_values) {
+ if (! $xml_values) {
logger('xml::to_array: libxml: parse error: ' . $contents, LOGGER_DATA);
- foreach(libxml_get_errors() as $err)
+ foreach (libxml_get_errors() as $err) {
logger('libxml: parse: ' . $err->code . " at " . $err->line . ":" . $err->column . " : " . $err->message, LOGGER_DATA);
+ }
libxml_clear_errors();
return;
}
// Go through the tags.
$repeated_tag_index = array(); // Multiple tags with same name will be turned into an array
- foreach($xml_values as $data) {
- unset($attributes,$value); // Remove existing values, or there will be trouble
+ foreach ($xml_values as $data) {
+ unset($attributes, $value); // Remove existing values, or there will be trouble
// This command will extract these variables into the foreach scope
// tag(string), type(string), level(int), attributes(array).
$result = array();
$attributes_data = array();
- if(isset($value)) {
- if($priority == 'tag') $result = $value;
- else $result['value'] = $value; // Put the value in a assoc array if we are in the 'Attribute' mode
+ if (isset($value)) {
+ if ($priority == 'tag') {
+ $result = $value;
+ } else {
+ $result['value'] = $value; // Put the value in a assoc array if we are in the 'Attribute' mode
+ }
}
//Set the attributes too.
- if(isset($attributes) and $get_attributes) {
- foreach($attributes as $attr => $val) {
- if($priority == 'tag') $attributes_data[$attr] = $val;
- else $result['@attributes'][$attr] = $val; // Set all the attributes in a array called 'attr'
+ if (isset($attributes) and $get_attributes) {
+ foreach ($attributes as $attr => $val) {
+ if($priority == 'tag') {
+ $attributes_data[$attr] = $val;
+ } else {
+ $result['@attributes'][$attr] = $val; // Set all the attributes in a array called 'attr'
+ }
}
}
// See tag status and do the needed.
- if($namespaces && strpos($tag,':')) {
- $namespc = substr($tag,0,strrpos($tag,':'));
- $tag = strtolower(substr($tag,strlen($namespc)+1));
+ if ($namespaces && strpos($tag, ':')) {
+ $namespc = substr($tag, 0, strrpos($tag, ':'));
+ $tag = strtolower(substr($tag, strlen($namespc)+1));
$result['@namespace'] = $namespc;
}
$tag = strtolower($tag);
- if($type == "open") { // The starting of the tag '<tag>'
+ if ($type == "open") { // The starting of the tag '<tag>'
$parent[$level-1] = &$current;
- if(!is_array($current) or (!in_array($tag, array_keys($current)))) { // Insert New tag
+ if (!is_array($current) or (!in_array($tag, array_keys($current)))) { // Insert New tag
$current[$tag] = $result;
- if($attributes_data) $current[$tag. '_attr'] = $attributes_data;
+ if ($attributes_data) {
+ $current[$tag. '_attr'] = $attributes_data;
+ }
$repeated_tag_index[$tag.'_'.$level] = 1;
$current = &$current[$tag];
} else { // There was another element with the same tag name
- if(isset($current[$tag][0])) { // If there is a 0th element it is already an array
+ if (isset($current[$tag][0])) { // If there is a 0th element it is already an array
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
$repeated_tag_index[$tag.'_'.$level]++;
} else { // This section will make the value an array if multiple tags with the same name appear together
- $current[$tag] = array($current[$tag],$result); // This will combine the existing item and the new item together to make an array
+ $current[$tag] = array($current[$tag], $result); // This will combine the existing item and the new item together to make an array
$repeated_tag_index[$tag.'_'.$level] = 2;
- if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
+ if (isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
unset($current[$tag.'_attr']);
}
$current = &$current[$tag][$last_item_index];
}
- } elseif($type == "complete") { // Tags that ends in 1 line '<tag />'
+ } elseif ($type == "complete") { // Tags that ends in 1 line '<tag />'
//See if the key is already taken.
- if(!isset($current[$tag])) { //New Key
+ if (!isset($current[$tag])) { //New Key
$current[$tag] = $result;
$repeated_tag_index[$tag.'_'.$level] = 1;
- if($priority == 'tag' and $attributes_data) $current[$tag. '_attr'] = $attributes_data;
+ if ($priority == 'tag' and $attributes_data) {
+ $current[$tag. '_attr'] = $attributes_data;
+ }
} else { // If taken, put all things inside a list(array)
- if(isset($current[$tag][0]) and is_array($current[$tag])) { // If it is already an array...
+ if (isset($current[$tag][0]) and is_array($current[$tag])) { // If it is already an array...
// ...push the new element into that array.
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
- if($priority == 'tag' and $get_attributes and $attributes_data) {
+ if ($priority == 'tag' and $get_attributes and $attributes_data) {
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
}
$repeated_tag_index[$tag.'_'.$level]++;
} else { // If it is not an array...
- $current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value
+ $current[$tag] = array($current[$tag], $result); //...Make it an array using using the existing value and the new value
$repeated_tag_index[$tag.'_'.$level] = 1;
- if($priority == 'tag' and $get_attributes) {
- if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
+ if ($priority == 'tag' and $get_attributes) {
+ if (isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
unset($current[$tag.'_attr']);
}
- if($attributes_data) {
+ if ($attributes_data) {
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
}
}
}
}
- } elseif($type == 'close') { // End of tag '</tag>'
+ } elseif ($type == 'close') { // End of tag '</tag>'
$current = &$parent[$level-1];
}
}
return($xml_array);
}
+
+ /**
+ * @brief Delete a node in a XML object
+ *
+ * @param object $doc XML document
+ * @param string $node Node name
+ */
+ public static function deleteNode(&$doc, $node) {
+ $xpath = new DomXPath($doc);
+ $list = $xpath->query("//".$node);
+ foreach ($list as $child) {
+ $child->parentNode->removeChild($child);
+ }
+ }
}
-?>
$stamp1 = microtime(true);
session_start();
$a->save_timestamp($stamp1, "parser");
+} else {
+ require_once "include/poller.php";
+
+ call_worker_if_idle();
}
/**
/* event from comment textarea button popups */
/* insert returned bbcode at cursor position or replace selected text */
$("body").on("fbrowser.image.comment", function(e, filename, bbcode, id) {
- console.log("on", id);
$.colorbox.close();
var textarea = document.getElementById("comment-edit-text-" +id);
var start = textarea.selectionStart;
$("#"+id+"_onoff ."+ (val==0?"on":"off")).addClass("hidden");
$("#"+id+"_onoff ."+ (val==1?"on":"off")).removeClass("hidden");
input.val(val);
- //console.log(id);
});
/* setup field_richtext */
$("#nav-notifications-linkmenu").removeClass("on");
}
- console.log(data.sysmsgs);
-
$(data.sysmsgs.notice).each(function(key, message){
$.jGrowl(message, {sticky: true, theme: 'notice'});
});
// page number
infinite_scroll.pageno+=1;
- console.log('Loading page ' + infinite_scroll.pageno);
-
// get the raw content from the next page and insert this content
// right before "#conversation-end"
$.get('network?mode=raw' + infinite_scroll.reload_uri + '&page=' + infinite_scroll.pageno, function(data) {
<?php
/**
- *
- * Module: dfrn_request
+ * @file mod/dfrn_request.php
+ * @brief Module: dfrn_request
*
* Purpose: Handles communication associated with the issuance of
* friend requests.
*
+ * @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/master/spec/dfrn2.pdf
*/
require_once('include/enotify.php');
require_once('include/Probe.php');
require_once('include/group.php');
-if(! function_exists('dfrn_request_init')) {
function dfrn_request_init(&$a) {
if($a->argc > 1)
profile_load($a,$which);
return;
-}}
+}
/**
* After logging in, we click 'submit' to approve the linkage.
*
*/
-
-if(! function_exists('dfrn_request_post')) {
function dfrn_request_post(&$a) {
if(($a->argc != 2) || (! count($a->profile))) {
}
- /**
+ /*
*
* Scenario 2: We've introduced ourself to another cell, then have been returned to our own cell
* to confirm the request, and then we've clicked submit (perhaps after logging in).
if((x($_POST,'localconfirm')) && ($_POST['localconfirm'] == 1)) {
- /**
+ /*
* Ensure this is a valid request
*/
$confirm_key = ((x($_POST,'confirm_key')) ? $_POST['confirm_key'] : "");
$hidden = ((x($_POST,'hidden-contact')) ? intval($_POST['hidden-contact']) : 0);
$contact_record = null;
+ $blocked = 1;
+ $pending = 1;
if(x($dfrn_url)) {
- /**
+ /*
* Lookup the contact based on their URL (which is the only unique thing we have at the moment)
*/
- $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND (`url` = '%s' OR `nurl` = '%s') AND `self` = 0 LIMIT 1",
+ $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `nurl` = '%s' AND NOT `self` LIMIT 1",
intval(local_user()),
- dbesc($dfrn_url),
dbesc(normalise_link($dfrn_url))
);
if(count($r)) {
if(strlen($r[0]['dfrn-id'])) {
- /**
+ /*
* We don't need to be here. It has already happened.
*/
}
else {
- /**
+ /*
* Scrape the other site's profile page to pick up the dfrn links, key, fn, and photo
*/
$photo = $parms["photo"];
- /********* Escape the entire array ********/
+ // Escape the entire array
dbesc_array($parms);
- /******************************************/
- /**
+ /*
* Create a contact record on our site for the other person
*/
$r = q("INSERT INTO `contact` ( `uid`, `created`,`url`, `nurl`, `addr`, `name`, `nick`, `photo`, `site-pubkey`,
- `request`, `confirm`, `notify`, `poll`, `poco`, `network`, `aes_allow`, `hidden`)
- VALUES ( %d, '%s', '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)",
+ `request`, `confirm`, `notify`, `poll`, `poco`, `network`, `aes_allow`, `hidden`, `blocked`, `pending`)
+ VALUES ( %d, '%s', '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d)",
intval(local_user()),
datetime_convert(),
dbesc($dfrn_url),
$parms['dfrn-poco'],
dbesc(NETWORK_DFRN),
intval($aes_allow),
- intval($hidden)
+ intval($hidden),
+ intval($blocked),
+ intval($pending)
);
}
} else
$forwardurl = $a->get_baseurl()."/contacts";
- /**
+ /*
* Allow the blocked remote notification to complete
*/
return; // NOTREACHED
}
- /**
+ /*
* Otherwise:
*
* Scenario 1:
$contact_record = null;
$failed = false;
$parms = null;
+ $blocked = 1;
+ $pending = 1;
if( x($_POST,'dfrn_url')) {
- /**
+ /*
* Block friend request spam
*/
}
}
- /**
+ /*
*
* Cleanup old introductions that remain blocked.
* Also remove the contact record, but only if there is no existing relationship
}
}
- /**
+ /*
*
* Cleanup any old email intros - which will have a greater lifetime
*/
$nurl = normalise_url($host);
$poll = 'email ' . random_string();
$notify = 'smtp ' . random_string();
- $blocked = 1;
- $pending = 1;
$network = NETWORK_MAIL2;
$rel = CONTACT_IS_FOLLOWER;
dbesc_array($parms);
$r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `name`, `nick`, `issued-id`, `photo`, `site-pubkey`,
- `request`, `confirm`, `notify`, `poll`, `poco`, `network` )
- VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' )",
+ `request`, `confirm`, `notify`, `poll`, `poco`, `network`, `blocked`, `pending` )
+ VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )",
intval($uid),
dbesc(datetime_convert()),
$parms['url'],
$parms['dfrn-notify'],
$parms['dfrn-poll'],
$parms['dfrn-poco'],
- dbesc(NETWORK_DFRN)
+ dbesc(NETWORK_DFRN),
+ intval($blocked),
+ intval($pending)
);
// find the contact record we just created
// END $network === NETWORK_DFRN
} elseif (($network != NETWORK_PHANTOM) AND ($url != "")) {
- /**
+ /*
*
* Substitute our user's feed URL into $url template
* Send the subscriber home to subscribe
}
} return;
-}}
-
-
+}
-if(! function_exists('dfrn_request_content')) {
function dfrn_request_content(&$a) {
if(($a->argc != 2) || (! count($a->profile)))
}
else {
- /**
+ /*
* Normal web request. Display our user's introduction form.
*/
}
- /**
+ /*
* Try to auto-fill the profile address
*/
$target_addr = $a->profile['nickname'] . '@' . substr(z_root(), strpos(z_root(),'://') + 3 );
- /**
+ /*
*
* The auto_request form only has the profile address
* because nobody is going to read the comments and
}
return; // Somebody is fishing.
-}}
+}
<?php
+
/**
* @file mod/parse_url.php
+ * @brief The parse_url module
*
- * @todo https://developers.google.com/+/plugins/snippet/
- *
- * @verbatim
- * <meta itemprop="name" content="Toller Titel">
- * <meta itemprop="description" content="Eine tolle Beschreibung">
- * <meta itemprop="image" content="http://maple.libertreeproject.org/images/tree-icon.png">
+ * This module does parse an url for embedable content (audio, video, image files or link)
+ * information and does format this information to BBCode or html (this depends
+ * on the user settings - default is BBCode output).
+ * If the user has enabled the richtext editor setting the output will be in html
+ * (Note: This is not always possible and in some case not useful because
+ * the richtext editor doesn't support all kind of html).
+ * Otherwise the output will be constructed BBCode.
*
- * <body itemscope itemtype="http://schema.org/Product">
- * <h1 itemprop="name">Shiny Trinket</h1>
- * <img itemprop="image" src="{image-url}" />
- * <p itemprop="description">Shiny trinkets are shiny.</p>
- * </body>
- * @endverbatim
+ * @see ParseUrl::getSiteinfo() for more information about scraping embeddable content
*/
-if(!function_exists('deletenode')) {
- function deletenode(&$doc, $node)
- {
- $xpath = new DomXPath($doc);
- $list = $xpath->query("//".$node);
- foreach ($list as $child)
- $child->parentNode->removeChild($child);
- }
-}
-
-function completeurl($url, $scheme) {
- $urlarr = parse_url($url);
-
- if (isset($urlarr["scheme"]))
- return($url);
-
- $schemearr = parse_url($scheme);
-
- $complete = $schemearr["scheme"]."://".$schemearr["host"];
-
- if (@$schemearr["port"] != "")
- $complete .= ":".$schemearr["port"];
-
- if(strpos($urlarr['path'],'/') !== 0)
- $complete .= '/';
-
- $complete .= $urlarr["path"];
-
- if (@$urlarr["query"] != "")
- $complete .= "?".$urlarr["query"];
-
- if (@$urlarr["fragment"] != "")
- $complete .= "#".$urlarr["fragment"];
-
- return($complete);
-}
+use \Friendica\ParseUrl;
-function parseurl_getsiteinfo_cached($url, $no_guessing = false, $do_oembed = true) {
+require_once("include/items.php");
- if ($url == "")
- return false;
+function parse_url_content(&$a) {
- $r = q("SELECT * FROM `parsed_url` WHERE `url` = '%s' AND `guessing` = %d AND `oembed` = %d",
- dbesc(normalise_link($url)), intval(!$no_guessing), intval($do_oembed));
+ $text = null;
+ $str_tags = "";
- if ($r)
- $data = $r[0]["content"];
+ $textmode = false;
- if (!is_null($data)) {
- $data = unserialize($data);
- return $data;
+ if (local_user() && (!feature_enabled(local_user(), "richtext"))) {
+ $textmode = true;
}
- $data = parseurl_getsiteinfo($url, $no_guessing, $do_oembed);
-
- q("INSERT INTO `parsed_url` (`url`, `guessing`, `oembed`, `content`, `created`) VALUES ('%s', %d, %d, '%s', '%s')
- ON DUPLICATE KEY UPDATE `content` = '%s', `created` = '%s'",
- dbesc(normalise_link($url)), intval(!$no_guessing), intval($do_oembed),
- dbesc(serialize($data)), dbesc(datetime_convert()),
- dbesc(serialize($data)), dbesc(datetime_convert()));
+ $br = (($textmode) ? "\n" : "<br />");
- return $data;
-}
-
-function parseurl_getsiteinfo($url, $no_guessing = false, $do_oembed = true, $count = 1) {
- require_once("include/network.php");
- require_once("include/Photo.php");
-
- $a = get_app();
-
- $siteinfo = array();
-
- // Check if the URL does contain a scheme
- $scheme = parse_url($url, PHP_URL_SCHEME);
-
- if ($scheme == "") {
- $url = "http://".trim($url, "/");
+ if (x($_GET,"binurl")) {
+ $url = trim(hex2bin($_GET["binurl"]));
+ } else {
+ $url = trim($_GET["url"]);
}
- if ($count > 10) {
- logger("parseurl_getsiteinfo: Endless loop detected for ".$url, LOGGER_DEBUG);
- return($siteinfo);
+ if ($_GET["title"]) {
+ $title = strip_tags(trim($_GET["title"]));
}
- $url = trim($url, "'");
- $url = trim($url, '"');
-
- $url = original_url($url);
-
- $siteinfo["url"] = $url;
- $siteinfo["type"] = "link";
-
- $check_cert = get_config('system','verifyssl');
-
- $stamp1 = microtime(true);
-
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_HEADER, 1);
- curl_setopt($ch, CURLOPT_NOBODY, 1);
- curl_setopt($ch, CURLOPT_TIMEOUT, 3);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_USERAGENT, $a->get_useragent());
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, (($check_cert) ? 2 : false));
-
- $header = curl_exec($ch);
- $curl_info = @curl_getinfo($ch);
- $http_code = $curl_info['http_code'];
- curl_close($ch);
-
- $a->save_timestamp($stamp1, "network");
-
- if ((($curl_info['http_code'] == "301") OR ($curl_info['http_code'] == "302") OR ($curl_info['http_code'] == "303") OR ($curl_info['http_code'] == "307"))
- AND (($curl_info['redirect_url'] != "") OR ($curl_info['location'] != ""))) {
- if ($curl_info['redirect_url'] != "")
- $siteinfo = parseurl_getsiteinfo($curl_info['redirect_url'], $no_guessing, $do_oembed, ++$count);
- else
- $siteinfo = parseurl_getsiteinfo($curl_info['location'], $no_guessing, $do_oembed, ++$count);
- return($siteinfo);
+ if ($_GET["description"]) {
+ $text = strip_tags(trim($_GET["description"]));
}
- // if the file is too large then exit
- if ($curl_info["download_content_length"] > 1000000)
- return($siteinfo);
-
- // if it isn't a HTML file then exit
- if (($curl_info["content_type"] != "") AND !strstr(strtolower($curl_info["content_type"]),"html"))
- return($siteinfo);
-
- if ($do_oembed) {
- require_once("include/oembed.php");
-
- $oembed_data = oembed_fetch_url($url);
-
- if (!in_array($oembed_data->type, array("error", "rich"))) {
- $siteinfo["type"] = $oembed_data->type;
- }
-
- if (($oembed_data->type == "link") AND ($siteinfo["type"] != "photo")) {
- if (isset($oembed_data->title))
- $siteinfo["title"] = $oembed_data->title;
- if (isset($oembed_data->description))
- $siteinfo["text"] = trim($oembed_data->description);
- if (isset($oembed_data->thumbnail_url))
- $siteinfo["image"] = $oembed_data->thumbnail_url;
+ if ($_GET["tags"]) {
+ $arr_tags = ParseUrl::convertTagsToArray($_GET["tags"]);
+ if (count($arr_tags)) {
+ $str_tags = $br . implode(" ", $arr_tags) . $br;
}
}
- $stamp1 = microtime(true);
-
- // Now fetch the body as well
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_HEADER, 1);
- curl_setopt($ch, CURLOPT_NOBODY, 0);
- curl_setopt($ch, CURLOPT_TIMEOUT, 10);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_USERAGENT, $a->get_useragent());
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, (($check_cert) ? 2 : false));
-
- $header = curl_exec($ch);
- $curl_info = @curl_getinfo($ch);
- $http_code = $curl_info['http_code'];
- curl_close($ch);
-
- $a->save_timestamp($stamp1, "network");
-
- // Fetch the first mentioned charset. Can be in body or header
- $charset = "";
- if (preg_match('/charset=(.*?)['."'".'"\s\n]/', $header, $matches))
- $charset = trim(trim(trim(array_pop($matches)), ';,'));
-
- if ($charset == "")
- $charset = "utf-8";
-
- $pos = strpos($header, "\r\n\r\n");
-
- if ($pos)
- $body = trim(substr($header, $pos));
- else
- $body = $header;
-
- if (($charset != '') AND (strtoupper($charset) != "UTF-8")) {
- logger("parseurl_getsiteinfo: detected charset ".$charset, LOGGER_DEBUG);
- //$body = mb_convert_encoding($body, "UTF-8", $charset);
- $body = iconv($charset, "UTF-8//TRANSLIT", $body);
- }
-
- $body = mb_convert_encoding($body, 'HTML-ENTITIES', "UTF-8");
-
- $doc = new DOMDocument();
- @$doc->loadHTML($body);
-
- deletenode($doc, 'style');
- deletenode($doc, 'script');
- deletenode($doc, 'option');
- deletenode($doc, 'h1');
- deletenode($doc, 'h2');
- deletenode($doc, 'h3');
- deletenode($doc, 'h4');
- deletenode($doc, 'h5');
- deletenode($doc, 'h6');
- deletenode($doc, 'ol');
- deletenode($doc, 'ul');
-
- $xpath = new DomXPath($doc);
-
- $list = $xpath->query("//meta[@content]");
- foreach ($list as $node) {
- $attr = array();
- if ($node->attributes->length)
- foreach ($node->attributes as $attribute)
- $attr[$attribute->name] = $attribute->value;
-
- if (@$attr["http-equiv"] == 'refresh') {
- $path = $attr["content"];
- $pathinfo = explode(";", $path);
- $content = "";
- foreach ($pathinfo AS $value) {
- if (substr(strtolower($value), 0, 4) == "url=")
- $content = substr($value, 4);
- }
- if ($content != "") {
- $siteinfo = parseurl_getsiteinfo($content, $no_guessing, $do_oembed, ++$count);
- return($siteinfo);
- }
+ // Add url scheme if it is missing
+ $arrurl = parse_url($url);
+ if (!x($arrurl, "scheme")) {
+ if (x($arrurl, "host")) {
+ $url = "http:".$url;
+ } else {
+ $url = "http://".$url;
}
}
- $list = $xpath->query("//title");
- if ($list->length > 0)
- $siteinfo["title"] = $list->item(0)->nodeValue;
-
- //$list = $xpath->query("head/meta[@name]");
- $list = $xpath->query("//meta[@name]");
- foreach ($list as $node) {
- $attr = array();
- if ($node->attributes->length)
- foreach ($node->attributes as $attribute)
- $attr[$attribute->name] = $attribute->value;
-
- $attr["content"] = trim(html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8"));
-
- if ($attr["content"] != "")
- switch (strtolower($attr["name"])) {
- case "fulltitle":
- $siteinfo["title"] = $attr["content"];
- break;
- case "description":
- $siteinfo["text"] = $attr["content"];
- break;
- case "thumbnail":
- $siteinfo["image"] = $attr["content"];
- break;
- case "twitter:image":
- $siteinfo["image"] = $attr["content"];
- break;
- case "twitter:image:src":
- $siteinfo["image"] = $attr["content"];
- break;
- case "twitter:card":
- if (($siteinfo["type"] == "") OR ($attr["content"] == "photo"))
- $siteinfo["type"] = $attr["content"];
- break;
- case "twitter:description":
- $siteinfo["text"] = $attr["content"];
- break;
- case "twitter:title":
- $siteinfo["title"] = $attr["content"];
- break;
- case "dc.title":
- $siteinfo["title"] = $attr["content"];
- break;
- case "dc.description":
- $siteinfo["text"] = $attr["content"];
- break;
- case "keywords":
- $keywords = explode(",", $attr["content"]);
- break;
- case "news_keywords":
- $keywords = explode(",", $attr["content"]);
- break;
+ logger("prse_url: " . $url);
+
+ // Check if the URL is an image, video or audio file. If so format
+ // the URL with the corresponding BBCode media tag
+ $redirects = 0;
+ // Fetch the header of the URL
+ $result = z_fetch_url($url, false, $redirects, array("novalidate" => true, "nobody" => true));
+ if($result["success"]) {
+ // Convert the header fields into an array
+ $hdrs = array();
+ $h = explode("\n", $result["header"]);
+ foreach ($h as $l) {
+ list($k,$v) = array_map("trim", explode(":", trim($l), 2));
+ $hdrs[$k] = $v;
+ }
+ if (array_key_exists("Content-Type", $hdrs)) {
+ $type = $hdrs["Content-Type"];
+ }
+ if ($type) {
+ if(stripos($type, "image/") !== false) {
+ echo $br . "[img]" . $url . "[/img]" . $br;
+ killme();
}
- if ($siteinfo["type"] == "summary")
- $siteinfo["type"] = "link";
- }
-
- if (isset($keywords)) {
- $siteinfo["keywords"] = array();
- foreach ($keywords as $keyword)
- if (!in_array(trim($keyword), $siteinfo["keywords"]))
- $siteinfo["keywords"][] = trim($keyword);
- }
-
- //$list = $xpath->query("head/meta[@property]");
- $list = $xpath->query("//meta[@property]");
- foreach ($list as $node) {
- $attr = array();
- if ($node->attributes->length)
- foreach ($node->attributes as $attribute)
- $attr[$attribute->name] = $attribute->value;
-
- $attr["content"] = trim(html_entity_decode($attr["content"], ENT_QUOTES, "UTF-8"));
-
- if ($attr["content"] != "")
- switch (strtolower($attr["property"])) {
- case "og:image":
- $siteinfo["image"] = $attr["content"];
- break;
- case "og:title":
- $siteinfo["title"] = $attr["content"];
- break;
- case "og:description":
- $siteinfo["text"] = $attr["content"];
- break;
+ if (stripos($type, "video/") !== false) {
+ echo $br . "[video]" . $url . "[/video]" . $br;
+ killme();
}
- }
-
- if ((@$siteinfo["image"] == "") AND !$no_guessing) {
- $list = $xpath->query("//img[@src]");
- foreach ($list as $node) {
- $attr = array();
- if ($node->attributes->length)
- foreach ($node->attributes as $attribute)
- $attr[$attribute->name] = $attribute->value;
-
- $src = completeurl($attr["src"], $url);
- $photodata = get_photo_info($src);
-
- if (($photodata) && ($photodata[0] > 150) and ($photodata[1] > 150)) {
- if ($photodata[0] > 300) {
- $photodata[1] = round($photodata[1] * (300 / $photodata[0]));
- $photodata[0] = 300;
- }
- if ($photodata[1] > 300) {
- $photodata[0] = round($photodata[0] * (300 / $photodata[1]));
- $photodata[1] = 300;
- }
- $siteinfo["images"][] = array("src"=>$src,
- "width"=>$photodata[0],
- "height"=>$photodata[1]);
+ if (stripos($type, "audio/") !== false) {
+ echo $br . "[audio]" . $url . "[/audio]" . $br;
+ killme();
}
-
- }
- } elseif ($siteinfo["image"] != "") {
- $src = completeurl($siteinfo["image"], $url);
-
- unset($siteinfo["image"]);
-
- $photodata = get_photo_info($src);
-
- if (($photodata) && ($photodata[0] > 10) and ($photodata[1] > 10))
- $siteinfo["images"][] = array("src"=>$src,
- "width"=>$photodata[0],
- "height"=>$photodata[1]);
- }
-
- if ((@$siteinfo["text"] == "") AND (@$siteinfo["title"] != "") AND !$no_guessing) {
- $text = "";
-
- $list = $xpath->query("//div[@class='article']");
- foreach ($list as $node)
- if (strlen($node->nodeValue) > 40)
- $text .= " ".trim($node->nodeValue);
-
- if ($text == "") {
- $list = $xpath->query("//div[@class='content']");
- foreach ($list as $node)
- if (strlen($node->nodeValue) > 40)
- $text .= " ".trim($node->nodeValue);
- }
-
- // If none text was found then take the paragraph content
- if ($text == "") {
- $list = $xpath->query("//p");
- foreach ($list as $node)
- if (strlen($node->nodeValue) > 40)
- $text .= " ".trim($node->nodeValue);
- }
-
- if ($text != "") {
- $text = trim(str_replace(array("\n", "\r"), array(" ", " "), $text));
-
- while (strpos($text, " "))
- $text = trim(str_replace(" ", " ", $text));
-
- $siteinfo["text"] = trim(html_entity_decode(substr($text,0,350), ENT_QUOTES, "UTF-8").'...');
}
}
- logger("parseurl_getsiteinfo: Siteinfo for ".$url." ".print_r($siteinfo, true), LOGGER_DEBUG);
-
- call_hooks('getsiteinfo', $siteinfo);
-
- return($siteinfo);
-}
-
-function arr_add_hashes(&$item,$k) {
- $item = '#' . $item;
-}
-
-function parse_url_content(&$a) {
-
- require_once("include/items.php");
-
- $text = null;
- $str_tags = '';
-
- $textmode = false;
-
- if(local_user() && (! feature_enabled(local_user(),'richtext')))
- $textmode = true;
-
- //if($textmode)
- $br = (($textmode) ? "\n" : '<br />');
-
- if(x($_GET,'binurl'))
- $url = trim(hex2bin($_GET['binurl']));
- else
- $url = trim($_GET['url']);
-
- if($_GET['title'])
- $title = strip_tags(trim($_GET['title']));
-
- if($_GET['description'])
- $text = strip_tags(trim($_GET['description']));
-
- if($_GET['tags']) {
- $arr_tags = str_getcsv($_GET['tags']);
- if(count($arr_tags)) {
- array_walk($arr_tags,'arr_add_hashes');
- $str_tags = $br . implode(' ',$arr_tags) . $br;
- }
- }
-
- // add url scheme if missing
- $arrurl = parse_url($url);
- if (!x($arrurl, 'scheme')) {
- if (x($arrurl, 'host'))
- $url = "http:".$url;
- else
- $url = "http://".$url;
- }
-
- logger('parse_url: ' . $url);
-
- if($textmode)
- $template = '[bookmark=%s]%s[/bookmark]%s';
- else
+ if ($textmode) {
+ $template = "[bookmark=%s]%s[/bookmark]%s";
+ } else {
$template = "<a class=\"bookmark\" href=\"%s\" >%s</a>%s";
+ }
- $arr = array('url' => $url, 'text' => '');
+ $arr = array("url" => $url, "text" => "");
- call_hooks('parse_link', $arr);
+ call_hooks("parse_link", $arr);
- if(strlen($arr['text'])) {
- echo $arr['text'];
+ if (strlen($arr["text"])) {
+ echo $arr["text"];
killme();
}
+ // If there is allready some content information submitted we don't
+ // need to parse the url for content.
+ if ($url && $title && $text) {
- if($url && $title && $text) {
-
- $title = str_replace(array("\r","\n"),array('',''),$title);
+ $title = str_replace(array("\r","\n"),array("",""),$title);
- if($textmode)
- $text = '[quote]' . trim($text) . '[/quote]' . $br;
- else {
- $text = '<blockquote>' . htmlspecialchars(trim($text)) . '</blockquote><br />';
+ if ($textmode) {
+ $text = "[quote]" . trim($text) . "[/quote]" . $br;
+ } else {
+ $text = "<blockquote>" . htmlspecialchars(trim($text)) . "</blockquote><br />";
$title = htmlspecialchars($title);
}
- $result = sprintf($template,$url,($title) ? $title : $url,$text) . $str_tags;
+ $result = sprintf($template, $url, ($title) ? $title : $url, $text) . $str_tags;
- logger('parse_url (unparsed): returns: ' . $result);
+ logger("parse_url (unparsed): returns: " . $result);
echo $result;
killme();
}
- $siteinfo = parseurl_getsiteinfo($url);
+ // Fetch the information directly from the webpage
+ $siteinfo = ParseUrl::getSiteinfo($url);
unset($siteinfo["keywords"]);
+ // Format it as BBCode attachment
$info = add_page_info_data($siteinfo);
- if (!$textmode)
+ if (!$textmode) {
// Replace ' with ’ - not perfect - but the richtext editor has problems otherwise
$info = str_replace(array("'"), array("’"), $info);
+ }
echo $info;
killme();
}
-?>
+
+/**
+ * @brief Legacy function to call ParseUrl::getSiteinfoCached
+ *
+ * Note: We have moved the function to ParseUrl.php. This function is only for
+ * legacy support and will be remove in the future
+ *
+ * @param type $url The url of the page which should be scraped
+ * @param type $no_guessing If true the parse doens't search for
+ * preview pictures
+ * @param type $do_oembed The false option is used by the function fetch_oembed()
+ * to avoid endless loops
+ *
+ * @return array which contains needed data for embedding
+ *
+ * @see ParseUrl::getSiteinfoCached()
+ *
+ * @todo Remove this function after all Addons has been changed to use
+ * ParseUrl::getSiteinfoCached
+ */
+function parseurl_getsiteinfo_cached($url, $no_guessing = false, $do_oembed = true) {
+ $siteinfo = ParseUrl::getSiteinfoCached($url, $no_guessing, $do_oembed);
+ return $siteinfo;
+}
require_once('mod/proxy.php');
require_once('include/xml.php');
-function ping_init(&$a) {
-
+/**
+ * @brief Outputs the counts and the lists of various notifications
+ *
+ * The output format can be controlled via the GET parameter 'format'. It can be
+ * - xml (deprecated legacy default)
+ * - json (outputs JSONP with the 'callback' GET parameter)
+ *
+ * Expected JSON structure:
+ * {
+ * "result": {
+ * "intro": 0,
+ * "mail": 0,
+ * "net": 0,
+ * "home": 0,
+ * "register": 0,
+ * "all-events": 0,
+ * "all-events-today": 0,
+ * "events": 0,
+ * "events-today": 0,
+ * "birthdays": 0,
+ * "birthdays-today": 0,
+ * "groups": [ ],
+ * "forums": [ ],
+ * "notify": 0,
+ * "notifications": [ ],
+ * "sysmsgs": {
+ * "notice": [ ],
+ * "info": [ ]
+ * }
+ * }
+ * }
+ *
+ * @param App $a The Friendica App instance
+ */
+function ping_init(App $a)
+{
$format = 'xml';
if (isset($_GET['format']) && $_GET['format'] == 'json') {
$format = 'json';
}
+ $tags = array();
+ $comments = array();
+ $likes = array();
+ $dislikes = array();
+ $friends = array();
+ $posts = array();
+ $regs = array();
+ $mails = array();
+ $notifications = array();
+
+ $intro_count = 0;
+ $mail_count = 0;
+ $home_count = 0;
+ $network_count = 0;
+ $register_count = 0;
+ $sysnotify_count = 0;
+ $groups_unseen = array();
+ $forums_unseen = array();
+
+ $all_events = 0;
+ $all_events_today = 0;
+ $events = 0;
+ $events_today = 0;
+ $birthdays = 0;
+ $birthdays_today = 0;
+
+ $data = array();
+ $data['intro'] = $intro_count;
+ $data['mail'] = $mail_count;
+ $data['net'] = $network_count;
+ $data['home'] = $home_count;
+ $data['register'] = $register_count;
+
+ $data['all-events'] = $all_events;
+ $data['all-events-today'] = $all_events_today;
+ $data['events'] = $events;
+ $data['events-today'] = $events_today;
+ $data['birthdays'] = $birthdays;
+ $data['birthdays-today'] = $birthdays_today;
+
if (local_user()){
// Different login session than the page that is calling us.
if (intval($_GET['uid']) && intval($_GET['uid']) != local_user()) {
}
$notifs = ping_get_notifications(local_user());
- $sysnotify_count = 0; // we will update this in a moment
-
- $tags = array();
- $comments = array();
- $likes = array();
- $dislikes = array();
- $friends = array();
- $posts = array();
- $regs = array();
- $mails = array();
-
- $home_count = 0;
- $network_count = 0;
- $register_count = 0;
- $groups_unseen = array();
- $forums_unseen = array();
-
- $r = q("SELECT `item`.`id`,`item`.`parent`, `item`.`verb`, `item`.`wall`, `item`.`author-name`,
+
+ $items_unseen = q("SELECT `item`.`id`, `item`.`parent`, `item`.`verb`, `item`.`wall`, `item`.`author-name`,
`item`.`contact-id`, `item`.`author-link`, `item`.`author-avatar`, `item`.`created`, `item`.`object`,
- `pitem`.`author-name` as `pname`, `pitem`.`author-link` as `plink`
- FROM `item` INNER JOIN `item` as `pitem` ON `pitem`.`id`=`item`.`parent`
+ `pitem`.`author-name` AS `pname`, `pitem`.`author-link` AS `plink`
+ FROM `item` INNER JOIN `item` AS `pitem` ON `pitem`.`id` = `item`.`parent`
WHERE `item`.`unseen` = 1 AND `item`.`visible` = 1 AND
`item`.`deleted` = 0 AND `item`.`uid` = %d AND `pitem`.`parent` != 0
AND `item`.`contact-id` != %d
intval(local_user()), intval(local_user())
);
- if (dbm::is_result($r)) {
-
- $arr = array('items' => $r);
+ if (dbm::is_result($items_unseen)) {
+ $arr = array('items' => $items_unseen);
call_hooks('network_ping', $arr);
- foreach ($r as $it) {
- if ($it['wall']) {
+ foreach ($items_unseen as $item) {
+ if ($item['wall']) {
$home_count++;
} else {
$network_count++;
}
if ($network_count) {
- if (intval(feature_enabled(local_user(),'groups'))) {
+ if (intval(feature_enabled(local_user(), 'groups'))) {
// Find out how unseen network posts are spread across groups
$group_counts = groups_count_unseen();
if (dbm::is_result($group_counts)) {
}
}
- if (intval(feature_enabled(local_user(),'forumlist_widget'))) {
+ if (intval(feature_enabled(local_user(), 'forumlist_widget'))) {
$forum_counts = ForumManager::count_unseen_items();
if (dbm::is_result($forums_counts)) {
foreach ($forums_counts as $forum_count) {
$intros1 = q("SELECT `intro`.`id`, `intro`.`datetime`,
`fcontact`.`name`, `fcontact`.`url`, `fcontact`.`photo`
FROM `intro` LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
- WHERE `intro`.`uid` = %d AND `intro`.`blocked` = 0 AND `intro`.`ignore` = 0 AND `intro`.`fid`!=0",
+ WHERE `intro`.`uid` = %d AND `intro`.`blocked` = 0 AND `intro`.`ignore` = 0 AND `intro`.`fid` != 0",
intval(local_user())
);
$intros2 = q("SELECT `intro`.`id`, `intro`.`datetime`,
`contact`.`name`, `contact`.`url`, `contact`.`photo`
FROM `intro` LEFT JOIN `contact` ON `intro`.`contact-id` = `contact`.`id`
- WHERE `intro`.`uid` = %d AND `intro`.`blocked` = 0 AND `intro`.`ignore` = 0 AND `intro`.`contact-id`!=0",
+ WHERE `intro`.`uid` = %d AND `intro`.`blocked` = 0 AND `intro`.`ignore` = 0 AND `intro`.`contact-id` != 0",
intval(local_user())
);
$mail_count = count($mails);
if ($a->config['register_policy'] == REGISTER_APPROVE && is_site_admin()){
- $regs = q("SELECT `contact`.`name`, `contact`.`url`, `contact`.`micro`, `register`.`created`, COUNT(*) as `total` FROM `contact` RIGHT JOIN `register` ON `register`.`uid`=`contact`.`uid` WHERE `contact`.`self`=1");
+ $regs = q("SELECT `contact`.`name`, `contact`.`url`, `contact`.`micro`, `register`.`created`, COUNT(*) AS `total`
+ FROM `contact` RIGHT JOIN `register` ON `register`.`uid` = `contact`.`uid`
+ WHERE `contact`.`self` = 1");
if ($regs) {
$register_count = $regs[0]['total'];
}
}
- $all_events = 0;
- $all_events_today = 0;
- $events = 0;
- $events_today = 0;
- $birthdays = 0;
- $birthdays_today = 0;
-
- $ev = q("SELECT count(`event`.`id`) as total, type, start, adjust FROM `event`
+ $ev = q("SELECT count(`event`.`id`) AS total, type, start, adjust FROM `event`
WHERE `event`.`uid` = %d AND `start` < '%s' AND `finish` > '%s' and `ignore` = 0
ORDER BY `start` ASC ",
intval(local_user()),
- dbesc(datetime_convert('UTC','UTC','now + 7 days')),
- dbesc(datetime_convert('UTC','UTC','now'))
+ dbesc(datetime_convert('UTC', 'UTC', 'now + 7 days')),
+ dbesc(datetime_convert('UTC', 'UTC', 'now'))
);
if (dbm::is_result($ev)) {
$all_events = intval($ev[0]['total']);
if ($all_events) {
- $str_now = datetime_convert('UTC',$a->timezone,'now','Y-m-d');
+ $str_now = datetime_convert('UTC', $a->timezone, 'now', 'Y-m-d');
foreach($ev as $x) {
$bd = false;
if ($x['type'] === 'birthday') {
else {
$events ++;
}
- if (datetime_convert('UTC',((intval($x['adjust'])) ? $a->timezone : 'UTC'), $x['start'],'Y-m-d') === $str_now) {
+ if (datetime_convert('UTC', ((intval($x['adjust'])) ? $a->timezone : 'UTC'), $x['start'], 'Y-m-d') === $str_now) {
$all_events_today ++;
if ($bd)
$birthdays_today ++;
}
}
- $data = array();
$data['intro'] = $intro_count;
$data['mail'] = $mail_count;
$data['net'] = $network_count;
$sysmsgs = array();
$sysmsgs_info = array();
- if (x($_SESSION,'sysmsg')) {
+ if (x($_SESSION, 'sysmsg')) {
$sysmsgs = $_SESSION['sysmsg'];
unset($_SESSION['sysmsg']);
}
- if (x($_SESSION,'sysmsg_info')) {
+ if (x($_SESSION, 'sysmsg_info')) {
$sysmsgs_info = $_SESSION['sysmsg_info'];
unset($_SESSION['sysmsg_info']);
}
* @param int $uid User id
* @return array Associative array of notifications
*/
-function ping_get_notifications($uid) {
-
- $result = array();
- $offset = 0;
- $seen = false;
+function ping_get_notifications($uid)
+{
+ $result = array();
+ $offset = 0;
+ $seen = false;
$seensql = "NOT";
- $order = "DESC";
- $quit = false;
+ $order = "DESC";
+ $quit = false;
$a = get_app();
* @param array $notifs Complete list of notification
* @param array $sysmsgs List of system notice messages
* @param array $sysmsgs_info List of system info messages
+ * @param int $groups_unseen Number of unseen group items
+ * @param int $forums_unseen Number of unseen forum items
* @return array XML-transform ready data array
*/
-function ping_format_xml_data($data, $sysnotify_count, $notifs, $sysmsgs, $sysmsgs_info, $groups_unseen, $forums_unseen) {
+function ping_format_xml_data($data, $sysnotify, $notifs, $sysmsgs, $sysmsgs_info, $groups_unseen, $forums_unseen)
+{
$notifications = array();
- foreach($notifs as $key => $n) {
- $notifications[$key . ":note"] = $n['message'];
-
- $notifications[$key . ":@attributes"] = array(
- "id" => $n["id"],
- "href" => $n['href'],
- "name" => $n['name'],
- "url" => $n['url'],
- "photo" => $n['photo'],
- "date" => $n['date'],
- "seen" => $n['seen'],
- "timestamp" => $n['timestamp']
+ foreach($notifs as $key => $notif) {
+ $notifications[$key . ':note'] = $notif['message'];
+
+ $notifications[$key . ':@attributes'] = array(
+ 'id' => $notif['id'],
+ 'href' => $notif['href'],
+ 'name' => $notif['name'],
+ 'url' => $notif['url'],
+ 'photo' => $notif['photo'],
+ 'date' => $notif['date'],
+ 'seen' => $notif['seen'],
+ 'timestamp' => $notif['timestamp']
);
}
$sysmsg = array();
foreach ($sysmsgs as $key => $m){
- $sysmsg[$key . ":notice"] = $m;
+ $sysmsg[$key . ':notice'] = $m;
}
foreach ($sysmsgs_info as $key => $m){
- $sysmsg[$key . ":info"] = $m;
+ $sysmsg[$key . ':info'] = $m;
}
- $data["notif"] = $notifications;
- $data["@attributes"] = array("count" => $sysnotify_count + $data["intro"] + $data["mail"] + $data["register"]);
- $data["sysmsgs"] = $sysmsg;
+ $data['notif'] = $notifications;
+ $data['@attributes'] = array('count' => $sysnotify_count + $data['intro'] + $data['mail'] + $data['register']);
+ $data['sysmsgs'] = $sysmsg;
- if ($data["register"] == 0) {
- unset($data["register"]);
+ if ($data['register'] == 0) {
+ unset($data['register']);
}
$groups = array();
}
return $data;
-}
\ No newline at end of file
+}
--- /dev/null
+<?php
+/**
+ * @file mod/worker.php
+ * @brief Module for running the poller as frontend process
+ */
+require_once("include/poller.php");
+
+use \Friendica\Core\Config;
+use \Friendica\Core\PConfig;
+
+function worker_init($a){
+
+ if (!Config::get("system", "frontend_worker")) {
+ return;
+ }
+
+ clear_worker_processes();
+
+ $workers = q("SELECT COUNT(*) AS `processes` FROM `process` WHERE `command` = 'worker.php'");
+
+ if ($workers[0]["processes"] > Config::get("system", "worker_queues", 4)) {
+ return;
+ }
+
+ $a->start_process();
+
+ logger("Front end worker started: ".getmypid());
+
+ call_worker();
+
+ if ($r = poller_worker_process()) {
+
+ // On most configurations this parameter wouldn't have any effect.
+ // But since it doesn't destroy anything, we just try to get more execution time in any way.
+ set_time_limit(0);
+
+ poller_execute($r[0]);
+ }
+
+ call_worker();
+
+ $a->end_process();
+
+ logger("Front end worker ended: ".getmypid());
+
+ killme();
+}
--- /dev/null
+<?php
+/**
+ * @file util/daemon.php
+ * @brief Run the poller from a daemon.
+ *
+ * This script was taken from http://php.net/manual/en/function.pcntl-fork.php
+ */
+function shutdown() {
+ posix_kill(posix_getpid(), SIGHUP);
+}
+
+if (in_array("start", $_SERVER["argv"])) {
+ $mode = "start";
+}
+
+if (in_array("stop", $_SERVER["argv"])) {
+ $mode = "stop";
+}
+
+if (in_array("status", $_SERVER["argv"])) {
+ $mode = "status";
+}
+
+if (!isset($mode)) {
+ die("Please use either 'start', 'stop' or 'status'.\n");
+}
+
+@include(".htconfig.php");
+
+if (!isset($pidfile)) {
+ die('Please specify a pid file in the variable $pidfile in the .htconfig.php. For example:'."\n".
+ '$pidfile = "/path/to/daemon.pid";'."\n");
+}
+
+if (in_array($mode, array("stop", "status"))) {
+ $pid = @file_get_contents($pidfile);
+
+ if (!$pid) {
+ die("Pidfile wasn't found. Is the daemon running?\n");
+ }
+}
+
+if ($mode == "status") {
+ if (posix_kill($pid, 0)) {
+ die("Daemon process $pid is running.\n");
+ }
+
+ unlink($pidfile);
+
+ die("Daemon process $pid isn't running.\n");
+}
+
+if ($mode == "stop") {
+ posix_kill($pid, SIGTERM);
+
+ unlink($pidfile);
+
+ die("Worker daemon process $pid was killed.\n");
+}
+
+echo "Starting worker daemon.\n";
+
+if (isset($a->config['php_path'])) {
+ $php = $a->config['php_path'];
+} else {
+ $php = "php";
+}
+
+// Switch over to daemon mode.
+if ($pid = pcntl_fork())
+ return; // Parent
+
+fclose(STDIN); // Close all of the standard
+fclose(STDOUT); // file descriptors as we
+fclose(STDERR); // are running as a daemon.
+
+register_shutdown_function('shutdown');
+
+if (posix_setsid() < 0)
+ return;
+
+if ($pid = pcntl_fork())
+ return; // Parent
+
+$pid = getmypid();
+file_put_contents($pidfile, $pid);
+
+// Now running as a daemon.
+while (true) {
+ // Just to be sure that this script really runs endlessly
+ set_time_limit(0);
+
+ // Call the poller
+ $cmdline = $php.' include/poller.php';
+
+ exec($cmdline);
+
+ // Now sleep for 5 minutes
+ sleep(300);
+}
+?>
<div class="wall-item-tools" id="wall-item-tools-{{$item.id}}">
{{if $item.vote}}
<div class="wall-item-like-buttons" id="wall-item-like-buttons-{{$item.id}}">
- <a href="#" class="icon like" title="{{$item.vote.like.0|escape:'html'}}" onclick="dolike({{$item.id}},'like'); return false"></a>
- {{if $item.vote.dislike}}<a href="#" class="icon dislike" title="{{$item.vote.dislike.0|escape:'html'}}" onclick="dolike({{$item.id}},'dislike'); return false"></a>{{/if}}
+ <a href="#" class="icon like{{if $item.responses.like.self}} active{{/if}}" title="{{$item.vote.like.0|escape:'html'}}" onclick="dolike({{$item.id}},'like'); return false"></a>
+ {{if $item.vote.dislike}}<a href="#" class="icon dislike{{if $item.responses.dislike.self}} active{{/if}}" title="{{$item.vote.dislike.0|escape:'html'}}" onclick="dolike({{$item.id}},'dislike'); return false"></a>{{/if}}
{{if $item.vote.share}}<a href="#" class="icon recycle wall-item-share-buttons" title="{{$item.vote.share.0|escape:'html'}}" onclick="jotShare({{$item.id}}); return false"></a>{{/if}}
<img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait|escape:'html'}}" title="{{$item.wait|escape:'html'}}" style="display: none;" />
</div>
{{/if}}
{{if $item.isevent }}
<div class="wall-item-attend-wrapper">
- <a href="#" id="attendyes-{{$item.id}}" class="icon attendyes" onclick="dolike({{$item.id}},'attendyes'); return false;" title="{{$item.attend.0|escape:'html'}}"></a>
- <a href="#" id="attendno-{{$item.id}}" class="icon attendno" onclick="dolike({{$item.id}},'attendno'); return false;" title="{{$item.attend.1|escape:'html'}}"></a>
- <a href="#" id="attendmaybe-{{$item.id}}" class="icon attendmaybe" onclick="dolike({{$item.id}},'attendmaybe'); return false;" title="{{$item.attend.2|escape:'html'}}"></a>
+ <a href="#" id="attendyes-{{$item.id}}" class="icon attendyes{{if $item.responses.attendyes.self}} active{{/if}}" onclick="dolike({{$item.id}},'attendyes'); return false;" title="{{$item.attend.0|escape:'html'}}"></a>
+ <a href="#" id="attendno-{{$item.id}}" class="icon attendno{{if $item.responses.attendno.self}} active{{/if}}" onclick="dolike({{$item.id}},'attendno'); return false;" title="{{$item.attend.1|escape:'html'}}"></a>
+ <a href="#" id="attendmaybe-{{$item.id}}" class="icon attendmaybe{{if $item.responses.attendmaybe.self}} active{{/if}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;" title="{{$item.attend.2|escape:'html'}}"></a>
</div>
{{/if}}
<div class="wall-item-delete-wrapper" id="wall-item-delete-wrapper-{{$item.id}}" >
margin-right: 10px;
}
+.wall-item-like-buttons > a.active,
+.wall-item-attend-wrapper > a.active {
+ background-color: rgba(52, 101, 164, .5);
+}
+
.editpost {
margin-left: 10px;
float: left;
/* item social action buttons */
.wall-item-actions, .wall-item-actions a {
font-size: 13px;
- /*color: #aeaeae;*/
color: #555;
margin-top: 15px;
margin-bottom: 0;
}
+.wall-item-actions a.active {
+ font-weight: bold;
+}
.wall-item-actions a:hover {
color: #555;
}
+.wall-item-actions a.active:hover {
+ color: $link_color;
+}
.wall-item-actions-left {
display: table-cell;
vertical-align: middle;
<!-- ./TODO => Unknow block -->
-<div class="panel">
+<div class="panel">
<div class="wall-item-container panel-body{{$item.indent}} {{$item.shiny}} {{$item.previewing}}" >
<div class="media">
{{* Put additional actions in a top-right dropdown menu *}}
{{* Buttons for like and dislike *}}
{{if $item.vote}}
{{if $item.vote.like}}
- <a role="button" href="#" class="button-likes" id="like-{{$item.id}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false;">{{$item.vote.like.0}}</a>
+ <a role="button" href="#" class="button-likes{{if $item.responses.like.self}} active{{/if}}" id="like-{{$item.id}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false;">{{$item.vote.like.0}}</a>
{{/if}}
{{if $item.vote.like AND $item.vote.dislike}}
{{/if}}
{{if $item.vote.dislike}}
- <a role="button" href="#" class="button-likes" id="dislike-{{$item.id}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false;">{{$item.vote.dislike.0}}</a>
+ <a role="button" href="#" class="button-likes{{if $item.responses.like.self}} active{{/if}}" id="dislike-{{$item.id}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false;">{{$item.vote.dislike.0}}</a>
{{/if}}
{{if ($item.vote.like OR $item.vote.dislike) AND $item.comment}}
{{* Event attendance buttons *}}
{{if $item.isevent}}
<div class="vote-event">
- <a role="button" href="#" class="button-event" id="attendyes-{{$item.id}}" title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;"><i class="fa fa-check"><span class="sr-only">{{$item.attend.0}}</span></i></a>
- <a role="button" href="#" class="button-event" id="attendno-{{$item.id}}" title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;"><i class="fa fa-times"><span class="sr-only">{{$item.attend.1}}</span></i></a>
- <a role="button" href="#" class="button-event" id="attendmaybe-{{$item.id}}" title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;"><i class="fa fa-question"><span class="sr-only">{{$item.attend.2}}</span></i></a>
+ <a role="button" href="#" class="button-event{{if $item.responses.attendyes.self}} active{{/if}}" id="attendyes-{{$item.id}}" title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;"><i class="fa fa-check"><span class="sr-only">{{$item.attend.0}}</span></i></a>
+ <a role="button" href="#" class="button-event{{if $item.responses.attendno.self}} active{{/if}}" id="attendno-{{$item.id}}" title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;"><i class="fa fa-times"><span class="sr-only">{{$item.attend.1}}</span></i></a>
+ <a role="button" href="#" class="button-event{{if $item.responses.attendmaybe.self}} active{{/if}}" id="attendmaybe-{{$item.id}}" title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;"><i class="fa fa-question"><span class="sr-only">{{$item.attend.2}}</span></i></a>
</div>
{{/if}}
<span class="icon s22 star {{$item.isstarred}}" id="starred-{{$item.id}}" title="{{$item.star.starred}}">{{$item.star.starred}}</span>
{{/if}}
{{if $item.lock}}<span class="navicon lock fakelink" onclick="lockview(event,{{$item.id}});" title="{{$item.lock}}"></span><span class="fa fa-lock"></span>{{/if}}
- <img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait}}" title="{{$item.wait}}" style="display: none;" />
</div>
<!-- ./TODO => Unknow block -->
<div class="additional-info text-muted">
<div id="wall-item-ago-{{$item.id}}" class="wall-item-ago">
<small><a href="{{$item.plink.orig}}"><span class="time" title="{{$item.localtime}}" data-toggle="tooltip"><time class="dt-published" datetime="{{$item.localtime}}">{{$item.ago}}</time></span></a></small>
+ <img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait}}" title="{{$item.wait}}" style="display: none;" />
</div>
{{if $item.location}}
{{* Buttons for like and dislike *}}
{{if $item.vote}}
{{if $item.vote.like}}
- <a role="button" class="button-likes" id="like-{{$item.id}}" title="{{$item.vote.like.1}}" onclick="dolike({{$item.id}},'like'); return false;"><i class="fa fa-thumbs-up"></i> {{$item.vote.like.1}}</a>
+ <a role="button" class="button-likes{{if $item.responses.like.self}} active{{/if}}" id="like-{{$item.id}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false;"><i class="fa fa-thumbs-up"></i> {{$item.vote.like.1}}</a>
{{/if}}
{{if $item.vote.like AND $item.vote.dislike}}
{{/if}}
{{if $item.vote.dislike}}
- <a role="button" class="button-likes" id="dislike-{{$item.id}}" title="{{$item.vote.dislike.1}}" onclick="dolike({{$item.id}},'dislike'); return false;"><i class="fa fa-thumbs-down"></i> {{$item.vote.dislike.1}}</a>
+ <a role="button" class="button-likes{{if $item.responses.dislike.self}} active{{/if}}" id="dislike-{{$item.id}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false;"><i class="fa fa-thumbs-down"></i> {{$item.vote.dislike.1}}</a>
{{/if}}
{{if ($item.vote.like OR $item.vote.dislike) AND $item.comment}}
<span role="presentation" class="separator"> • </span>
{{/if}}
{{if $item.vote.share}}
- <a role="button" class="button-votes" id="share-{{$item.id}}" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}}); return false;"><i class="fa fa-retweet"></i> {{$item.vote.share.0}}</a>
+ <a role="button" class="button-votes" id="share-{{$item.id}}" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}}); return false;"><i class="fa fa-retweet"></i> {{$item.vote.share.1}}</a>
{{/if}}
{{/if}}
</div>
{{* Event attendance buttons *}}
{{if $item.isevent}}
<div class="vote-event">
- <a role="button" class="button-event" id="attendyes-{{$item.id}}" title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;"><i class="fa fa-check"><span class="sr-only">{{$item.attend.0}}</span></i></a>
- <a role="button" class="button-event" id="attendno-{{$item.id}}" title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;"><i class="fa fa-times"><span class="sr-only">{{$item.attend.1}}</span></i></a>
- <a role="button" class="button-event" id="attendmaybe-{{$item.id}}" title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;"><i class="fa fa-question"><span class="sr-only">{{$item.attend.2}}</span></i></a>
+ <a role="button" class="button-event{{if $item.responses.attendyes.self}} active{{/if}}" id="attendyes-{{$item.id}}" title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;"><i class="fa fa-check"><span class="sr-only">{{$item.attend.0}}</span></i></a>
+ <a role="button" class="button-event{{if $item.responses.attendno.self}} active{{/if}}" id="attendno-{{$item.id}}" title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;"><i class="fa fa-times"><span class="sr-only">{{$item.attend.1}}</span></i></a>
+ <a role="button" class="button-event{{if $item.responses.attendmaybe.self}} active{{/if}}" id="attendmaybe-{{$item.id}}" title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;"><i class="fa fa-question"><span class="sr-only">{{$item.attend.2}}</span></i></a>
</div>
{{/if}}
background-repeat: repeat-x;*/\r
padding: 5px 5px 0px;\r
height: 32px;\r
-\r
}\r
+.wall-item-tools a {\r
+ border-radius: 8px;\r
+ padding: 2px;\r
+ background-position: center;\r
+}\r
+.wall-item-tools a.active {\r
+ background-color: rgba(59, 101, 164, 0.5);\r
+}\r
+\r
.wall-item-author {\r
/* margin-top: 10px;*/\r
margin-top: 0px;\r
.icon.like {\r
display: block; width: 26px; height: 28px;/*31 33*/\r
margin-right: 7px;\r
- background-size: 100% 100%;\r
+ background-size: 26px 28px;\r
background-image: url('images/approve.png');\r
background-repeat: no-repeat;\r
opacity: 0.5;\r
\r
.icon.link {\r
display: block; width: 22px; height: 24px;\r
- background-size: 100% 100%;\r
+ background-size: 22px 24px;\r
background-image: url('images/link.png');\r
background-repeat: no-repeat;\r
\r
/*.globe { background-position: 0px -16px;}*/\r
.icon.globe {\r
display: block; width: 28px; height: 28px;\r
- background-size: 100% 100%;\r
+ background-size: 28px 28px;\r
background-image: url('images/globe.png');\r
background-repeat: no-repeat;\r
}\r
/*.noglobe { background-position: -16px -16px;}*/\r
.icon.noglobe {\r
display: block; width: 24px; height: 24px;\r
- background-size: 100% 100%;\r
+ background-size: 24px 24px;\r
background-image: url('images/noglobe.png');\r
background-repeat: no-repeat;\r
}\r
.small-pencil { background-position: -96px -16px;}*/\r
.icon.pencil {\r
display: block; width: 28px; height: 28px;\r
- background-size: 100% 100%;\r
+ background-size: 28px 28px;\r
background-image: url('images/pencil.png');\r
background-repeat: no-repeat;\r
opacity: 0.5;\r
}\r
.icon.small-pencil {\r
display: block; width: 28px; height: 28px;\r
- background-size: 100% 100%;\r
+ background-size: 28px 28px;\r
background-image: url('images/pencil.png');\r
background-repeat: no-repeat;\r
opacity: 0.5;\r
.icon.recycle {\r
display: block;\r
width: 28px; height: 27px;/*33 32*/\r
- background-size: 100% 100%;\r
+ background-size: 28px 27px;\r
background-image: url('images/recycle.png');\r
background-repeat: no-repeat;\r
opacity: 0.5;\r
/* display: block;*/\r
display: none;\r
width: 28px; height: 28px;\r
- background-size: 100% 100%;\r
+ background-size: 28px 28px;\r
background-image: url('images/remote-link.png');\r
background-repeat: no-repeat;\r
opacity: 0.5;\r
.icon.lock {\r
display: block; width: 17px; height: 25px;\r
margin-top: 1px;\r
- background-size: 100% 100%;\r
+ background-size: 17px 25px;\r
background-image: url('images/lock.png');\r
background-repeat: no-repeat;\r
}\r
.icon.unlock {\r
display: block; width: 17px; height: 28px;\r
margin-top: -2px;\r
- background-size: 100% 100%;\r
+ background-size: 17px 28px;\r
background-image: url('images/unlock.png');\r
background-repeat: no-repeat;\r
}\r
/*.attach { background-position: -80px -32px; }*/\r
.icon.attach {\r
display: block; width: 28px; height: 28px;\r
- background-size: 100% 100%;\r
+ background-size: 28px 28px;\r
background-image: url('images/paperclip.png');\r
background-repeat: no-repeat;\r
}\r
/*.starred { background-position: -16px -48px; }*/\r
.icon.starred {\r
display: block; width: 28px; height: 28px;\r
- background-size: 100% 100%;\r
+ background-size: 28px 28px;\r
background-image: url('images/star-yellow.png');\r
background-repeat: no-repeat;\r
}\r
/*.unstarred { background-position: -32px -48px; }*/\r
.icon.unstarred {\r
display: block; width: 28px; height: 28px;\r
- background-size: 100% 100%;\r
+ background-size: 28px 28px;\r
background-image: url('images/star.png');\r
background-repeat: no-repeat;\r
\r
/*.tagged { background-position: -48px -48px; }*/\r
.icon.tagged {\r
display: block; width: 28px; height: 28px;\r
- background-size: 100% 100%;\r
+ background-size: 28px 28px;\r
background-image: url('images/tag.png');\r
background-repeat: no-repeat;\r
opacity: 0.5;\r
\r
.filer-icon {\r
display: block; width: 24px; height: 24px;\r
- background-size: 100% 100%;\r
+ background-size: 24px 24px;\r
background-image: url('images/folder.png');\r
background-repeat: no-repeat;\r
opacity: 0.5;\r
\r
.event-icon {\r
display: block; width: 33px; height: 33px;\r
- background-size: 100% 100%;\r
+ background-size: 33px 33px;\r
background-repeat: no-repeat;\r
opacity: 0.5;\r
}\r
</div>
<div class="wall-item-arrowphoto-wrapper" ><img src="images/larrow.gif" alt="{{$item.wall}}" /></div>
{{/if}}
- {{*<!--<div class="wall-item-photo-wrapper wwfrom" id="wall-item-photo-wrapper-{{$item.id}}"
+ {{*<!--<div class="wall-item-photo-wrapper wwfrom" id="wall-item-photo-wrapper-{{$item.id}}"
onmouseover="if (typeof t{{$item.id}} != 'undefined') clearTimeout(t{{$item.id}}); openMenu('wall-item-photo-menu-button-{{$item.id}}')"
onmouseout="t{{$item.id}}=setTimeout('closeMenu(\'wall-item-photo-menu-button-{{$item.id}}\'); closeMenu(\'wall-item-photo-menu-{{$item.id}}\');',200)">-->*}}
{{*<!--<div class="wall-item-photo-wrapper{{if $item.owner_url}} wwfrom{{/if}}" id="wall-item-photo-wrapper-{{$item.id}}">-->*}}
{{*<!--<div class="wall-item-photo-end"></div>-->*}}
<div class="wall-item-wrapper" id="wall-item-wrapper-{{$item.id}}" >
{{if $item.lock}}{{*<!--<div class="wall-item-lock">-->*}}<img src="images/lock_icon.gif" class="wall-item-lock lockview" alt="{{$item.lock}}" onclick="lockview(event,{{$item.id}});" />{{*<!--</div>-->*}}
- {{else}}<div class="wall-item-lock"></div>{{/if}}
+ {{else}}<div class="wall-item-lock"></div>{{/if}}
<div class="wall-item-location" id="wall-item-location-{{$item.id}}">{{$item.location}}</div>
</div>
</div>
<div class="wall-item-tools" id="wall-item-tools-{{$item.id}}">
{{if $item.vote}}
<div class="wall-item-like-buttons" id="wall-item-like-buttons-{{$item.id}}">
- <a href="#" class="icon like" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false"></a>
+ <a href="#" class="icon like{{if $item.responses.like.self}} active{{/if}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false"></a>
{{if $item.vote.dislike}}
- <a href="#" class="icon dislike" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false"></a>
+ <a href="#" class="icon dislike{{if $item.responses.dislike.self}} active{{/if}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false"></a>
{{/if}}
{{if $item.vote.share}}<a href="#" class="icon recycle wall-item-share-buttons" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}}); return false"></a>{{/if}}
<img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait}}" title="{{$item.wait}}" style="display: none;" />
{{if $item.edpost}}
<a class="editpost icon pencil" href="{{$item.edpost.0}}" title="{{$item.edpost.1}}"></a>
{{/if}}
-
+
{{if $item.star}}
<a href="#" id="starred-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="star-item icon {{$item.isstarred}}" title="{{$item.star.toggle}}"></a>
{{/if}}
{{/if}}
{{if $item.filer}}
<a href="#" id="filer-{{$item.id}}" onclick="itemFiler({{$item.id}}); return false;" class="filer-item filer-icon" title="{{$item.filer}}"></a>
- {{/if}}
-
+ {{/if}}
+
{{if $item.isevent}}
- <a href="#" id="attendyes-{{$item.id}}" title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;" class="event-item event-icon event-attend-icon"></a>
- <a href="#" id="attendno-{{$item.id}}" title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;" class="event-item event-icon event-dontattend-icon"></a>
- <a href="#" id="attendmaybe-{{$item.id}}" title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;" class="event-item event-icon event-maybeattend-icon"></a>
+ <a href="#" id="attendyes-{{$item.id}}" title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;" class="event-item event-icon event-attend-icon{{if $item.responses.attendyes.self}} active{{/if}}"></a>
+ <a href="#" id="attendno-{{$item.id}}" title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;" class="event-item event-icon event-dontattend-icon{{if $item.responses.attendno.self}} active{{/if}}"></a>
+ <a href="#" id="attendmaybe-{{$item.id}}" title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;" class="event-item event-icon event-maybeattend-icon{{if $item.responses.attendmaybe.self}} active{{/if}}"></a>
{{/if}}
-
+
{{*<!--<div class="wall-item-delete-wrapper" id="wall-item-delete-wrapper-{{$item.id}}" >-->*}}
{{if $item.drop.dropping}}<a href="item/drop/{{$item.id}}" onclick="return confirmDelete();" class="wall-item-delete-wrapper icon drophide" title="{{$item.drop.delete}}" id="wall-item-delete-wrapper-{{$item.id}}" {{*onmouseover="imgbright(this);" onmouseout="imgdull(this);" *}}></a>{{/if}}
{{*<!--</div>-->*}}
{{if $item.drop.pagedrop}}<input type="checkbox" onclick="checkboxhighlight(this);" title="{{$item.drop.select}}" class="item-select" name="itemselected[]" value="{{$item.id}}" />{{/if}}
{{*<!--<div class="wall-item-delete-end"></div>-->*}}
</div>
- </div>
+ </div>
{{*<!--<div class="wall-item-wrapper-end"></div>-->*}}
{{if $item.responses}}
{{foreach $item.responses as $verb=>$response}}
cursor: pointer;
}
+.wall-item-tools a {
+ border-radius: 4px;
+ padding: 2px;
+ background-position: center;
+ background-size: initial !important;
+}
+
+.wall-item-tools a.active {
+ background-color: rgba(59, 101, 164, 0.5);
+}
+
.wall-item-share-buttons {
margin-left: 10px;
margin-right: 10px;
.event-maybeattend-icon { background-image: url('images/event-maybeattend-16.png'); }
.event-dontattend-icon { background-image: url('images/event-dontattend-16.png'); }
-.filer-icon:hover {
+.event-icon:hover {
opacity: 1.0;
}
</div>
<div class="wall-item-arrowphoto-wrapper" ><img src="images/larrow.gif" alt="{{$item.wall}}" /></div>
{{/if}}
- <div class="wall-item-photo-wrapper wwfrom p-author h-card" id="wall-item-photo-wrapper-{{$item.id}}"
+ <div class="wall-item-photo-wrapper wwfrom p-author h-card" id="wall-item-photo-wrapper-{{$item.id}}"
onmouseover="if (typeof t{{$item.id}} != 'undefined') clearTimeout(t{{$item.id}}); openMenu('wall-item-photo-menu-button-{{$item.id}}')"
onmouseout="t{{$item.id}}=setTimeout('closeMenu(\'wall-item-photo-menu-button-{{$item.id}}\'); closeMenu(\'wall-item-photo-menu-{{$item.id}}\');',200)">
<a href="{{$item.profile_url}}" target="redir" title="{{$item.linktitle}}" class="wall-item-photo-link u-url" id="wall-item-photo-link-{{$item.id}}">
{{*<!--<div class="wall-item-photo-end"></div>-->*}}
<div class="wall-item-wrapper" id="wall-item-wrapper-{{$item.id}}" >
{{if $item.lock}}{{*<!--<div class="wall-item-lock">-->*}}<img src="images/lock_icon.gif" class="wall-item-lock lockview" alt="{{$item.lock}}" onclick="lockview(event,{{$item.id}});" />{{*<!--</div>-->*}}
- {{else}}<div class="wall-item-lock"></div>{{/if}}
+ {{else}}<div class="wall-item-lock"></div>{{/if}}
<div class="wall-item-location" id="wall-item-location-{{$item.id}}">{{$item.location}}</div>
</div>
</div>
<div class="wall-item-tools" id="wall-item-tools-{{$item.id}}">
{{if $item.vote}}
<div class="wall-item-like-buttons" id="wall-item-like-buttons-{{$item.id}}">
- <a href="#" class="tool like" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false"></a>
+ <a href="#" class="tool like{{if $item.responses.like.self}} active{{/if}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false"></a>
{{if $item.vote.dislike}}
- <a href="#" class="tool dislike" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false"></a>
+ <a href="#" class="tool dislike{{if $item.responses.dislike.self}} active{{/if}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false"></a>
{{/if}}
{{if $item.vote.share}}<a href="#" class="tool recycle wall-item-share-buttons" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}}); return false"></a>{{/if}}
<img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait}}" title="{{$item.wait}}" style="display: none;" />
{{if $item.edpost}}
<a class="editpost tool pencil" href="{{$item.edpost.0}}" title="{{$item.edpost.1}}"></a>
{{/if}}
-
+
{{if $item.star}}
<a href="#" id="starred-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="star-item tool {{$item.isstarred}}" title="{{$item.star.toggle}}"></a>
{{/if}}
{{/if}}
{{if $item.filer}}
<a href="#" id="filer-{{$item.id}}" onclick="itemFiler({{$item.id}}); return false;" class="filer-item filer-icon" title="{{$item.filer}}"></a>
- {{/if}}
+ {{/if}}
{{if $item.isevent}}
- <a href="#" id="attendyes-{{$item.id}}" title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;" class="event-item event-icon event-attend-icon"></a>
- <a href="#" id="attendno-{{$item.id}}" title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;" class="event-item event-icon event-dontattend-icon"></a>
- <a href="#" id="attendmaybe-{{$item.id}}" title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;" class="event-item event-icon event-maybeattend-icon"></a>
+ <a href="#" id="attendyes-{{$item.id}}" title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;" class="event-item event-icon event-attend-icon{{if $item.responses.attendyes.self}} active{{/if}}"></a>
+ <a href="#" id="attendno-{{$item.id}}" title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;" class="event-item event-icon event-dontattend-icon{{if $item.responses.attendno.self}} active{{/if}}"></a>
+ <a href="#" id="attendmaybe-{{$item.id}}" title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;" class="event-item event-icon event-maybeattend-icon{{if $item.responses.attendmaybe.self}} active{{/if}}"></a>
{{/if}}
{{*<!--</div>-->*}}
{{if $item.drop.pagedrop}}<input type="checkbox" onclick="checkboxhighlight(this);" title="{{$item.drop.select}}" class="item-select" name="itemselected[]" value="{{$item.id}}" />{{/if}}
{{*<!--<div class="wall-item-delete-end"></div>-->*}}
-
-
+
+
</div>
- </div>
+ </div>
{{*<!--<div class="wall-item-wrapper-end"></div>-->*}}
{{if $item.responses}}
{{foreach $item.responses as $verb=>$response}}
.wall-item-container .wall-item-actions-social a {
margin-right: 3em;
}
+.wall-item-container .wall-item-actions-social a.active {
+ font-weight: bold;
+}
.wall-item-container .wall-item-actions-tools {
float: right;
width: 15%;
.wall-item-container .wall-item-actions-social a {
margin-right: 3em;
}
+.wall-item-container .wall-item-actions-social a.active {
+ font-weight: bold;
+}
.wall-item-container .wall-item-actions-tools {
float: right;
width: 15%;
.wall-item-container .wall-item-actions-social a {
margin-right: 3em;
}
+.wall-item-container .wall-item-actions-social a.active {
+ font-weight: bold;
+}
.wall-item-container .wall-item-actions-tools {
float: right;
width: 15%;
a { margin-right: 3em; }
}
.wall-item-actions-social { float: left; margin-top: 0.5em;
- a { margin-right: 3em; }
+ a { margin-right: 3em;
+ .active { font-weight: bold;}
+ }
}
.wall-item-actions-tools { float: right; width: 15%;
a { float: right; }
<img src="{{$thumb}}" class="contact-photo{{$sparkle}}" id="wall-item-photo-{{$id}}" alt="{{$name}}" />
</a>
</div>
- <div class="wall-item-location">{{$location}}</div>
+ <div class="wall-item-location">{{$location}}</div>
</div>
<div class="wall-item-content">
{{if $title}}<h2><a href="{{$plink.href}}">{{$title}}</a></h2>{{/if}}
<div class="wall-item-actions-author">
<a href="{{$profile_url}}" target="redir" title="{{$linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$sparkle}}">{{$name}}</span></a> <span class="wall-item-ago" title="{{$localtime}}">{{$ago}}</span>
</div>
-
+
<div class="wall-item-actions-social">
{{if $star}}
<a href="#" id="star-{{$id}}" onclick="dostar({{$id}}); return false;" class="{{$star.classdo}}" title="{{$star.do}}">{{$star.do}}</a>
<a href="#" id="unstar-{{$id}}" onclick="dostar({{$id}}); return false;" class="{{$star.classundo}}" title="{{$star.undo}}">{{$star.undo}}</a>
<a href="#" id="tagger-{{$id}}" onclick="itemTag({{$id}}); return false;" class="{{$star.classtagger}}" title="{{$star.tagger}}">{{$star.tagger}}</a>
{{/if}}
-
+
{{if $vote}}
- <a href="#" id="like-{{$id}}" title="{{$vote.like.0}}" onclick="dolike({{$id}},'like'); return false">{{$vote.like.1}}</a>
- <a href="#" id="dislike-{{$id}}" title="{{$vote.dislike.0}}" onclick="dolike({{$id}},'dislike'); return false">{{$vote.dislike.1}}</a>
+ <a href="#" id="like-{{$id}}"{{if $item.responses.like.self}} class="active{{/if}}" title="{{$vote.like.0}}" onclick="dolike({{$id}},'like'); return false">{{$vote.like.1}}</a>
+ <a href="#" id="dislike-{{$id}}"{{if $item.responses.dislike.self}} class="active{{/if}}" title="{{$vote.dislike.0}}" onclick="dolike({{$id}},'dislike'); return false">{{$vote.dislike.1}}</a>
{{/if}}
-
+
{{if $vote.share}}
<a href="#" id="share-{{$id}}" title="{{$vote.share.0}}" onclick="jotShare({{$id}}); return false">{{$vote.share.1}}</a>
- {{/if}}
+ {{/if}}
</div>
-
+
<div class="wall-item-actions-tools">
{{if $drop.pagedrop}}
<a class="icon edit s16" href="{{$edpost.0}}" title="{{$edpost.1}}"></a>
{{/if}}
</div>
-
+
</div>
</div>
<div class="wall-item-bottom">
</div>
{{/if}}
</div>
-
-
+
+
</div>
<div class="wall-item-decor">
{{if $item.star}}<span class="icon s22 star {{$item.isstarred}}" id="starred-{{$item.id}}" title="{{$item.star.starred}}">{{$item.star.starred}}</span>{{/if}}
- {{if $item.lock}}<span class="icon s22 lock fakelink" onclick="lockview(event,{{$item.id}});" title="{{$item.lock}}">{{$item.lock}}</span>{{/if}}
+ {{if $item.lock}}<span class="icon s22 lock fakelink" onclick="lockview(event,{{$item.id}});" title="{{$item.lock}}">{{$item.lock}}</span>{{/if}}
<img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait}}" title="{{$item.wait}}" style="display: none;" />
</div>
<div class="wall-item-item">
<div class="wall-item-info">
<div class="contact-photo-wrapper"
- onmouseover="if (typeof t{{$item.id}} != 'undefined') clearTimeout(t{{$item.id}}); openMenu('wall-item-photo-menu-button-{{$item.id}}')"
+ onmouseover="if (typeof t{{$item.id}} != 'undefined') clearTimeout(t{{$item.id}}); openMenu('wall-item-photo-menu-button-{{$item.id}}')"
onmouseout="t{{$item.id}}=setTimeout('closeMenu(\'wall-item-photo-menu-button-{{$item.id}}\'); closeMenu(\'wall-item-photo-menu-{{$item.id}}\');',200)">
<a href="{{$item.profile_url}}" target="redir" title="{{$item.linktitle}}" class="wall-item-photo-link" id="wall-item-photo-link-{{$item.id}}">
<img src="{{$item.thumb}}" class="contact-photo{{$item.sparkle}}" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" />
<ul class="wall-item-menu menu-popup" id="wall-item-photo-menu-{{$item.id}}">
{{$item.item_photo_menu}}
</ul>
-
+
</div>
- <div class="wall-item-location">{{$item.location}}</div>
+ <div class="wall-item-location">{{$item.location}}</div>
</div>
<div class="wall-item-content">
{{if $item.title}}<h2><a href="{{$item.plink.href}}">{{$item.title}}</a></h2>{{/if}}
<div class="wall-item-actions-author">
<a href="{{$item.profile_url}}" target="redir" title="{{$item.linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.sparkle}}">{{$item.name}}</span></a> <span class="wall-item-ago" title="{{$item.localtime}}">{{$item.ago}}</span>
</div>
-
+
<div class="wall-item-actions-social">
{{if $item.star}}
<a href="#" id="star-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="{{$item.star.classdo}}" title="{{$item.star.do}}">{{$item.star.do}}</a>
<a href="#" id="unstar-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="{{$item.star.classundo}}" title="{{$item.star.undo}}">{{$item.star.undo}}</a>
<a href="#" id="tagger-{{$item.id}}" onclick="itemTag({{$item.id}}); return false;" class="{{$item.star.classtagger}}" title="{{$item.star.tagger}}">{{$item.star.tagger}}</a>
{{/if}}
-
+
{{if $item.vote}}
- <a href="#" id="like-{{$item.id}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false">{{$item.vote.like.1}}</a>
- <a href="#" id="dislike-{{$item.id}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false">{{$item.vote.dislike.1}}</a>
+ <a href="#" id="like-{{$item.id}}"{{if $item.responses.like.self}} class="active{{/if}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false">{{$item.vote.like.1}}</a>
+ <a href="#" id="dislike-{{$item.id}}"{{if $item.responses.dislike.self}} class="active{{/if}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false">{{$item.vote.dislike.1}}</a>
{{/if}}
-
+
{{if $item.vote.share}}
<a href="#" id="share-{{$item.id}}" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}}); return false">{{$item.vote.share.1}}</a>
- {{/if}}
+ {{/if}}
</div>
-
+
<div class="wall-item-actions-tools">
{{if $item.drop.pagedrop}}
<a class="icon edit s16" href="{{$item.edpost.0}}" title="{{$item.edpost.1}}"></a>
{{/if}}
</div>
-
+
</div>
</div>
<div class="wall-item-bottom">
</div>
{{/if}}
</div>
-
-
+
+
</div>
{{else}}
{{if $item.comment_firstcollapsed}}
<div class="hide-comments-outer">
- <span id="hide-comments-total-{{$item.id}}"
+ <span id="hide-comments-total-{{$item.id}}"
class="hide-comments-total">{{$item.num_comments}}</span>
- <span id="hide-comments-{{$item.id}}"
- class="hide-comments fakelink"
+ <span id="hide-comments-{{$item.id}}"
+ class="hide-comments fakelink"
onclick="showHideComments({{$item.id}});">{{$item.hide_text}}</span>
- {{if $item.thread_level==3}} -
+ {{if $item.thread_level==3}} -
<span id="hide-thread-{{$item}}-id"
class="fakelink"
onclick="showThread({{$item.id}});">expand</span> /
<div class="wall-item-decor">
{{if $item.star}}<span class="icon s22 star {{$item.isstarred}}" id="starred-{{$item.id}}" title="{{$item.star.starred}}">{{$item.star.starred}}</span>{{/if}}
- {{if $item.lock}}<span class="icon s22 lock fakelink" onclick="lockview(event,{{$item.id}});" title="{{$item.lock}}">{{$item.lock}}</span>{{/if}}
+ {{if $item.lock}}<span class="icon s22 lock fakelink" onclick="lockview(event,{{$item.id}});" title="{{$item.lock}}">{{$item.lock}}</span>{{/if}}
<img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait}}" title="{{$item.wait}}" style="display: none;" />
</div>
<div class="wall-item-item">
<div class="wall-item-info">
<div class="contact-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}} p-author h-card"
- onmouseover="if (typeof t{{$item.id}} != 'undefined') clearTimeout(t{{$item.id}}); openMenu('wall-item-photo-menu-button-{{$item.id}}')"
+ onmouseover="if (typeof t{{$item.id}} != 'undefined') clearTimeout(t{{$item.id}}); openMenu('wall-item-photo-menu-button-{{$item.id}}')"
onmouseout="t{{$item.id}}=setTimeout('closeMenu(\'wall-item-photo-menu-button-{{$item.id}}\'); closeMenu(\'wall-item-photo-menu-{{$item.id}}\');',200)">
<a href="{{$item.profile_url}}" target="redir" title="{{$item.linktitle}}" class="contact-photo-link u-url" id="wall-item-photo-link-{{$item.id}}">
<img src="{{$item.thumb}}" class="contact-photo {{$item.sparkle}} p-name u-photo" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" />
<ul class="contact-menu menu-popup" id="wall-item-photo-menu-{{$item.id}}">
{{$item.item_photo_menu}}
</ul>
-
- </div>
+
+ </div>
{{if $item.owner_url}}
<div class="contact-photo-wrapper mframe wwto" id="wall-item-ownerphoto-wrapper-{{$item.id}}" >
<a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="contact-photo-link" id="wall-item-ownerphoto-link-{{$item.id}}">
<img src="{{$item.owner_photo}}" class="contact-photo {{$item.osparkle}}" id="wall-item-ownerphoto-{{$item.id}}" alt="{{$item.owner_name}}" />
</a>
</div>
- {{/if}}
- <div class="wall-item-location">{{$item.location}}</div>
+ {{/if}}
+ <div class="wall-item-location">{{$item.location}}</div>
</div>
<div class="wall-item-content">
{{if $item.title}}<h2><a href="{{$item.plink.href}}" class="{{$item.sparkle}} p-name">{{$item.title}}</a></h2>{{/if}}
<span class='category p-category'>{{$cat.name}}</a>{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
{{/foreach}}
</div>
- </div>
+ </div>
<div class="wall-item-bottom">
<div class="wall-item-links">
{{if $item.plink}}<a class="icon s16 link{{$item.sparkle}} u-url" title="{{$item.plink.title}}" href="{{$item.plink.href}}">{{$item.plink.title}}</a>{{/if}}
{{if $item.owner_url}}<br/>{{$item.to}} <a href="{{$item.owner_url}}" target="redir" title="{{$item.olinktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.osparkle}}" id="wall-item-ownername-{{$item.id}}">{{$item.owner_name}}</span></a> {{$item.vwall}}
{{/if}}
</div>
-
+
<div class="wall-item-actions-social">
{{if $item.star}}
<a href="#" id="star-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="{{$item.star.classdo}}" title="{{$item.star.do}}">{{$item.star.do}}</a>
{{/if}}
{{if $item.filer}}
<a href="#" id="filer-{{$item.id}}" onclick="itemFiler({{$item.id}}); return false;" class="filer-item filer-icon" title="{{$item.filer}}">{{$item.filer}}</a>
- {{/if}}
-
+ {{/if}}
+
{{if $item.vote}}
- <a href="#" id="like-{{$item.id}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false">{{$item.vote.like.1}}</a>
+ <a href="#" id="like-{{$item.id}}"{{if $item.responses.like.self}} class="active{{/if}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false">{{$item.vote.like.1}}</a>
{{if $item.vote.dislike}}
- <a href="#" id="dislike-{{$item.id}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false">{{$item.vote.dislike.1}}</a>
+ <a href="#" id="dislike-{{$item.id}}"{{if $item.responses.dislike.self}} class="active{{/if}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false">{{$item.vote.dislike.1}}</a>
{{/if}}
{{if $item.vote.share}}
<a href="#" id="share-{{$item.id}}" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}}); return false">{{$item.vote.share.1}}</a>
- {{/if}}
+ {{/if}}
{{/if}}
{{if $item.isevent}}
<div class="clear"></div>
<div class="wall-item-actions-isevent">
- <a href="#" id="attendyes-{{$item.id}}" title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;">{{$item.attend.0}}</a>
- <a href="#" id="attendno-{{$item.id}}" title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;">{{$item.attend.1}}</a>
- <a href="#" id="attendmaybe-{{$item.id}}" title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;">{{$item.attend.2}}</a>
+ <a href="#" id="attendyes-{{$item.id}}"{{if $item.responses.attendyes.self}} class="active{{/if}}" title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;">{{$item.attend.0}}</a>
+ <a href="#" id="attendno-{{$item.id}}"{{if $item.responses.attendno.self}} class="active{{/if}}" title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;">{{$item.attend.1}}</a>
+ <a href="#" id="attendmaybe-{{$item.id}}"{{if $item.responses.attendmaybe.self}} class="active{{/if}}" title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;">{{$item.attend.2}}</a>
</div>
{{/if}}
-
+
</div>
-
+
<div class="wall-item-actions-tools">
{{if $item.drop.pagedrop}}
<a class="icon edit s16" href="{{$item.edpost.0}}" title="{{$item.edpost.1}}"></a>
{{/if}}
</div>
-
+
</div>
</div>
<div class="wall-item-bottom">
{{/foreach}}
{{/if}}
</div>
-
+
{{if $item.threaded}}{{if $item.comment}}{{if $item.indent==comment}}
<div class="wall-item-bottom commentbox">
<div class="wall-item-links"></div>
margin-right: 10px;
display: inline;
}
+.wall-item-like-buttons a.self {
+ background-color: rgba(52, 101, 164, .5);
+ border-radius: 6px;
+}
.wall-item-links-wrapper {
width: 30px;
{{if $item.comment_firstcollapsed}}
<div class="hide-comments-outer">
- <span id="hide-comments-total-{{$item.id}}" class="hide-comments-total">{{$item.num_comments}}</span>
+ <span id="hide-comments-total-{{$item.id}}" class="hide-comments-total">{{$item.num_comments}}</span>
<span id="hide-comments-{{$item.id}}" class="hide-comments fakelink" onclick="showHideComments({{$item.id}});">{{$item.hide_text}}</span>
</div>
<div id="collapsed-comments-{{$item.id}}" class="collapsed-comments" style="display: none;">
</div>
<div class="wall-item-arrowphoto-wrapper" ><img src="view/theme/smoothly/images/larrow.gif" alt="{{$item.wall}}" /></div>
{{/if}}
- <div class="wall-item-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}} p-author h-card" id="wall-item-photo-wrapper-{{$item.id}}"
+ <div class="wall-item-photo-wrapper mframe{{if $item.owner_url}} wwfrom{{/if}} p-author h-card" id="wall-item-photo-wrapper-{{$item.id}}"
onmouseover="if (typeof t{{$item.id}} != 'undefined') clearTimeout(t{{$item.id}}); openMenu('wall-item-photo-menu-button-{{$item.id}}')"
onmouseout="t{{$item.id}}=setTimeout('closeMenu(\'wall-item-photo-menu-button-{{$item.id}}\'); closeMenu(\'wall-item-photo-menu-{{$item.id}}\');',200)">
<a href="{{$item.profile_url}}" title="{{$item.linktitle}}" class="wall-item-photo-link u-url" id="wall-item-photo-link-{{$item.id}}">
</a>
<div class="wall-item-ago">•</div>
<div class="wall-item-ago" id="wall-item-ago-{{$item.id}}" title="{{$item.localtime}}"><time class="dt-published" datetime="{{$item.localtime}}">{{$item.ago}}</time></div>
- </div>
+ </div>
<div>
<hr class="line-dots">
</div>
{{if $item.has_cats}}
- <div class="categorytags"><span>{{$item.txt_cats}} {{foreach $item.categories as $cat}}<span class="p-category">{{$cat.name}}</span>
- <a href="{{$cat.removeurl}}" title="{{$remove}}">[{{$remove}}]</a>
+ <div class="categorytags"><span>{{$item.txt_cats}} {{foreach $item.categories as $cat}}<span class="p-category">{{$cat.name}}</span>
+ <a href="{{$cat.removeurl}}" title="{{$remove}}">[{{$remove}}]</a>
{{if $cat.last}}{{else}}, {{/if}}{{/foreach}}
</div>
{{/if}}
{{if $item.has_folders}}
- <div class="filesavetags"><span>{{$item.txt_folders}} {{foreach $item.folders as $cat}}<span class="p-category">{{$cat.name}}</span>
- <a href="{{$cat.removeurl}}" title="{{$remove}}">[{{$remove}}]</a>
+ <div class="filesavetags"><span>{{$item.txt_folders}} {{foreach $item.folders as $cat}}<span class="p-category">{{$cat.name}}</span>
+ <a href="{{$cat.removeurl}}" title="{{$remove}}">[{{$remove}}]</a>
{{if $cat.last}}{{else}}, {{/if}}{{/foreach}}
</div>
{{/if}}
{{if $item.vote}}
<div class="wall-item-like-buttons" id="wall-item-like-buttons-{{$item.id}}">
- <a href="#" class="icon like" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false"></a>
+ <a href="#" class="icon like{{if $item.responses.like.self}} self{{/if}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false"></a>
{{if $item.vote.dislike}}
- <a href="#" class="icon dislike" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false"></a>
+ <a href="#" class="icon dislike{{if $item.responses.dislike.self}} self{{/if}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false"></a>
{{/if}}
{{if $item.vote.share}}
<a href="#" class="icon recycle wall-item-share-buttons" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}}); return false"></a> {{/if}}
<a href="{{$item.plink.href}}" title="{{$item.plink.title}}" target="external-link" class="icon remote-link u-url"></a>
</div>
{{/if}}
-
+
{{if $item.star}}
<a href="#" id="starred-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="star-item icon {{$item.isstarred}}" title="{{$item.star.toggle}}"></a>
{{/if}}
{{if $item.filer}}
<a href="#" id="filer-{{$item.id}}" onclick="itemFiler({{$item.id}}); return false;" class="filer-item filer-icon" title="{{$item.filer}}"></a>
{{/if}}
-
+
</div>
<div class="wall-item-tools" id="wall-item-tools-{{$item.id}}">
<div class="wall-item-delete-end"></div>
</div>
- </div>
+ </div>
<div class="wall-item-wrapper-end"></div>
<div class="wall-item-like" id="wall-item-like-{{$item.id}}">{{$item.like}}</div>
<div class="wall-item-dislike" id="wall-item-dislike-{{$item.id}}">{{$item.dislike}}</div>
margin-right: 1em;
cursor: pointer;
}
+.wall-item-container .wall-item-actions-social a.active,
+.wall-item-container .wall-item-actions-isevent a.active {
+ color: #36C;
+}
+
.wall-item-container .wall-item-actions-tools {
float: right;
width: 80px;
max-width: calc(100% - 1px);
}
-.children .wall-item-comment-wrapper textarea,
+.children .wall-item-comment-wrapper textarea,
.wall-item-container.thread_level_3 .wall-item-comment-wrapper textarea,
.wall-item-container.thread_level_4 .wall-item-comment-wrapper textarea,
.wall-item-container.thread_level_5 .wall-item-comment-wrapper textarea,
</div>
</div>
<div class="wall-item-actions-author">
- <a href="{{$profile_url}}" target="redir" title="{{$linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$sparkle}}">{{$name}}</span></a>
+ <a href="{{$profile_url}}" target="redir" title="{{$linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$sparkle}}">{{$name}}</span></a>
<span class="wall-item-ago">
{{if $plink}}<a class="link" title="{{$plink.title}}" href="{{$plink.href}}" style="color: #999">{{$ago}}</a>{{else}} {{$ago}} {{/if}}
{{if $lock}}<span class="fakelink" style="color: #999" onclick="lockview(event,{{$id}});">{{$lock}}</span> {{/if}}
</div>
<div class="wall-item-actions">
- <div class="wall-item-location">{{$location}} </div>
-
+ <div class="wall-item-location">{{$location}} </div>
+
<div class="wall-item-actions-social">
{{if $star}}
<a href="#" id="star-{{$id}}" onclick="dostar({{$id}}); return false;" class="{{$star.classdo}}" title="{{$star.do}}">{{$star.do}}</a>
<a href="#" id="unstar-{{$id}}" onclick="dostar({{$id}}); return false;" class="{{$star.classundo}}" title="{{$star.undo}}">{{$star.undo}}</a>
<a href="#" id="tagger-{{$id}}" onclick="itemTag({{$id}}); return false;" class="{{$star.classtagger}}" title="{{$star.tagger}}">{{$star.tagger}}</a>
{{/if}}
-
+
{{if $vote}}
- <a href="#" id="like-{{$id}}" title="{{$vote.like.0}}" onclick="dolike({{$id}},'like'); return false">{{$vote.like.1}}</a>
- <a href="#" id="dislike-{{$id}}" title="{{$vote.dislike.0}}" onclick="dolike({{$id}},'dislike'); return false">{{$vote.dislike.1}}</a>
+ <a href="#" id="like-{{$id}}"{{if $item.responses.like.self}} class="active"{{/if}} title="{{$vote.like.0}}" onclick="dolike({{$id}},'like'); return false">{{$vote.like.1}}</a>
+ <a href="#" id="dislike-{{$id}}"{{if $item.responses.dislike.self}} class="active"{{/if}} title="{{$vote.dislike.0}}" onclick="dolike({{$id}},'dislike'); return false">{{$vote.dislike.1}}</a>
{{/if}}
-
+
{{if $vote.share}}
<a href="#" id="share-{{$id}}" title="{{$vote.share.0}}" onclick="jotShare({{$id}}); return false">{{$vote.share.1}}</a>
- {{/if}}
+ {{/if}}
</div>
-
+
<div class="wall-item-actions-tools">
{{if $drop.pagedrop}}
<a class="icon edit s16" href="{{$edpost.0}}" title="{{$edpost.1}}"></a>
{{/if}}
</div>
-
+
</div>
</div>
<div class="wall-item-bottom">
<div class="wall-item-links"></div>
<div class="wall-item-like" id="wall-item-like-{{$id}}">{{$like}}</div>
- <div class="wall-item-dislike" id="wall-item-dislike-{{$id}}">{{$dislike}}</div>
+ <div class="wall-item-dislike" id="wall-item-dislike-{{$id}}">{{$dislike}}</div>
</div>
</div>
<div class="wall-item-decor">
{{if $item.star}}<span class="icon star {{$item.isstarred}}" id="starred-{{$item.id}}" title="{{$item.star.starred}}">{{$item.star.starred}}</span>{{/if}}
- {{if $item.lock}}<span class="icon lock fakelink" onclick="lockview(event,{{$item.id}});" title="{{$item.lock}}">{{$item.lock}}</span>{{/if}}
+ {{if $item.lock}}<span class="icon lock fakelink" onclick="lockview(event,{{$item.id}});" title="{{$item.lock}}">{{$item.lock}}</span>{{/if}}
<img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait}}" title="{{$item.wait}}" style="display: none;" />
</div>
<div class="wall-item-item">
<div class="wall-item-info">
<div class="contact-photo-wrapper">
- <!-- onmouseover="if (typeof t{{$item.id}} != 'undefined') clearTimeout(t{{$item.id}}); openMenu('wall-item-photo-menu-button-{{$item.id}}')"
+ <!-- onmouseover="if (typeof t{{$item.id}} != 'undefined') clearTimeout(t{{$item.id}}); openMenu('wall-item-photo-menu-button-{{$item.id}}')"
onmouseout="t{{$item.id}}=setTimeout('closeMenu(\'wall-item-photo-menu-button-{{$item.id}}\'); closeMenu(\'wall-item-photo-menu-{{$item.id}}\');',200)"> -->
<!-- <a href="{{$item.profile_url}}" target="redir" title="{{$item.linktitle}}" class="wall-item-photo-link" id="wall-item-photo-link-{{$item.id}}"></a> -->
<img src="{{$item.thumb}}" class="contact-photo{{$item.sparkle}}" id="wall-item-photo-{{$item.id}}" alt="{{$item.name}}" />
<ul role="menu" aria-haspopup="true" class="wall-item-menu menu-popup" id="wall-item-photo-menu-{{$item.id}}">
{{$item.item_photo_menu}}
</ul>
-
+
</div>
</div>
<div class="wall-item-actions-author">
- <a href="{{$item.profile_url}}" target="redir" title="{{$item.linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.sparkle}}">{{$item.name}}</span></a>
+ <a href="{{$item.profile_url}}" target="redir" title="{{$item.linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.sparkle}}">{{$item.name}}</span></a>
<span class="wall-item-ago">
{{if $item.plink}}<a class="link" title="{{$item.plink.title}}" href="{{$item.plink.href}}" style="color: #999">{{$item.ago}}</a>{{else}} {{$item.ago}} {{/if}}
{{if $item.lock}}<span class="fakelink" style="color: #999" onclick="lockview(event,{{$item.id}});">{{$item.lock}}</span> {{/if}}
</div>
<div class="wall-item-actions">
- <div class="wall-item-location">{{$item.location}} </div>
-
+ <div class="wall-item-location">{{$item.location}} </div>
+
<div class="wall-item-actions-social">
{{if $item.star}}
<a href="#" id="star-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="{{$item.star.classdo}}" title="{{$item.star.do}}">{{$item.star.do}}</a>
<a href="#" id="unstar-{{$item.id}}" onclick="dostar({{$item.id}}); return false;" class="{{$item.star.classundo}}" title="{{$item.star.undo}}">{{$item.star.undo}}</a>
<a href="#" id="tagger-{{$item.id}}" onclick="itemTag({{$item.id}}); return false;" class="{{$item.star.classtagger}}" title="{{$item.star.tagger}}">{{$item.star.tagger}}</a>
{{/if}}
-
+
{{if $item.vote}}
- <a href="#" id="like-{{$item.id}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false">{{$item.vote.like.1}}</a>
- <a href="#" id="dislike-{{$item.id}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false">{{$item.vote.dislike.1}}</a>
+ <a href="#" id="like-{{$item.id}}"{{if $item.responses.like.self}} class="active"{{/if}} title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false">{{$item.vote.like.1}}</a>
+ <a href="#" id="dislike-{{$item.id}}"{{if $item.responses.dislike.self}} class="active"{{/if}} title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false">{{$item.vote.dislike.1}}</a>
{{/if}}
-
+
{{if $item.vote.share}}
<a href="#" id="share-{{$item.id}}" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}}); return false">{{$item.vote.share.1}}</a>
- {{/if}}
+ {{/if}}
</div>
-
+
<div class="wall-item-actions-tools">
{{if $item.drop.pagedrop}}
<a class="icon edit s16" href="{{$item.edpost.0}}" title="{{$item.edpost.1}}"></a>
{{/if}}
</div>
-
+
</div>
</div>
<div class="wall-item-bottom">
<div class="wall-item-links"></div>
<div class="wall-item-like" id="wall-item-like-{{$item.id}}">{{$item.like}}</div>
- <div class="wall-item-dislike" id="wall-item-dislike-{{$item.id}}">{{$item.dislike}}</div>
+ <div class="wall-item-dislike" id="wall-item-dislike-{{$item.id}}">{{$item.dislike}}</div>
</div>
</div>
{{if $mode == display}}
{{else}}
{{if $item.comment_firstcollapsed}}
- {{if $item.thread_level<3}}
+ {{if $item.thread_level<3}}
<div class="hide-comments-outer">
- <span id="hide-comments-total-{{$item.id}}"
+ <span id="hide-comments-total-{{$item.id}}"
class="hide-comments-total">{{$item.num_comments}}</span>
- <span id="hide-comments-{{$item.id}}"
- class="hide-comments fakelink"
+ <span id="hide-comments-{{$item.id}}"
+ class="hide-comments fakelink"
onclick="showHideComments({{$item.id}});">{{$item.hide_text}}</span>
</div>
<div id="collapsed-comments-{{$item.id}}" class="collapsed-comments" style="display: none;">
<ul role="menu" aria-haspopup="true" class="contact-menu menu-popup" id="wall-item-photo-menu-{{$item.id}}">
{{$item.item_photo_menu}}
</ul>
-
+
</div>
{{if $item.owner_url}}
<div aria-hidden="true" class="contact-photo-wrapper mframe wwto" id="wall-item-ownerphoto-wrapper-{{$item.id}}" >
<img src="{{$item.owner_photo}}" class="contact-photo {{$item.osparkle}} p-name u-photo" id="wall-item-ownerphoto-{{$item.id}}" alt="{{$item.owner_name}}" />
</a>
</div>
- {{/if}}
+ {{/if}}
</div>
<div role="heading" aria-level="{{$item.thread_level}}" class="wall-item-actions-author">
<a href="{{$item.profile_url}}" target="redir" title="{{$item.linktitle}}" class="wall-item-name-link"><span class="wall-item-name{{$item.sparkle}}">{{$item.name}}</span></a>
<span class='category p-category'>{{$cat.name}}</a>{{if $cat.removeurl}} (<a href="{{$cat.removeurl}}" title="{{$remove}}">x</a>) {{/if}} </span>
{{/foreach}}
</div>
- </div>
+ </div>
<div class="wall-item-bottom">
<div class="wall-item-links">
{{if $item.plink}}<a role="button" title="{{$item.plink.orig_title}}" href="{{$item.plink.orig}}"><i class="icon-link icon-large"><span class="sr-only">{{$item.plink.orig_title}}</span></i></a>{{/if}}
{{/if}}
{{if $item.isevent}}
- <a role="button" id="attendyes-{{$item.id}}" title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;"><i class="icon-ok icon-large"><span class="sr-only">{{$item.attend.0}}</span></i></a>
- <a role="button" id="attendno-{{$item.id}}" title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;"><i class="icon-remove icon-large"><span class="sr-only">{{$item.attend.1}}</span></i></a>
- <a role="button" id="attendmaybe-{{$item.id}}" title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;"><i class="icon-question icon-large"><span class="sr-only">{{$item.attend.2}}</span></i></a>
+ <a role="button" id="attendyes-{{$item.id}}"{{if $item.responses.attendyes.self}} class="active"{{/if}} title="{{$item.attend.0}}" onclick="dolike({{$item.id}},'attendyes'); return false;"><i class="icon-ok icon-large"><span class="sr-only">{{$item.attend.0}}</span></i></a>
+ <a role="button" id="attendno-{{$item.id}}"{{if $item.responses.attendno.self}} class="active"{{/if}} title="{{$item.attend.1}}" onclick="dolike({{$item.id}},'attendno'); return false;"><i class="icon-remove icon-large"><span class="sr-only">{{$item.attend.1}}</span></i></a>
+ <a role="button" id="attendmaybe-{{$item.id}}"{{if $item.responses.attendmaybe.self}} class="active"{{/if}} title="{{$item.attend.2}}" onclick="dolike({{$item.id}},'attendmaybe'); return false;"><i class="icon-question icon-large"><span class="sr-only">{{$item.attend.2}}</span></i></a>
{{/if}}
{{if $item.vote}}
{{if $item.vote.like}}
- <a role="button" id="like-{{$item.id}}" title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false"><i class="icon-thumbs-up icon-large"><span class="sr-only">{{$item.vote.like.0}}</span></i></a>
+ <a role="button" id="like-{{$item.id}}"{{if $item.responses.like.self}} class="active"{{/if}} title="{{$item.vote.like.0}}" onclick="dolike({{$item.id}},'like'); return false"><i class="icon-thumbs-up icon-large"><span class="sr-only">{{$item.vote.like.0}}</span></i></a>
{{/if}}{{if $item.vote.dislike}}
- <a role="button" id="dislike-{{$item.id}}" title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false"><i class="icon-thumbs-down icon-large"><span class="sr-only">{{$item.vote.dislike.0}}</span></i></a>
+ <a role="button" id="dislike-{{$item.id}}"{{if $item.responses.dislike.self}} class="active"{{/if}} title="{{$item.vote.dislike.0}}" onclick="dolike({{$item.id}},'dislike'); return false"><i class="icon-thumbs-down icon-large"><span class="sr-only">{{$item.vote.dislike.0}}</span></i></a>
{{/if}}
{{if $item.vote.share}}
<a role="button" id="share-{{$item.id}}" title="{{$item.vote.share.0}}" onclick="jotShare({{$item.id}}); return false"><i class="icon-retweet icon-large"><span class="sr-only">{{$item.vote.share.0}}</span></i></a>
<a role="button" href="{{$item.edpost.0}}" title="{{$item.edpost.1}}"><i class="icon-edit icon-large"><span class="sr-only">{{$item.edpost.1}}</span></i></a>
{{/if}}
</div>
-
+
</div>
</div>
<div class="wall-item-bottom">
<div class="wall-item-{{$verb}}" id="wall-item-{{$verb}}-{{$item.id}}">{{$response.output}}</div>
{{/foreach}}
{{/if}}
-
+
</div>
-
+
{{if $item.threaded}}{{if $item.comment}}
<div class="wall-item-bottom">
<div class="wall-item-links">