From d4b2d3bf8a64e1fef8dbd88dbd625acbdef4a0df Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Wed, 13 Aug 2014 00:13:13 +0200 Subject: [PATCH 1/2] Moved "privacy_image_cache" into the core. Enabled by default, can be disabled in the page settings. --- include/api.php | 23 +-- include/bbcode.php | 2 +- include/conversation.php | 5 +- include/cronhooks.php | 2 +- include/oembed.php | 6 +- include/poller.php | 10 ++ include/text.php | 2 + mod/admin.php | 3 + mod/content.php | 26 +-- mod/directory.php | 10 +- mod/ping.php | 2 + mod/proxy.php | 307 ++++++++++++++++++++++++++++++++++ object/Item.php | 8 +- view/templates/admin_site.tpl | 1 + 14 files changed, 367 insertions(+), 40 deletions(-) create mode 100644 mod/proxy.php diff --git a/include/api.php b/include/api.php index 7cc72948d..b4b59068c 100644 --- a/include/api.php +++ b/include/api.php @@ -1641,21 +1641,16 @@ $a = get_app(); - $result = q("SELECT `installed` FROM `addon` WHERE `name` = 'privacy_image_cache' AND `installed`"); - $image_cache = (count($result) > 0); - $include_entities = strtolower(x($_REQUEST,'include_entities')?$_REQUEST['include_entities']:"false"); if ($include_entities != "true") { - if ($image_cache) { - require_once("addon/privacy_image_cache/privacy_image_cache.php"); + require_once("mod/proxy.php"); - preg_match_all("/\[img](.*?)\[\/img\]/ism", $bbcode, $images); + preg_match_all("/\[img](.*?)\[\/img\]/ism", $bbcode, $images); - foreach ($images[1] AS $image) { - $replace = $a->get_baseurl()."/privacy_image_cache/".privacy_image_cache_cachename($image); - $text = str_replace($image, $replace, $text); - } + foreach ($images[1] AS $image) { + $replace = proxy_url($image); + $text = str_replace($image, $replace, $text); } return array(); } @@ -1750,11 +1745,11 @@ require_once("include/Photo.php"); $image = get_photo_info($url); if ($image) { - // If privacy_image_cache is activated, then use the following sizes: + // If image cache is activated, then use the following sizes: // thumb (150), small (340), medium (600) and large (1024) - if ($image_cache) { - require_once("addon/privacy_image_cache/privacy_image_cache.php"); - $media_url = $a->get_baseurl()."/privacy_image_cache/".privacy_image_cache_cachename($url); + if (!get_config("system", "proxy_disabled")) { + require_once("mod/proxy.php"); + $media_url = proxy_url($url); $sizes = array(); $scale = scale_image($image[0], $image[1], 150); diff --git a/include/bbcode.php b/include/bbcode.php index df2c7101b..7cf8b71fe 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -145,7 +145,7 @@ function bb_cleanup_share($shared, $plaintext, $nolink) { if (isset($bookmark[1][0])) $link = $bookmark[1][0]; - if (strpos($shared[1],$title) !== false) + if (($title != "") AND (strpos($shared[1],$title) !== false)) $title = ""; // if (strpos($shared[1],$link) !== false) diff --git a/include/conversation.php b/include/conversation.php index 95792640e..558942063 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -370,6 +370,7 @@ if(!function_exists('conversation')) { function conversation(&$a, $items, $mode, $update, $preview = false) { require_once('include/bbcode.php'); + require_once('mod/proxy.php'); $ssl_state = ((local_user()) ? true : false); @@ -656,7 +657,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { 'name' => $profile_name_e, 'sparkle' => $sparkle, 'lock' => $lock, - 'thumb' => $profile_avatar, + 'thumb' => proxy_url($profile_avatar), 'title' => $item['title_e'], 'body' => $body_e, 'tags' => $tags_e, @@ -675,7 +676,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { 'indent' => '', 'owner_name' => $owner_name_e, 'owner_url' => $owner_url, - 'owner_photo' => $owner_photo, + 'owner_photo' => proxy_url($owner_photo), 'plink' => get_plink($item), 'edpost' => false, 'isstarred' => $isstarred, diff --git a/include/cronhooks.php b/include/cronhooks.php index 031011ac3..c0549dfff 100644 --- a/include/cronhooks.php +++ b/include/cronhooks.php @@ -40,7 +40,7 @@ function cronhooks_run(&$argv, &$argc){ $pidfile = new pidfile($lockpath, 'cronhooks'); if($pidfile->is_already_running()) { logger("cronhooks: Already running"); - if ($pidfile->running_time() > 9*60) { + if ($pidfile->running_time() > 19*60) { $pidfile->kill(); logger("cronhooks: killed stale process"); // Calling a new instance diff --git a/include/oembed.php b/include/oembed.php index 29d462d8f..4a95bd8a4 100755 --- a/include/oembed.php +++ b/include/oembed.php @@ -109,6 +109,8 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){ } 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) ); @@ -138,8 +140,8 @@ function oembed_format_object($j){ $ret.="
"; }; break; case "photo": { - $ret.= ""; - //$ret.= ""; + $ret.= ""; + //$ret.= ""; $ret.="
"; }; break; case "link": { diff --git a/include/poller.php b/include/poller.php index 46f1079fd..e94ab8746 100644 --- a/include/poller.php +++ b/include/poller.php @@ -134,6 +134,16 @@ function poller_run(&$argv, &$argc){ // clear smarty cache clear_cache($a->get_basepath()."/view/smarty3/compiled", $a->get_basepath()."/view/smarty3/compiled"); + // clear cache for image proxy + if (!get_config("system", "proxy_disabled")) { + clear_cache($a->get_basepath(), $a->get_basepath()."/proxy"); + + $cachetime = get_config('system','proxy_cache_time'); + if (!$cachetime) $cachetime = PROXY_DEFAULT_TIME; + + q('DELETE FROM `photo` WHERE `uid` = 0 AND `resource-id` LIKE "pic:%%" AND `created` < NOW() - INTERVAL %d SECOND', $cachetime); + } + set_config('system','cache_last_cleared', time()); } diff --git a/include/text.php b/include/text.php index 26de709e3..c7d6f4d52 100644 --- a/include/text.php +++ b/include/text.php @@ -1353,6 +1353,8 @@ function prepare_body(&$item,$attach = false, $preview = false) { $s = prepare_text($item['body']); } + require_once("mod/proxy.php"); + $s = proxy_parse_html($s); $prep_arr = array('item' => $item, 'html' => $s, 'preview' => $preview); call_hooks('prepare_body', $prep_arr); diff --git a/mod/admin.php b/mod/admin.php index a7e66876c..55bbde34d 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -361,6 +361,7 @@ function admin_page_site_post(&$a){ $temppath = ((x($_POST,'temppath')) ? notags(trim($_POST['temppath'])) : ''); $basepath = ((x($_POST,'basepath')) ? notags(trim($_POST['basepath'])) : ''); $singleuser = ((x($_POST,'singleuser')) ? notags(trim($_POST['singleuser'])) : ''); + $proxy_disabled = ((x($_POST,'proxy_disabled')) ? True : False); if($ssl_policy != intval(get_config('system','ssl_policy'))) { if($ssl_policy == SSL_POLICY_FULL) { q("update `contact` set @@ -484,6 +485,7 @@ function admin_page_site_post(&$a){ set_config('system','lockpath', $lockpath); set_config('system','temppath', $temppath); set_config('system','basepath', $basepath); + set_config('system','proxy_disabled', $proxy_disabled); info( t('Site settings updated.') . EOL); goaway($a->get_baseurl(true) . '/admin/site' ); @@ -642,6 +644,7 @@ function admin_page_site(&$a) { '$lockpath' => array('lockpath', t("Path for lock file"), get_config('system','lockpath'), "The lock file is used to avoid multiple pollers at one time. Only define a folder here."), '$temppath' => array('temppath', t("Temp path"), get_config('system','temppath'), "If you have a restricted system where the webserver can't access the system temp path, enter another path here."), '$basepath' => array('basepath', t("Base path to installation"), get_config('system','basepath'), "If the system cannot detect the correct path to your installation, enter the correct path here. This setting should only be set if you are using a restricted system and symbolic links to your webroot."), + '$proxy_disabled' => array('proxy_disabled', t("Disable picture proxy"), get_config('system','proxy_disabled'), t("The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith.")), '$relocate_url' => array('relocate_url', t("New base url"), $a->get_baseurl(), "Change base url for this server. Sends relocate message to all DFRN contacts of all users."), diff --git a/mod/content.php b/mod/content.php index fa32b576c..1e44bf160 100644 --- a/mod/content.php +++ b/mod/content.php @@ -307,8 +307,8 @@ function content_content(&$a, $update = 0) { function render_content(&$a, $items, $mode, $update, $preview = false) { - require_once('include/bbcode.php'); + require_once('mod/proxy.php'); $ssl_state = ((local_user()) ? true : false); @@ -361,8 +361,8 @@ function render_content(&$a, $items, $mode, $update, $preview = false) { $alike = array(); $dlike = array(); - - + + // array with html for each thread (parent+comments) $threads = array(); $threadsid = -1; @@ -412,7 +412,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) { if($sp) $sparkle = ' sparkle'; else - $profile_link = zrl($profile_link); + $profile_link = zrl($profile_link); $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']); if(($normalised != 'mailbox') && (x($a->contacts[$normalised]))) @@ -440,7 +440,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) { $star = false; $isstarred = "unstarred"; - + $lock = false; $likebuttons = false; $shareable = false; @@ -463,7 +463,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) { $location_e = $location; $owner_name_e = $owner_name; } - + //$tmp_item = replace_macros($tpl,array( $tmp_item = array( 'template' => $tpl, @@ -474,7 +474,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) { 'name' => $name_e, 'sparkle' => $sparkle, 'lock' => $lock, - 'thumb' => $profile_avatar, + 'thumb' => proxy_url($profile_avatar), 'title' => $title_e, 'body' => $body_e, 'text' => $text_e, @@ -483,7 +483,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) { 'indent' => '', 'owner_name' => $owner_name_e, 'owner_url' => $owner_url, - 'owner_photo' => $owner_photo, + 'owner_photo' => proxy_url($owner_photo), 'plink' => get_plink($item), 'edpost' => false, 'isstarred' => $isstarred, @@ -591,7 +591,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) { $comments_seen ++; $comment_lastcollapsed = false; $comment_firstcollapsed = false; - } + } $override_comment_box = ((($page_writeable) && ($item_writeable)) ? true : false); $show_comment_box = ((($page_writeable) && ($item_writeable) && ($comments_seen == $comments[$item['parent']])) ? true : false); @@ -783,7 +783,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) { if($sp) $sparkle = ' sparkle'; else - $profile_link = zrl($profile_link); + $profile_link = zrl($profile_link); $normalised = normalise_link((strlen($item['author-link'])) ? $item['author-link'] : $item['url']); if(($normalised != 'mailbox') && (x($a->contacts,$normalised))) @@ -843,7 +843,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) { 'comment_lastcollapsed' => $comment_lastcollapsed, // template to use to render item (wall, walltowall, search) 'template' => $template, - + 'type' => implode("",array_slice(explode("/",$item['verb']),-1)), 'tags' => $tags, 'body' => $body_e, @@ -857,7 +857,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) { 'profile_url' => $profile_link, 'item_photo_menu' => item_photo_menu($item), 'name' => $name_e, - 'thumb' => $profile_avatar, + 'thumb' => proxy_url($profile_avatar), 'osparkle' => $osparkle, 'sparkle' => $sparkle, 'title' => $title_e, @@ -867,7 +867,7 @@ function render_content(&$a, $items, $mode, $update, $preview = false) { 'indent' => $indent, 'shiny' => $shiny, 'owner_url' => $owner_url, - 'owner_photo' => $owner_photo, + 'owner_photo' => proxy_url($owner_photo), 'owner_name' => $owner_name_e, 'plink' => get_plink($item), 'edpost' => $edpost, diff --git a/mod/directory.php b/mod/directory.php index 3e138570c..7fab53b68 100644 --- a/mod/directory.php +++ b/mod/directory.php @@ -27,6 +27,8 @@ function directory_post(&$a) { function directory_content(&$a) { + require_once("mod/proxy.php"); + if((get_config('system','block_public')) && (! local_user()) && (! remote_user())) { notice( t('Public access denied.') . EOL); return; @@ -90,7 +92,7 @@ function directory_content(&$a) { $profile_link = $a->get_baseurl() . '/profile/' . ((strlen($rr['nickname'])) ? $rr['nickname'] : $rr['profile_uid']); - + $pdesc = (($rr['pdesc']) ? $rr['pdesc'] . '
' : ''); $details = ''; @@ -140,7 +142,7 @@ function directory_content(&$a) { $homepage = ((x($profile,'homepage') == 1) ? t('Homepage:') : False); $about = ((x($profile,'about') == 1) ? t('About:') : False); - + $tpl = get_markup_template('directory_item.tpl'); if($a->theme['template_engine'] === 'internal') { @@ -153,7 +155,7 @@ function directory_content(&$a) { $entry = replace_macros($tpl,array( '$id' => $rr['id'], '$profile_link' => $profile_link, - '$photo' => $a->get_cached_avatar_image($rr[$photo]), + '$photo' => proxy_url($a->get_cached_avatar_image($rr[$photo])), '$alt_text' => $rr['name'], '$name' => $rr['name'], '$details' => $pdesc . $details, @@ -171,7 +173,7 @@ function directory_content(&$a) { $arr = array('contact' => $rr, 'entry' => $entry); call_hooks('directory_item', $arr); - + unset($profile); unset($location); diff --git a/mod/ping.php b/mod/ping.php index 21154f9ff..405edd3c4 100644 --- a/mod/ping.php +++ b/mod/ping.php @@ -188,6 +188,8 @@ function ping_init(&$a) { function xmlize($href, $name, $url, $photo, $date, $seen, $message){ + require_once("mod/proxy.php"); + $photo = proxy_url($photo); $data = array('href' => &$href, 'name' => &$name, 'url'=>&$url, 'photo'=>&$photo, 'date'=>&$date, 'seen'=>&$seen, 'messsage'=>&$message); call_hooks('ping_xmlize', $data); $notsxml = '%s'; diff --git a/mod/proxy.php b/mod/proxy.php new file mode 100644 index 000000000..77515bb88 --- /dev/null +++ b/mod/proxy.php @@ -0,0 +1,307 @@ + + +define("PROXY_DEFAULT_TIME", 86400); // 1 Day + +require_once('include/security.php'); +require_once("include/Photo.php"); + +function proxy_init() { + global $a, $_SERVER; + + // Pictures are stored in one of the following ways: + // 1. If a folder "proxy" exists and is writeable, then use this for caching + // 2. If a cache path is defined, use this + // 3. If everything else failed, cache into the database + // + // Question: Do we really need these three methods? + + if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { + header('HTTP/1.1 304 Not Modified'); + header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT"); + header('Etag: '.$_SERVER['HTTP_IF_NONE_MATCH']); + header("Expires: " . gmdate("D, d M Y H:i:s", time() + (31536000)) . " GMT"); + header("Cache-Control: max-age=31536000"); + if(function_exists('header_remove')) { + header_remove('Last-Modified'); + header_remove('Expires'); + header_remove('Cache-Control'); + } + exit; + } + + if(function_exists('header_remove')) { + header_remove('Pragma'); + header_remove('pragma'); + } + + $thumb = false; + $size = 1024; + + // If the cache path isn't there, try to create it + if (!is_dir($_SERVER["DOCUMENT_ROOT"]."/proxy")) + if (is_writable($_SERVER["DOCUMENT_ROOT"])) + mkdir($_SERVER["DOCUMENT_ROOT"]."/proxy"); + + // Checking if caching into a folder in the webroot is activated and working + $direct_cache = (is_dir($_SERVER["DOCUMENT_ROOT"]."/proxy") AND is_writable($_SERVER["DOCUMENT_ROOT"]."/proxy")); + + // Look for filename in the arguments + if (isset($a->argv[1]) OR isset($a->argv[2]) OR isset($a->argv[3])) { + if (isset($a->argv[3])) + $url = $a->argv[3]; + elseif (isset($a->argv[2])) + $url = $a->argv[2]; + else + $url = $a->argv[1]; + + if (isset($a->argv[3]) and ($a->argv[3] == "thumb")) + $size = 200; + + // thumb, small, medium and large. + if (substr($url, -6) == ":thumb") + $size = 150; + if (substr($url, -6) == ":small") + $size = 340; + if (substr($url, -7) == ":medium") + $size = 600; + if (substr($url, -6) == ":large") + $size = 1024; + + $pos = strrpos($url, "=."); + if ($pos) + $url = substr($url, 0, $pos+1); + + $url = str_replace(array(".jpg", ".jpeg", ".gif", ".png"), array("","","",""), $url); + + $url = base64_decode(strtr($url, '-_', '+/'), true); + + if ($url) + $_REQUEST['url'] = $url; + } + + if (!$direct_cache) { + $urlhash = 'pic:' . sha1($_REQUEST['url']); + + $cachefile = get_cachefile(hash("md5", $_REQUEST['url'])); + if ($cachefile != '') { + if (file_exists($cachefile)) { + $img_str = file_get_contents($cachefile); + $mime = image_type_to_mime_type(exif_imagetype($cachefile)); + + header("Content-type: $mime"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT"); + header('Etag: "'.md5($img_str).'"'); + header("Expires: " . gmdate("D, d M Y H:i:s", time() + (31536000)) . " GMT"); + header("Cache-Control: max-age=31536000"); + + // reduce quality - if it isn't a GIF + if ($mime != "image/gif") { + $img = new Photo($img_str, $mime); + if($img->is_valid()) { + $img_str = $img->imageString(); + } + } + + echo $img_str; + killme(); + } + } + } else + $cachefile = ""; + + $valid = true; + + if (!$direct_cache AND ($cachefile == "")) { + $r = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' LIMIT 1", $urlhash); + if (count($r)) { + $img_str = $r[0]['data']; + $mime = $r[0]["desc"]; + if ($mime == "") $mime = "image/jpeg"; + } + } else + $r = array(); + + if (!count($r)) { + // It shouldn't happen but it does - spaces in URL + $_REQUEST['url'] = str_replace(" ", "+", $_REQUEST['url']); + $redirects = 0; + $img_str = fetch_url($_REQUEST['url'],true, $redirects, 10); + + $tempfile = tempnam(get_temppath(), "cache"); + file_put_contents($tempfile, $img_str); + $mime = image_type_to_mime_type(exif_imagetype($tempfile)); + unlink($tempfile); + + // If there is an error then return a blank image + if ((substr($a->get_curl_code(), 0, 1) == "4") or (!$img_str)) { + $img_str = file_get_contents("images/blank.png"); + $mime = "image/png"; + $cachefile = ""; // Clear the cachefile so that the dummy isn't stored + $valid = false; + $img = new Photo($img_str, "image/png"); + if($img->is_valid()) { + $img->scaleImage(10); + $img_str = $img->imageString(); + } + } else if (($mime != "image/jpeg") AND !$direct_cache AND ($cachefile == "")) { + $image = @imagecreatefromstring($img_str); + + if($image === FALSE) die(); + + q("INSERT INTO `photo` + ( `uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, `album`, `height`, `width`, `desc`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` ) + VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', '%s', '%s' )", + 0, 0, get_guid(), dbesc($urlhash), + dbesc(datetime_convert()), + dbesc(datetime_convert()), + dbesc(basename(dbesc($_REQUEST["url"]))), + dbesc(''), + intval(imagesy($image)), + intval(imagesx($image)), + $mime, + dbesc($img_str), + 100, + intval(0), + dbesc(''), dbesc(''), dbesc(''), dbesc('') + ); + + } else { + $img = new Photo($img_str, $mime); + if($img->is_valid()) { + if (!$direct_cache AND ($cachefile == "")) + $img->store(0, 0, $urlhash, $_REQUEST['url'], '', 100); + } + } + } + + // reduce quality - if it isn't a GIF + if ($mime != "image/gif") { + $img = new Photo($img_str, $mime); + if($img->is_valid()) { + $img->scaleImage($size); + $img_str = $img->imageString(); + } + } + + // If there is a real existing directory then put the cache file there + // advantage: real file access is really fast + // Otherwise write in cachefile + if ($valid AND $direct_cache) + file_put_contents($_SERVER["DOCUMENT_ROOT"]."/proxy/".proxy_url($_REQUEST['url'], true), $img_str); + elseif ($cachefile != '') + file_put_contents($cachefile, $img_str); + + header("Content-type: $mime"); + + // Only output the cache headers when the file is valid + if ($valid) { + header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT"); + header('Etag: "'.md5($img_str).'"'); + header("Expires: " . gmdate("D, d M Y H:i:s", time() + (31536000)) . " GMT"); + header("Cache-Control: max-age=31536000"); + } + + echo $img_str; + + killme(); +} + +function proxy_url($url, $writemode = false) { + global $_SERVER; + + // Only continue if it isn't a local image and the isn't deactivated + if (get_config("system", "proxy_disabled") OR proxy_is_local_image($url)) + return($url); + + $a = get_app(); + + // Creating a sub directory to reduce the amount of files in the cache directory + $basepath = $_SERVER["DOCUMENT_ROOT"]."/proxy"; + + $path = substr(hash("md5", $url), 0, 2); + + if (is_dir($basepath) and $writemode) + if (!is_dir($basepath."/".$path)) { + mkdir($basepath."/".$path); + chmod($basepath."/".$path, 0777); + } + + $path .= "/".strtr(base64_encode($url), '+/', '-_'); + + // Checking for valid extensions. Only add them if they are safe + $pos = strrpos($url, "."); + if ($pos) { + $extension = strtolower(substr($url, $pos+1)); + $pos = strpos($extension, "?"); + if ($pos) + $extension = substr($extension, 0, $pos); + } + + $extensions = array("jpg", "jpeg", "gif", "png"); + + if (in_array($extension, $extensions)) + $path .= ".".$extension; + + $proxypath = $a->get_baseurl()."/proxy/".$path; + + // Too long files aren't supported by Apache + if (strlen($proxypath) > 250) + return ($url); + elseif ($writemode) + return ($path); + else + return ($proxypath); +} + +/** + * @param $url string + * @return boolean + */ +function proxy_is_local_image($url) { + if ($url[0] == '/') return true; + + if (strtolower(substr($url, 0, 5)) == "data:") return true; + + // links normalised - bug #431 + $baseurl = normalise_link(get_app()->get_baseurl()); + $url = normalise_link($url); + return (substr($url, 0, strlen($baseurl)) == $baseurl); +} + +function proxy_parse_query($var) { + /** + * Use this function to parse out the query array element from + * the output of parse_url(). + */ + $var = parse_url($var, PHP_URL_QUERY); + $var = html_entity_decode($var); + $var = explode('&', $var); + $arr = array(); + + foreach($var as $val) { + $x = explode('=', $val); + $arr[$x[0]] = $x[1]; + } + + unset($val, $x, $var); + return $arr; +} + +function proxy_img_cb($matches) { + + // if the picture seems to be from another picture cache then take the original source + $queryvar = proxy_parse_query($matches[2]); + if (($queryvar['url'] != "") AND (substr($queryvar['url'], 0, 4) == "http")) + $matches[2] = urldecode($queryvar['url']); + + // following line changed per bug #431 + if (proxy_is_local_image($matches[2])) + return $matches[1] . $matches[2] . $matches[3]; + + return $matches[1].proxy_url(htmlspecialchars_decode($matches[2])).$matches[3]; +} + +function proxy_parse_html($html) { + return preg_replace_callback("/(]*src *= *[\"'])([^\"']+)([\"'][^>]*>)/siU", "proxy_img_cb", $html); +} diff --git a/object/Item.php b/object/Item.php index 7c78a1d33..246fecc18 100644 --- a/object/Item.php +++ b/object/Item.php @@ -81,6 +81,8 @@ class Item extends BaseObject { * _ false on failure */ public function get_template_data($alike, $dlike, $thread_level=1) { + require_once("mod/proxy.php"); + $result = array(); $a = $this->get_app(); @@ -314,7 +316,7 @@ class Item extends BaseObject { 'profile_url' => $profile_link, 'item_photo_menu' => item_photo_menu($item), 'name' => $name_e, - 'thumb' => $profile_avatar, + 'thumb' => proxy_url($profile_avatar), 'osparkle' => $osparkle, 'sparkle' => $sparkle, 'title' => $title_e, @@ -327,7 +329,7 @@ class Item extends BaseObject { 'indent' => $indent, 'shiny' => $shiny, 'owner_url' => $this->get_owner_url(), - 'owner_photo' => $this->get_owner_photo(), + 'owner_photo' => proxy_url($this->get_owner_photo()), 'owner_name' => $owner_name_e, 'plink' => get_plink($item), 'edpost' => ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''), @@ -687,7 +689,7 @@ class Item extends BaseObject { $a = $this->get_app(); $conv = $this->get_conversation(); $this->wall_to_wall = false; - + if($this->is_toplevel()) { if( (! $this->get_data_value('self')) && ($conv->get_mode() !== 'profile')) { if($this->get_data_value('wall')) { diff --git a/view/templates/admin_site.tpl b/view/templates/admin_site.tpl index 835b027fe..5303ac481 100644 --- a/view/templates/admin_site.tpl +++ b/view/templates/admin_site.tpl @@ -112,6 +112,7 @@ {{include file="field_input.tpl" field=$itemcache}} {{include file="field_input.tpl" field=$itemcache_duration}} {{include file="field_input.tpl" field=$max_comments}} + {{include file="field_checkbox.tpl" field=$proxy_disabled}}
From 271a184e1e16a53116be8fff676cf0b72afa563c Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Sat, 16 Aug 2014 01:40:38 +0200 Subject: [PATCH 2/2] proxy: Added support for long addresses. "vier": New style "Plus" --- mod/proxy.php | 28 ++-- view/theme/vier/config.php | 3 +- view/theme/vier/css/font2.css | 7 +- view/theme/vier/plus.css | 141 +++++++++++++++++++++ view/theme/vier/style.css | 1 + view/theme/vier/templates/comment_item.tpl | 4 +- view/theme/vier/theme.php | 6 + 7 files changed, 176 insertions(+), 14 deletions(-) create mode 100644 view/theme/vier/plus.css diff --git a/mod/proxy.php b/mod/proxy.php index 77515bb88..d82d334ce 100644 --- a/mod/proxy.php +++ b/mod/proxy.php @@ -47,7 +47,7 @@ function proxy_init() { $direct_cache = (is_dir($_SERVER["DOCUMENT_ROOT"]."/proxy") AND is_writable($_SERVER["DOCUMENT_ROOT"]."/proxy")); // Look for filename in the arguments - if (isset($a->argv[1]) OR isset($a->argv[2]) OR isset($a->argv[3])) { + if ((isset($a->argv[1]) OR isset($a->argv[2]) OR isset($a->argv[3])) AND !isset($_REQUEST["url"])) { if (isset($a->argv[3])) $url = $a->argv[3]; elseif (isset($a->argv[2])) @@ -78,7 +78,8 @@ function proxy_init() { if ($url) $_REQUEST['url'] = $url; - } + } else + $direct_cache = false; if (!$direct_cache) { $urlhash = 'pic:' . sha1($_REQUEST['url']); @@ -210,12 +211,17 @@ function proxy_init() { function proxy_url($url, $writemode = false) { global $_SERVER; - // Only continue if it isn't a local image and the isn't deactivated - if (get_config("system", "proxy_disabled") OR proxy_is_local_image($url)) - return($url); - $a = get_app(); + // Only continue if it isn't a local image and the isn't deactivated + if (proxy_is_local_image($url)) { + $url = str_replace(normalise_link($a->get_baseurl())."/", $a->get_baseurl()."/", $url); + return($url); + } + + if (get_config("system", "proxy_disabled")) + return($url); + // Creating a sub directory to reduce the amount of files in the cache directory $basepath = $_SERVER["DOCUMENT_ROOT"]."/proxy"; @@ -246,8 +252,11 @@ function proxy_url($url, $writemode = false) { $proxypath = $a->get_baseurl()."/proxy/".$path; // Too long files aren't supported by Apache - if (strlen($proxypath) > 250) - return ($url); + // Writemode in combination with long files shouldn't be possible + if ((strlen($proxypath) > 250) AND $writemode) + return (hash("md5", $url)); + elseif (strlen($proxypath) > 250) + return ($a->get_baseurl()."/proxy/".hash("md5", $url)."?url=".urlencode($url)); elseif ($writemode) return ($path); else @@ -303,5 +312,8 @@ function proxy_img_cb($matches) { } function proxy_parse_html($html) { + $a = get_app(); + $html = str_replace(normalise_link($a->get_baseurl())."/", $a->get_baseurl()."/", $html); + return preg_replace_callback("/(]*src *= *[\"'])([^\"']+)([\"'][^>]*>)/siU", "proxy_img_cb", $html); } diff --git a/view/theme/vier/config.php b/view/theme/vier/config.php index 8736dfe84..286639d28 100644 --- a/view/theme/vier/config.php +++ b/view/theme/vier/config.php @@ -44,7 +44,8 @@ function vier_form(&$a, $style){ "shadow"=>"Shadow", "flat"=>"Flat", "netcolour"=>"Coloured Networks", - "breathe"=>"Breathe" + "breathe"=>"Breathe", + "plus"=>"Plus" ); $t = get_markup_template("theme_settings.tpl" ); $o .= replace_macros($t, array( diff --git a/view/theme/vier/css/font2.css b/view/theme/vier/css/font2.css index a0afe8c04..093982508 100644 --- a/view/theme/vier/css/font2.css +++ b/view/theme/vier/css/font2.css @@ -140,7 +140,8 @@ li.icon.icon-large:before { .icon-bookmark:before { content: "\f02e"; } .icon-print:before { content: "\f02f"; } -.icon.camera:before { content: "\f030"; } +.icon-camera:before { content: "\f030"; } +.icon.camera:before { content: "\f03e"; } .icon-font:before { content: "\f031"; } .icon-bold:before { content: "\f032"; } .icon-italic:before { content: "\f033"; } @@ -198,7 +199,7 @@ li.icon.icon-large:before { .icon.add:before { content: "\f067"; } .icon-minus:before { content: "\f068"; } .icon-asterisk:before { content: "\f069"; } -.icon.notify:before { content: "\f06a"; } +.icon.exclamation:before { content: "\f06a"; } .icon-gift:before { content: "\f06b"; } .icon-leaf:before { content: "\f06c"; } .icon-fire:before { content: "\f06d"; } @@ -254,7 +255,7 @@ li.icon.icon-large:before { .icon-hdd:before { content: "\f0a0"; } .icon-bullhorn:before { content: "\f0a1"; } -.icon-bell:before { content: "\f0a2"; } +.icon.notify:before { content: "\f0a2"; } .icon-certificate:before { content: "\f0a3"; } .icon-hand-right:before { content: "\f0a4"; } .icon-hand-left:before { content: "\f0a5"; } diff --git a/view/theme/vier/plus.css b/view/theme/vier/plus.css new file mode 100644 index 000000000..baaffb899 --- /dev/null +++ b/view/theme/vier/plus.css @@ -0,0 +1,141 @@ +nav { + background: #fff; + box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.15); + padding-top: 6px; + padding-bottom: 6px; +} + +nav a:active, +nav a:link, +nav a:visited, +nav a { + color: #737373; +} + +nav a:hover, +#nav-messages-see-all a:hover { + color: #000; +} + +nav .nav-notify { +/* background-color: #427FED; */ + background-color: #CB4437; + top: -3px; + right: -4px; + font: bold 11px/16px Arial; + padding: 1px; + border-radius: 10px; +} + +nav .nav-menu-icon .nav-notify { + top: 0px; +} + +nav .nav-menu.selected a { + color: #000; +/* font-weight: bold; */ +} + +nav .nav-menu:hover, +nav .nav-menu.selected { + border-bottom: 2px solid #427FED; +} + +nav .nav-menu { + height: 23px; + font-size: 14px; + font-weight: initial; +} + +#nav-site-menu, +#nav-notifications-menu, +#nav-user-menu { + top: 35px; +} + +#nav-messages-menu { + top: 32px; +} + +#nav-messages-see-all a { + color: #737373; +} + +ul.tabs li .active, span.pager_current a { + border-bottom: 2px solid #427FED; +} + +span.pager_current, span.pager_n a:hover, +span.pager_first a:hover, span.pager_last a:hover, +span.pager_prev a:hover, span.pager_next a:hover, +ul.tabs a:hover { + border-bottom: 2px solid #427FED; +} + +nav #nav-notifications-linkmenu.on .icon.s22.notify, nav #nav-notifications-linkmenu.selected .icon.s22.notify { + color: #737373; +} + +nav #nav-messages-linkmenu.selected, +nav #nav-user-linklabel.selected, +nav #nav-apps-link.selected { + background-color: #fff; + border-bottom-style: none; +} + +div.jGrowl div.info { + background: #fff url("../../../images/icons/48/info.png") no-repeat 5px center; +} + +nav .nav-menu-icon.selected { + background-color: #fff; +} + +#jot #jot-tools li:hover { + background-color: #fff; +} + +nav .icon { + color: #737373; +} + +nav a:hover .icon { + color: #000; +} + +ul.menu-popup { + border: 0px solid #FFF; + margin-top: 0px; +} + +header #banner a, header #banner a:active, header #banner a:visited, header #banner a:link, header #banner a:hover { + color: #737373; +} + +header { + left: 10px; +} + +header #banner { + margin-top: 6px; +} + +#banner #logo-text { + margin-left: 5px; +} + +aside { + top: 44px; + height: calc(100% - 54px); +} + +section { + top: 44px; +} + +nav #search-box #search-text { + background-color: initial; + border-style: solid; + border-width: 1px; + border-color: rgba(0, 0, 0, 0.15); +} diff --git a/view/theme/vier/style.css b/view/theme/vier/style.css index 3fec53fcf..88f310b26 100644 --- a/view/theme/vier/style.css +++ b/view/theme/vier/style.css @@ -1987,6 +1987,7 @@ ul.tabs li .active, span.pager_current a { .comment-edit-bb a { color: #888; padding: 0px 5px 1px 5px; + cursor: pointer; } .comment-edit-bb a:hover { diff --git a/view/theme/vier/templates/comment_item.tpl b/view/theme/vier/templates/comment_item.tpl index 7cbc02e06..833cf1828 100644 --- a/view/theme/vier/templates/comment_item.tpl +++ b/view/theme/vier/templates/comment_item.tpl @@ -36,13 +36,13 @@
- + - +
diff --git a/view/theme/vier/theme.php b/view/theme/vier/theme.php index 928ab6c8b..779a5ce4a 100644 --- a/view/theme/vier/theme.php +++ b/view/theme/vier/theme.php @@ -26,11 +26,17 @@ else if ($style == "netcolour") $a->page['htmlhead'] .= ''."\n"; else if ($style == "breathe") $a->page['htmlhead'] .= ''."\n"; +else if ($style == "plus") + $a->page['htmlhead'] .= ''."\n"; $a->page['htmlhead'] .= <<< EOT