2011-08-02 01:51:01 +02:00
|
|
|
<?php
|
2017-12-04 14:33:49 +01:00
|
|
|
/**
|
|
|
|
* @file include/text.php
|
|
|
|
*/
|
2018-01-25 03:08:45 +01:00
|
|
|
|
2017-04-30 06:07:00 +02:00
|
|
|
use Friendica\App;
|
2018-01-10 04:42:04 +01:00
|
|
|
use Friendica\Content\ContactSelector;
|
2017-12-04 15:04:36 +01:00
|
|
|
use Friendica\Content\Feature;
|
2017-11-11 13:21:15 +01:00
|
|
|
use Friendica\Content\Smilies;
|
2018-02-15 03:33:55 +01:00
|
|
|
use Friendica\Content\Text\BBCode;
|
2018-01-17 19:42:40 +01:00
|
|
|
use Friendica\Core\Addon;
|
2017-11-07 03:22:52 +01:00
|
|
|
use Friendica\Core\Config;
|
2018-01-21 19:33:59 +01:00
|
|
|
use Friendica\Core\L10n;
|
2017-11-07 03:22:52 +01:00
|
|
|
use Friendica\Core\PConfig;
|
2017-08-26 08:04:21 +02:00
|
|
|
use Friendica\Core\System;
|
2017-11-08 04:57:46 +01:00
|
|
|
use Friendica\Database\DBM;
|
2018-05-19 16:55:27 +02:00
|
|
|
use Friendica\Model\Contact;
|
2018-03-17 02:45:02 +01:00
|
|
|
use Friendica\Model\Event;
|
2018-02-07 21:22:40 +01:00
|
|
|
use Friendica\Model\Item;
|
2018-01-15 03:22:39 +01:00
|
|
|
use Friendica\Model\Profile;
|
2018-02-15 03:33:55 +01:00
|
|
|
use Friendica\Render\FriendicaSmarty;
|
2018-01-27 03:38:34 +01:00
|
|
|
use Friendica\Util\DateTimeFormat;
|
2017-12-13 22:37:34 +01:00
|
|
|
use Friendica\Util\Map;
|
2017-04-30 06:07:00 +02:00
|
|
|
|
2017-05-17 18:28:00 +02:00
|
|
|
require_once "mod/proxy.php";
|
2017-11-29 22:27:39 +01:00
|
|
|
require_once "include/conversation.php";
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* This is our template processor
|
2014-07-30 15:23:36 +02:00
|
|
|
*
|
|
|
|
* @param string|FriendicaSmarty $s the string requiring macro substitution,
|
2016-11-29 07:40:35 +01:00
|
|
|
* or an instance of FriendicaSmarty
|
2013-03-27 10:11:40 +01:00
|
|
|
* @param array $r key value pairs (search => replace)
|
|
|
|
* @return string substituted string
|
|
|
|
*/
|
2017-05-17 18:28:00 +02:00
|
|
|
function replace_macros($s, $r) {
|
2013-12-08 20:10:28 +01:00
|
|
|
|
2013-01-26 16:46:43 +01:00
|
|
|
$stamp1 = microtime(true);
|
|
|
|
|
2012-12-22 20:57:29 +01:00
|
|
|
$a = get_app();
|
2016-01-14 21:56:37 +01:00
|
|
|
|
2015-11-13 10:56:37 +01:00
|
|
|
// pass $baseurl to all templates
|
2017-08-26 09:32:10 +02:00
|
|
|
$r['$baseurl'] = System::baseUrl();
|
2016-01-14 21:56:37 +01:00
|
|
|
|
2013-03-27 15:37:59 +01:00
|
|
|
$t = $a->template_engine();
|
2013-06-13 14:12:15 +02:00
|
|
|
try {
|
2017-11-19 16:22:18 +01:00
|
|
|
$output = $t->replaceMacros($s, $r);
|
2013-06-13 14:12:15 +02:00
|
|
|
} catch (Exception $e) {
|
2017-05-17 18:28:00 +02:00
|
|
|
echo "<pre><b>" . __FUNCTION__ . "</b>: " . $e->getMessage() . "</pre>";
|
|
|
|
killme();
|
2013-06-13 14:12:15 +02:00
|
|
|
}
|
2013-01-26 16:46:43 +01:00
|
|
|
|
2013-01-27 13:57:44 +01:00
|
|
|
$a->save_timestamp($stamp1, "rendering");
|
2013-01-26 16:46:43 +01:00
|
|
|
|
2012-12-22 20:57:29 +01:00
|
|
|
return $output;
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2017-11-26 03:15:50 +01:00
|
|
|
/**
|
|
|
|
* @brief Generates a pseudo-random string of hexadecimal characters
|
|
|
|
*
|
|
|
|
* @param int $size
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
function random_string($size = 64)
|
|
|
|
{
|
2017-11-26 13:57:29 +01:00
|
|
|
$byte_size = ceil($size / 2);
|
|
|
|
|
|
|
|
$bytes = random_bytes($byte_size);
|
2011-08-11 06:06:35 +02:00
|
|
|
|
2017-11-26 13:57:29 +01:00
|
|
|
$return = substr(bin2hex($bytes), 0, $size);
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2017-11-26 03:15:50 +01:00
|
|
|
return $return;
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
/**
|
2013-12-08 20:10:28 +01:00
|
|
|
* This is our primary input filter.
|
2011-08-02 01:51:01 +02:00
|
|
|
*
|
|
|
|
* The high bit hack only involved some old IE browser, forget which (IE5/Mac?)
|
|
|
|
* that had an XSS attack vector due to stripping the high-bit on an 8-bit character
|
|
|
|
* after cleansing, and angle chars with the high bit set could get through as markup.
|
2014-07-30 15:23:36 +02:00
|
|
|
*
|
|
|
|
* This is now disabled because it was interfering with some legitimate unicode sequences
|
|
|
|
* and hopefully there aren't a lot of those browsers left.
|
2011-08-02 01:51:01 +02:00
|
|
|
*
|
|
|
|
* Use this on any text input where angle chars are not valid or permitted
|
|
|
|
* They will be replaced with safer brackets. This may be filtered further
|
2014-07-30 15:23:36 +02:00
|
|
|
* if these are not allowed either.
|
2011-08-02 01:51:01 +02:00
|
|
|
*
|
2013-03-27 10:11:40 +01:00
|
|
|
* @param string $string Input string
|
|
|
|
* @return string Filtered string
|
2011-08-02 01:51:01 +02:00
|
|
|
*/
|
|
|
|
function notags($string) {
|
2018-01-15 14:05:12 +01:00
|
|
|
return str_replace(["<", ">"], ['[', ']'], $string);
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
// High-bit filter no longer used
|
2017-11-11 07:42:39 +01:00
|
|
|
// return str_replace(array("<",">","\xBA","\xBC","\xBE"), array('[',']','','',''), $string);
|
|
|
|
}
|
2013-03-27 10:11:40 +01:00
|
|
|
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* use this on "body" or "content" input where angle chars shouldn't be removed,
|
|
|
|
* and allow them to be safely displayed.
|
|
|
|
* @param string $string
|
|
|
|
* @return string
|
|
|
|
*/
|
2011-08-02 01:51:01 +02:00
|
|
|
function escape_tags($string) {
|
2017-05-17 18:28:00 +02:00
|
|
|
return htmlspecialchars($string, ENT_COMPAT, 'UTF-8', false);
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
2014-07-30 15:23:36 +02:00
|
|
|
* generate a string that's random, but usually pronounceable.
|
2013-03-27 10:11:40 +01:00
|
|
|
* used to generate initial passwords
|
|
|
|
* @param int $len
|
|
|
|
* @return string
|
|
|
|
*/
|
2011-08-02 01:51:01 +02:00
|
|
|
function autoname($len) {
|
|
|
|
|
2017-05-17 18:28:00 +02:00
|
|
|
if ($len <= 0) {
|
2012-04-06 03:44:36 +02:00
|
|
|
return '';
|
2017-05-17 18:28:00 +02:00
|
|
|
}
|
2012-04-06 03:44:36 +02:00
|
|
|
|
2018-01-15 14:05:12 +01:00
|
|
|
$vowels = ['a','a','ai','au','e','e','e','ee','ea','i','ie','o','ou','u'];
|
2017-05-17 18:28:00 +02:00
|
|
|
if (mt_rand(0, 5) == 4) {
|
2011-08-02 01:51:01 +02:00
|
|
|
$vowels[] = 'y';
|
2017-05-17 18:28:00 +02:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2018-01-15 14:05:12 +01:00
|
|
|
$cons = [
|
2011-08-02 01:51:01 +02:00
|
|
|
'b','bl','br',
|
|
|
|
'c','ch','cl','cr',
|
|
|
|
'd','dr',
|
|
|
|
'f','fl','fr',
|
|
|
|
'g','gh','gl','gr',
|
|
|
|
'h',
|
|
|
|
'j',
|
|
|
|
'k','kh','kl','kr',
|
|
|
|
'l',
|
|
|
|
'm',
|
|
|
|
'n',
|
|
|
|
'p','ph','pl','pr',
|
|
|
|
'qu',
|
|
|
|
'r','rh',
|
|
|
|
's','sc','sh','sm','sp','st',
|
|
|
|
't','th','tr',
|
|
|
|
'v',
|
|
|
|
'w','wh',
|
|
|
|
'x',
|
|
|
|
'z','zh'
|
2018-01-15 14:05:12 +01:00
|
|
|
];
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2018-01-15 14:05:12 +01:00
|
|
|
$midcons = ['ck','ct','gn','ld','lf','lm','lt','mb','mm', 'mn','mp',
|
|
|
|
'nd','ng','nk','nt','rn','rp','rt'];
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2018-01-15 14:05:12 +01:00
|
|
|
$noend = ['bl', 'br', 'cl','cr','dr','fl','fr','gl','gr',
|
2018-05-27 10:11:51 +02:00
|
|
|
'kh', 'kl','kr','mn','pl','pr','rh','tr','qu','wh','q'];
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
$start = mt_rand(0,2);
|
2017-05-17 18:28:00 +02:00
|
|
|
if ($start == 0) {
|
2015-11-28 02:56:36 +01:00
|
|
|
$table = $vowels;
|
2017-05-17 18:28:00 +02:00
|
|
|
} else {
|
2015-11-28 02:56:36 +01:00
|
|
|
$table = $cons;
|
2017-05-17 18:28:00 +02:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
$word = '';
|
|
|
|
|
|
|
|
for ($x = 0; $x < $len; $x ++) {
|
2015-11-28 02:56:36 +01:00
|
|
|
$r = mt_rand(0,count($table) - 1);
|
|
|
|
$word .= $table[$r];
|
2014-07-30 15:23:36 +02:00
|
|
|
|
2017-05-17 18:28:00 +02:00
|
|
|
if ($table == $vowels) {
|
2015-11-28 02:56:36 +01:00
|
|
|
$table = array_merge($cons,$midcons);
|
2017-05-17 18:28:00 +02:00
|
|
|
} else {
|
2015-11-28 02:56:36 +01:00
|
|
|
$table = $vowels;
|
2017-05-17 18:28:00 +02:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
$word = substr($word,0,$len);
|
|
|
|
|
2017-04-04 19:48:25 +02:00
|
|
|
foreach ($noend as $noe) {
|
2018-05-27 10:11:51 +02:00
|
|
|
$noelen = strlen($noe);
|
|
|
|
if ((strlen($word) > $noelen) && (substr($word, -$noelen) == $noe)) {
|
|
|
|
$word = autoname($len);
|
2015-11-28 02:56:36 +01:00
|
|
|
break;
|
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
}
|
2017-05-17 18:28:00 +02:00
|
|
|
|
2011-08-02 01:51:01 +02:00
|
|
|
return $word;
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* escape text ($str) for XML transport
|
|
|
|
* @param string $str
|
|
|
|
* @return string Escaped text.
|
|
|
|
*/
|
2011-08-02 01:51:01 +02:00
|
|
|
function xmlify($str) {
|
2017-05-17 18:28:00 +02:00
|
|
|
/// @TODO deprecated code found?
|
2013-02-07 06:30:27 +01:00
|
|
|
/* $buffer = '';
|
2014-07-30 15:23:36 +02:00
|
|
|
|
2013-02-06 08:37:15 +01:00
|
|
|
$len = mb_strlen($str);
|
2017-04-04 19:48:25 +02:00
|
|
|
for ($x = 0; $x < $len; $x ++) {
|
2013-02-06 08:37:15 +01:00
|
|
|
$char = mb_substr($str,$x,1);
|
2014-07-30 15:23:36 +02:00
|
|
|
|
2017-11-11 07:42:39 +01:00
|
|
|
switch($char) {
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
case "\r" :
|
|
|
|
break;
|
|
|
|
case "&" :
|
|
|
|
$buffer .= '&';
|
|
|
|
break;
|
|
|
|
case "'" :
|
|
|
|
$buffer .= ''';
|
|
|
|
break;
|
|
|
|
case "\"" :
|
|
|
|
$buffer .= '"';
|
|
|
|
break;
|
|
|
|
case '<' :
|
|
|
|
$buffer .= '<';
|
|
|
|
break;
|
|
|
|
case '>' :
|
|
|
|
$buffer .= '>';
|
|
|
|
break;
|
|
|
|
case "\n" :
|
|
|
|
$buffer .= "\n";
|
|
|
|
break;
|
|
|
|
default :
|
|
|
|
$buffer .= $char;
|
|
|
|
break;
|
2014-07-30 15:23:36 +02:00
|
|
|
}
|
2013-02-07 06:30:27 +01:00
|
|
|
}*/
|
2014-01-16 15:08:51 +01:00
|
|
|
/*
|
2013-02-07 06:30:27 +01:00
|
|
|
$buffer = mb_ereg_replace("&", "&", $str);
|
|
|
|
$buffer = mb_ereg_replace("'", "'", $buffer);
|
2014-01-16 15:08:51 +01:00
|
|
|
$buffer = mb_ereg_replace('"', """, $buffer);
|
2013-02-07 06:30:27 +01:00
|
|
|
$buffer = mb_ereg_replace("<", "<", $buffer);
|
|
|
|
$buffer = mb_ereg_replace(">", ">", $buffer);
|
2014-01-16 15:08:51 +01:00
|
|
|
*/
|
2015-06-22 23:47:08 +02:00
|
|
|
$buffer = htmlspecialchars($str, ENT_QUOTES, "UTF-8");
|
2011-08-02 01:51:01 +02:00
|
|
|
$buffer = trim($buffer);
|
2014-07-30 15:23:36 +02:00
|
|
|
|
2017-11-11 07:42:39 +01:00
|
|
|
return $buffer;
|
|
|
|
}
|
|
|
|
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* undo an xmlify
|
|
|
|
* @param string $s xml escaped text
|
|
|
|
* @return string unescaped text
|
|
|
|
*/
|
2011-08-02 01:51:01 +02:00
|
|
|
function unxmlify($s) {
|
2017-05-17 18:28:00 +02:00
|
|
|
/// @TODO deprecated code found?
|
2013-02-07 06:30:27 +01:00
|
|
|
// $ret = str_replace('&','&', $s);
|
|
|
|
// $ret = str_replace(array('<','>','"','''),array('<','>','"',"'"),$ret);
|
2014-01-16 15:08:51 +01:00
|
|
|
/*$ret = mb_ereg_replace('&', '&', $s);
|
2013-02-07 06:30:27 +01:00
|
|
|
$ret = mb_ereg_replace(''', "'", $ret);
|
|
|
|
$ret = mb_ereg_replace('"', '"', $ret);
|
|
|
|
$ret = mb_ereg_replace('<', "<", $ret);
|
|
|
|
$ret = mb_ereg_replace('>', ">", $ret);
|
2014-01-16 15:08:51 +01:00
|
|
|
*/
|
2014-01-20 08:59:20 +01:00
|
|
|
$ret = htmlspecialchars_decode($s, ENT_QUOTES);
|
2014-07-30 15:23:36 +02:00
|
|
|
return $ret;
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
|
|
|
|
/**
|
2017-03-02 05:26:49 +01:00
|
|
|
* @brief Paginator function. Pushes relevant links in a pager array structure.
|
|
|
|
*
|
|
|
|
* Links are generated depending on the current page and the total number of items.
|
|
|
|
* Inactive links (like "first" and "prev" on page 1) are given the "disabled" class.
|
|
|
|
* Current page link is given the "active" CSS class
|
2013-03-27 10:11:40 +01:00
|
|
|
*
|
|
|
|
* @param App $a App instance
|
2017-03-02 05:26:49 +01:00
|
|
|
* @param int $count [optional] item count (used with minimal pager)
|
2013-06-13 14:12:15 +02:00
|
|
|
* @return Array data for pagination template
|
2013-03-27 10:11:40 +01:00
|
|
|
*/
|
2017-03-02 05:26:49 +01:00
|
|
|
function paginate_data(App $a, $count = null) {
|
|
|
|
$stripped = preg_replace('/([&?]page=[0-9]*)/', '', $a->query_string);
|
2012-04-02 09:45:45 +02:00
|
|
|
|
2017-03-02 05:26:49 +01:00
|
|
|
$stripped = str_replace('q=', '', $stripped);
|
|
|
|
$stripped = trim($stripped, '/');
|
2011-08-02 01:51:01 +02:00
|
|
|
$pagenum = $a->pager['page'];
|
2013-12-08 20:10:28 +01:00
|
|
|
|
2017-06-08 04:00:59 +02:00
|
|
|
if (($a->page_offset != '') && !preg_match('/[?&].offset=/', $stripped)) {
|
2017-03-02 05:26:49 +01:00
|
|
|
$stripped .= '&offset=' . urlencode($a->page_offset);
|
|
|
|
}
|
2013-12-08 20:10:28 +01:00
|
|
|
|
2016-02-17 23:47:32 +01:00
|
|
|
$url = $stripped;
|
2018-01-15 14:05:12 +01:00
|
|
|
$data = [];
|
2017-03-14 18:31:03 +01:00
|
|
|
|
2017-03-02 05:26:49 +01:00
|
|
|
function _l(&$d, $name, $url, $text, $class = '') {
|
|
|
|
if (strpos($url, '?') === false && ($pos = strpos($url, '&')) !== false) {
|
|
|
|
$url = substr($url, 0, $pos) . '?' . substr($url, $pos + 1);
|
2015-02-06 16:56:09 +01:00
|
|
|
}
|
2013-12-08 20:10:28 +01:00
|
|
|
|
2018-01-15 14:05:12 +01:00
|
|
|
$d[$name] = ['url' => $url, 'text' => $text, 'class' => $class];
|
2013-06-13 14:12:15 +02:00
|
|
|
}
|
|
|
|
|
2017-03-02 05:26:49 +01:00
|
|
|
if (!is_null($count)) {
|
|
|
|
// minimal pager (newer / older)
|
|
|
|
$data['class'] = 'pager';
|
2018-01-21 19:33:59 +01:00
|
|
|
_l($data, 'prev', $url . '&page=' . ($a->pager['page'] - 1), L10n::t('newer'), 'previous' . ($a->pager['page'] == 1 ? ' disabled' : ''));
|
|
|
|
_l($data, 'next', $url . '&page=' . ($a->pager['page'] + 1), L10n::t('older'), 'next' . ($count <= 0 ? ' disabled' : ''));
|
2013-06-13 14:12:15 +02:00
|
|
|
} else {
|
2017-03-02 05:26:49 +01:00
|
|
|
// full pager (first / prev / 1 / 2 / ... / 14 / 15 / next / last)
|
|
|
|
$data['class'] = 'pagination';
|
|
|
|
if ($a->pager['total'] > $a->pager['itemspage']) {
|
2018-01-21 19:33:59 +01:00
|
|
|
_l($data, 'first', $url . '&page=1', L10n::t('first'), $a->pager['page'] == 1 ? 'disabled' : '');
|
|
|
|
_l($data, 'prev', $url . '&page=' . ($a->pager['page'] - 1), L10n::t('prev'), $a->pager['page'] == 1 ? 'disabled' : '');
|
2013-12-10 00:13:19 +01:00
|
|
|
|
2013-06-13 14:12:15 +02:00
|
|
|
$numpages = $a->pager['total'] / $a->pager['itemspage'];
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
$numstart = 1;
|
2013-06-13 14:12:15 +02:00
|
|
|
$numstop = $numpages;
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2017-03-14 18:31:03 +01:00
|
|
|
// Limit the number of displayed page number buttons.
|
|
|
|
if ($numpages > 8) {
|
|
|
|
$numstart = (($pagenum > 4) ? ($pagenum - 4) : 1);
|
|
|
|
$numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 8));
|
2013-06-13 14:12:15 +02:00
|
|
|
}
|
|
|
|
|
2018-01-15 14:05:12 +01:00
|
|
|
$pages = [];
|
2013-06-13 14:12:15 +02:00
|
|
|
|
2017-03-02 05:26:49 +01:00
|
|
|
for ($i = $numstart; $i <= $numstop; $i++) {
|
|
|
|
if ($i == $a->pager['page']) {
|
|
|
|
_l($pages, $i, '#', $i, 'current active');
|
|
|
|
} else {
|
|
|
|
_l($pages, $i, $url . '&page='. $i, $i, 'n');
|
|
|
|
}
|
2013-06-13 14:12:15 +02:00
|
|
|
}
|
|
|
|
|
2017-03-02 05:26:49 +01:00
|
|
|
if (($a->pager['total'] % $a->pager['itemspage']) != 0) {
|
|
|
|
if ($i == $a->pager['page']) {
|
|
|
|
_l($pages, $i, '#', $i, 'current active');
|
|
|
|
} else {
|
|
|
|
_l($pages, $i, $url . '&page=' . $i, $i, 'n');
|
|
|
|
}
|
2013-06-13 14:12:15 +02:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-06-13 14:12:15 +02:00
|
|
|
$data['pages'] = $pages;
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-06-13 14:12:15 +02:00
|
|
|
$lastpage = (($numpages > intval($numpages)) ? intval($numpages)+1 : $numpages);
|
2018-01-21 19:33:59 +01:00
|
|
|
_l($data, 'next', $url . '&page=' . ($a->pager['page'] + 1), L10n::t('next'), $a->pager['page'] == $lastpage ? 'disabled' : '');
|
|
|
|
_l($data, 'last', $url . '&page=' . $lastpage, L10n::t('last'), $a->pager['page'] == $lastpage ? 'disabled' : '');
|
2013-12-10 00:13:19 +01:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
}
|
2013-06-13 14:12:15 +02:00
|
|
|
|
2017-03-02 05:26:49 +01:00
|
|
|
return $data;
|
|
|
|
}
|
2013-06-13 14:12:15 +02:00
|
|
|
|
2017-11-11 07:42:39 +01:00
|
|
|
|
2013-06-13 14:12:15 +02:00
|
|
|
/**
|
|
|
|
* Automatic pagination.
|
|
|
|
*
|
|
|
|
* To use, get the count of total items.
|
|
|
|
* Then call $a->set_pager_total($number_items);
|
|
|
|
* Optionally call $a->set_pager_itemspage($n) to the number of items to display on each page
|
|
|
|
* Then call paginate($a) after the end of the display loop to insert the pager block on the page
|
|
|
|
* (assuming there are enough items to paginate).
|
|
|
|
* When using with SQL, the setting LIMIT %d, %d => $a->pager['start'],$a->pager['itemspage']
|
2014-07-30 15:23:36 +02:00
|
|
|
* will limit the results to the correct items for the current page.
|
|
|
|
* The actual page handling is then accomplished at the application layer.
|
|
|
|
*
|
2013-06-13 14:12:15 +02:00
|
|
|
* @param App $a App instance
|
|
|
|
* @return string html for pagination #FIXME remove html
|
|
|
|
*/
|
2017-01-09 13:09:01 +01:00
|
|
|
function paginate(App $a) {
|
2013-12-08 20:10:28 +01:00
|
|
|
|
2013-06-13 14:12:15 +02:00
|
|
|
$data = paginate_data($a);
|
|
|
|
$tpl = get_markup_template("paginate.tpl");
|
2018-01-15 14:05:12 +01:00
|
|
|
return replace_macros($tpl, ["pager" => $data]);
|
2013-06-13 14:12:15 +02:00
|
|
|
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
|
|
|
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* Alternative pager
|
|
|
|
* @param App $a App instance
|
|
|
|
* @param int $i
|
|
|
|
* @return string html for pagination #FIXME remove html
|
|
|
|
*/
|
2017-01-09 13:09:01 +01:00
|
|
|
function alt_pager(App $a, $i) {
|
2012-07-14 20:21:58 +02:00
|
|
|
|
2013-06-13 14:12:15 +02:00
|
|
|
$data = paginate_data($a, $i);
|
|
|
|
$tpl = get_markup_template("paginate.tpl");
|
2018-01-15 14:05:12 +01:00
|
|
|
return replace_macros($tpl, ['pager' => $data]);
|
2013-12-10 00:13:19 +01:00
|
|
|
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
|
|
|
|
2012-07-14 20:21:58 +02:00
|
|
|
|
2015-02-05 11:29:14 +01:00
|
|
|
/**
|
|
|
|
* Loader for infinite scrolling
|
|
|
|
* @return string html for loader
|
|
|
|
*/
|
|
|
|
function scroll_loader() {
|
|
|
|
$tpl = get_markup_template("scroll_loader.tpl");
|
2018-01-15 14:05:12 +01:00
|
|
|
return replace_macros($tpl, [
|
2018-01-21 19:33:59 +01:00
|
|
|
'wait' => L10n::t('Loading more entries...'),
|
|
|
|
'end' => L10n::t('The end')
|
2018-01-15 14:05:12 +01:00
|
|
|
]);
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
|
|
|
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* Turn user/group ACLs stored as angle bracketed text into arrays
|
2013-12-10 00:13:19 +01:00
|
|
|
*
|
2013-03-27 10:11:40 +01:00
|
|
|
* @param string $s
|
|
|
|
* @return array
|
|
|
|
*/
|
2011-08-02 01:51:01 +02:00
|
|
|
function expand_acl($s) {
|
|
|
|
// turn string array of angle-bracketed elements into numeric array
|
|
|
|
// e.g. "<1><2><3>" => array(1,2,3);
|
2018-01-15 14:05:12 +01:00
|
|
|
$ret = [];
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2017-04-04 19:48:25 +02:00
|
|
|
if (strlen($s)) {
|
2017-05-22 13:04:30 +02:00
|
|
|
$t = str_replace('<', '', $s);
|
|
|
|
$a = explode('>', $t);
|
|
|
|
foreach ($a as $aa) {
|
2017-05-17 18:28:00 +02:00
|
|
|
if (intval($aa)) {
|
2011-08-02 01:51:01 +02:00
|
|
|
$ret[] = intval($aa);
|
2017-05-17 18:28:00 +02:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return $ret;
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
|
|
|
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
2014-07-30 15:23:36 +02:00
|
|
|
* Wrap ACL elements in angle brackets for storage
|
2013-03-27 10:11:40 +01:00
|
|
|
* @param string $item
|
|
|
|
*/
|
2011-08-02 01:51:01 +02:00
|
|
|
function sanitise_acl(&$item) {
|
2017-05-17 18:42:40 +02:00
|
|
|
if (intval($item)) {
|
2011-08-02 01:51:01 +02:00
|
|
|
$item = '<' . intval(notags(trim($item))) . '>';
|
2017-05-17 18:42:40 +02:00
|
|
|
} else {
|
2011-08-02 01:51:01 +02:00
|
|
|
unset($item);
|
2017-05-17 18:42:40 +02:00
|
|
|
}
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* Convert an ACL array to a storable string
|
2014-07-30 15:23:36 +02:00
|
|
|
*
|
2013-03-27 10:11:40 +01:00
|
|
|
* Normally ACL permissions will be an array.
|
|
|
|
* We'll also allow a comma-separated string.
|
2014-07-30 15:23:36 +02:00
|
|
|
*
|
2013-03-27 10:11:40 +01:00
|
|
|
* @param string|array $p
|
|
|
|
* @return string
|
|
|
|
*/
|
2011-08-02 01:51:01 +02:00
|
|
|
function perms2str($p) {
|
|
|
|
$ret = '';
|
2017-05-17 18:42:40 +02:00
|
|
|
if (is_array($p)) {
|
2012-11-11 22:56:21 +01:00
|
|
|
$tmp = $p;
|
2017-05-17 18:42:40 +02:00
|
|
|
} else {
|
2017-01-26 16:07:30 +01:00
|
|
|
$tmp = explode(',', $p);
|
2017-05-17 18:42:40 +02:00
|
|
|
}
|
2012-11-11 22:56:21 +01:00
|
|
|
|
2017-04-04 19:48:25 +02:00
|
|
|
if (is_array($tmp)) {
|
2017-05-22 13:04:30 +02:00
|
|
|
array_walk($tmp, 'sanitise_acl');
|
|
|
|
$ret = implode('', $tmp);
|
2011-08-02 01:51:01 +02:00
|
|
|
}
|
|
|
|
return $ret;
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* generate a guaranteed unique (for this domain) item ID for ATOM
|
|
|
|
* safe from birthday paradox
|
2014-07-30 15:23:36 +02:00
|
|
|
*
|
2013-03-27 10:11:40 +01:00
|
|
|
* @param string $hostname
|
|
|
|
* @param int $uid
|
|
|
|
* @return string
|
|
|
|
*/
|
2017-05-17 18:28:00 +02:00
|
|
|
function item_new_uri($hostname, $uid, $guid = "") {
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
do {
|
2017-05-17 18:28:00 +02:00
|
|
|
if ($guid == "") {
|
2015-08-14 00:40:36 +02:00
|
|
|
$hash = get_guid(32);
|
2017-05-17 18:28:00 +02:00
|
|
|
} else {
|
2015-08-14 00:40:36 +02:00
|
|
|
$hash = $guid;
|
|
|
|
$guid = "";
|
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
|
|
|
$uri = "urn:X-dfrn:" . $hostname . ':' . $uid . ':' . $hash;
|
|
|
|
|
2018-01-15 14:05:12 +01:00
|
|
|
$dups = dba::exists('item', ['uri' => $uri]);
|
2017-04-04 19:48:25 +02:00
|
|
|
} while ($dups == true);
|
2017-05-17 18:28:00 +02:00
|
|
|
|
2011-08-02 01:51:01 +02:00
|
|
|
return $uri;
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* @deprecated
|
|
|
|
* wrapper to load a view template, checking for alternate
|
|
|
|
* languages before falling back to the default
|
2014-03-11 23:52:32 +01:00
|
|
|
*
|
2013-03-27 10:11:40 +01:00
|
|
|
* @global string $lang
|
|
|
|
* @global App $a
|
|
|
|
* @param string $s view name
|
|
|
|
* @return string
|
2014-07-30 15:23:36 +02:00
|
|
|
*/
|
2011-08-02 01:51:01 +02:00
|
|
|
function load_view_file($s) {
|
|
|
|
global $lang, $a;
|
2017-05-17 18:28:00 +02:00
|
|
|
if (! isset($lang)) {
|
2011-08-02 01:51:01 +02:00
|
|
|
$lang = 'en';
|
2017-05-17 18:28:00 +02:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
$b = basename($s);
|
|
|
|
$d = dirname($s);
|
2017-04-04 19:48:25 +02:00
|
|
|
if (file_exists("$d/$lang/$b")) {
|
2013-01-26 18:35:39 +01:00
|
|
|
$stamp1 = microtime(true);
|
|
|
|
$content = file_get_contents("$d/$lang/$b");
|
|
|
|
$a->save_timestamp($stamp1, "file");
|
|
|
|
return $content;
|
|
|
|
}
|
2013-01-26 16:46:43 +01:00
|
|
|
|
2018-04-29 00:37:04 +02:00
|
|
|
$theme = $a->getCurrentTheme();
|
2012-07-24 04:37:00 +02:00
|
|
|
|
2017-04-04 19:48:25 +02:00
|
|
|
if (file_exists("$d/theme/$theme/$b")) {
|
2013-01-26 18:35:39 +01:00
|
|
|
$stamp1 = microtime(true);
|
|
|
|
$content = file_get_contents("$d/theme/$theme/$b");
|
|
|
|
$a->save_timestamp($stamp1, "file");
|
|
|
|
return $content;
|
|
|
|
}
|
2013-01-26 16:46:43 +01:00
|
|
|
|
2013-01-26 18:35:39 +01:00
|
|
|
$stamp1 = microtime(true);
|
|
|
|
$content = file_get_contents($s);
|
|
|
|
$a->save_timestamp($stamp1, "file");
|
|
|
|
return $content;
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
|
|
|
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* load a view template, checking for alternate
|
|
|
|
* languages before falling back to the default
|
2014-07-30 15:23:36 +02:00
|
|
|
*
|
2013-03-27 10:11:40 +01:00
|
|
|
* @global string $lang
|
|
|
|
* @param string $s view path
|
|
|
|
* @return string
|
|
|
|
*/
|
2011-08-02 01:51:01 +02:00
|
|
|
function get_intltext_template($s) {
|
|
|
|
global $lang;
|
|
|
|
|
2012-12-22 20:57:29 +01:00
|
|
|
$a = get_app();
|
|
|
|
$engine = '';
|
2017-05-17 18:28:00 +02:00
|
|
|
if ($a->theme['template_engine'] === 'smarty3') {
|
2012-12-22 20:57:29 +01:00
|
|
|
$engine = "/smarty3";
|
2017-05-17 18:28:00 +02:00
|
|
|
}
|
2012-12-22 20:57:29 +01:00
|
|
|
|
2017-05-17 18:28:00 +02:00
|
|
|
if (! isset($lang)) {
|
2011-08-02 01:51:01 +02:00
|
|
|
$lang = 'en';
|
2017-05-17 18:28:00 +02:00
|
|
|
}
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2017-04-04 19:48:25 +02:00
|
|
|
if (file_exists("view/lang/$lang$engine/$s")) {
|
2013-01-26 18:35:39 +01:00
|
|
|
$stamp1 = microtime(true);
|
2016-09-30 16:46:56 +02:00
|
|
|
$content = file_get_contents("view/lang/$lang$engine/$s");
|
2013-01-26 18:35:39 +01:00
|
|
|
$a->save_timestamp($stamp1, "file");
|
|
|
|
return $content;
|
2017-04-04 19:48:25 +02:00
|
|
|
} elseif (file_exists("view/lang/en$engine/$s")) {
|
2013-01-26 18:35:39 +01:00
|
|
|
$stamp1 = microtime(true);
|
2016-09-30 16:46:56 +02:00
|
|
|
$content = file_get_contents("view/lang/en$engine/$s");
|
2013-01-26 18:35:39 +01:00
|
|
|
$a->save_timestamp($stamp1, "file");
|
|
|
|
return $content;
|
|
|
|
} else {
|
|
|
|
$stamp1 = microtime(true);
|
|
|
|
$content = file_get_contents("view$engine/$s");
|
|
|
|
$a->save_timestamp($stamp1, "file");
|
|
|
|
return $content;
|
|
|
|
}
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
|
|
|
|
2011-08-02 01:51:01 +02:00
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* load template $s
|
2014-07-30 15:23:36 +02:00
|
|
|
*
|
2013-03-27 10:11:40 +01:00
|
|
|
* @param string $s
|
|
|
|
* @param string $root
|
|
|
|
* @return string
|
|
|
|
*/
|
2012-12-22 20:57:29 +01:00
|
|
|
function get_markup_template($s, $root = '') {
|
2013-01-26 16:46:43 +01:00
|
|
|
$stamp1 = microtime(true);
|
|
|
|
|
2012-12-22 20:57:29 +01:00
|
|
|
$a = get_app();
|
2013-03-27 15:37:59 +01:00
|
|
|
$t = $a->template_engine();
|
2013-06-13 14:12:15 +02:00
|
|
|
try {
|
2017-11-19 16:22:18 +01:00
|
|
|
$template = $t->getTemplateFile($s, $root);
|
2013-06-13 14:12:15 +02:00
|
|
|
} catch (Exception $e) {
|
2017-05-17 18:28:00 +02:00
|
|
|
echo "<pre><b>" . __FUNCTION__ . "</b>: " . $e->getMessage() . "</pre>";
|
|
|
|
killme();
|
2013-06-13 14:12:15 +02:00
|
|
|
}
|
2014-07-30 15:23:36 +02:00
|
|
|
|
2013-03-27 15:37:59 +01:00
|
|
|
$a->save_timestamp($stamp1, "file");
|
2014-07-30 15:23:36 +02:00
|
|
|
|
2013-03-27 15:37:59 +01:00
|
|
|
return $template;
|
2017-11-11 07:42:39 +01:00
|
|
|
}
|
|
|
|
|
2013-03-27 10:11:40 +01:00
|
|
|
/**
|
|
|
|
* for html,xml parsing - let's say you've got
|
|
|
|
* an attribute foobar="class1 class2 class3"
|
|
|
|
* and you want to find out if it contains 'class3'.
|
|
|
|
* you can't use a normal sub string search because you
|
2014-07-30 15:23:36 +02:00
|
|
|
* might match 'notclass3' and a regex to do the job is
|
|
|
|
* possible but a bit complicated.
|
|
|
|
* pass the attribute string as $attr and the attribute you
|
2013-03-27 10:11:40 +01:00
|
|
|
* are looking for as $s - returns true if found, otherwise false
|
2014-07-30 15:23:36 +02:00
|
|
|
*
|
2013-03-27 10:11:40 +01:00
|
|
|
* @param string $attr attribute value
|
|
|
|
* @param string $s string to search
|
|
|
|
* @return boolean True if found, False otherwise
|
|
|
|
*/
|
2017-05-17 18:28:00 +02:00
|
|
|
function attribute_contains($attr, $s) {
|
|