mirror of
https://github.com/friendica/friendica
synced 2024-11-18 18:23:40 +00:00
Merge pull request #10551 from annando/profiler
Support for stacked profiler analysis
This commit is contained in:
commit
71a0c52dc3
26 changed files with 813 additions and 633 deletions
|
@ -22,7 +22,6 @@
|
|||
use Friendica\App;
|
||||
use Friendica\Content\ContactSelector;
|
||||
use Friendica\Content\Feature;
|
||||
use Friendica\Content\Text\BBCode;
|
||||
use Friendica\Core\Hook;
|
||||
use Friendica\Core\Logger;
|
||||
use Friendica\Core\Protocol;
|
||||
|
@ -34,7 +33,6 @@ use Friendica\DI;
|
|||
use Friendica\Model\Contact;
|
||||
use Friendica\Model\Item;
|
||||
use Friendica\Model\Post;
|
||||
use Friendica\Model\Profile;
|
||||
use Friendica\Model\Tag;
|
||||
use Friendica\Model\Verb;
|
||||
use Friendica\Object\Post as PostObject;
|
||||
|
@ -56,6 +54,7 @@ use Friendica\Util\XML;
|
|||
*/
|
||||
function localize_item(&$item)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
/// @todo The following functionality needs to be cleaned up.
|
||||
if (!empty($item['verb'])) {
|
||||
$activity = DI::activity();
|
||||
|
@ -65,9 +64,11 @@ function localize_item(&$item)
|
|||
if (stristr($item['verb'], Activity::POKE)) {
|
||||
$verb = urldecode(substr($item['verb'], strpos($item['verb'],'#') + 1));
|
||||
if (!$verb) {
|
||||
DI::profiler()->stopRecording();
|
||||
return;
|
||||
}
|
||||
if ($item['object-type'] == "" || $item['object-type'] !== Activity\ObjectType::PERSON) {
|
||||
DI::profiler()->stopRecording();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -120,6 +121,7 @@ function localize_item(&$item)
|
|||
'verb', 'object-type', 'resource-id', 'body', 'plink'];
|
||||
$obj = Post::selectFirst($fields, ['uri' => $item['parent-uri']]);
|
||||
if (!DBA::isResult($obj)) {
|
||||
DI::profiler()->stopRecording();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -177,6 +179,7 @@ function localize_item(&$item)
|
|||
'network' => $item['author-network'], 'url' => $item['author-link']];
|
||||
$item['plink'] = Contact::magicLinkByContact($author, $item['plink']);
|
||||
}
|
||||
DI::profiler()->stopRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -263,6 +266,7 @@ function conv_get_blocklist()
|
|||
*/
|
||||
function conversation(App $a, array $items, $mode, $update, $preview = false, $order = 'commented', $uid = 0)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$page = DI::page();
|
||||
|
||||
$page->registerFooterScript(Theme::getPathForFile('asset/typeahead.js/dist/typeahead.bundle.js'));
|
||||
|
@ -603,6 +607,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
|
|||
'$dropping' => ($page_dropping ? DI::l10n()->t('Delete Selected Items') : False),
|
||||
]);
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
@ -616,6 +621,7 @@ function conversation(App $a, array $items, $mode, $update, $preview = false, $o
|
|||
* @return array items with parents and comments
|
||||
*/
|
||||
function conversation_fetch_comments($thread_items, bool $pinned, array $activity) {
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$comments = [];
|
||||
|
||||
while ($row = Post::fetch($thread_items)) {
|
||||
|
@ -693,6 +699,7 @@ function conversation_fetch_comments($thread_items, bool $pinned, array $activit
|
|||
|
||||
DBA::close($thread_items);
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $comments;
|
||||
}
|
||||
|
||||
|
@ -711,6 +718,7 @@ function conversation_fetch_comments($thread_items, bool $pinned, array $activit
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
function conversation_add_children(array $parents, $block_authors, $order, $uid) {
|
||||
DI::profiler()->startRecording('rendering');
|
||||
if (count($parents) > 1) {
|
||||
$max_comments = DI::config()->get('system', 'max_comments', 100);
|
||||
} else {
|
||||
|
@ -753,6 +761,7 @@ function conversation_add_children(array $parents, $block_authors, $order, $uid)
|
|||
|
||||
$items = conv_sort($items, $order);
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $items;
|
||||
}
|
||||
|
||||
|
@ -768,6 +777,7 @@ function conversation_add_children(array $parents, $block_authors, $order, $uid)
|
|||
* @return array
|
||||
*/
|
||||
function conversation_fetch_items(array $parent, array $items, array $condition, bool $block_authors, array $params, array $activity) {
|
||||
DI::profiler()->startRecording('rendering');
|
||||
if ($block_authors) {
|
||||
$condition[0] .= " AND NOT `author-hidden`";
|
||||
}
|
||||
|
@ -779,11 +789,13 @@ function conversation_fetch_items(array $parent, array $items, array $condition,
|
|||
if (count($comments) != 0) {
|
||||
$items = array_merge($items, $comments);
|
||||
}
|
||||
DI::profiler()->stopRecording();
|
||||
return $items;
|
||||
}
|
||||
|
||||
function item_photo_menu($item)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$sub_link = '';
|
||||
$poke_link = '';
|
||||
$contact_url = '';
|
||||
|
@ -882,6 +894,7 @@ function item_photo_menu($item)
|
|||
$o .= '<li role="menuitem"><a href="' . $v . '">' . $k . '</a></li>' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
DI::profiler()->stopRecording();
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
@ -980,6 +993,7 @@ function builtin_activity_puller(array $activity, array &$conv_responses)
|
|||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
*/
|
||||
function format_activity(array $links, $verb, $id) {
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$o = '';
|
||||
$expanded = '';
|
||||
$phrase = '';
|
||||
|
@ -1059,11 +1073,13 @@ function format_activity(array $links, $verb, $id) {
|
|||
]);
|
||||
$o .= $expanded;
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $o;
|
||||
}
|
||||
|
||||
function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$o = '';
|
||||
|
||||
$geotag = !empty($x['allow_location']) ? Renderer::replaceMacros(Renderer::getMarkupTemplate('jot_geotag.tpl'), []) : '';
|
||||
|
@ -1151,6 +1167,7 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
|
|||
$o = '<div id="jot-popup" style="display: none;">' . $o . '</div>';
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
@ -1164,6 +1181,7 @@ function status_editor(App $a, $x, $notes_cid = 0, $popup = false)
|
|||
*/
|
||||
function get_item_children(array &$item_list, array $parent, $recursive = true)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$children = [];
|
||||
foreach ($item_list as $i => $item) {
|
||||
if ($item['gravity'] != GRAVITY_PARENT) {
|
||||
|
@ -1185,6 +1203,7 @@ function get_item_children(array &$item_list, array $parent, $recursive = true)
|
|||
}
|
||||
}
|
||||
}
|
||||
DI::profiler()->stopRecording();
|
||||
return $children;
|
||||
}
|
||||
|
||||
|
@ -1196,6 +1215,7 @@ function get_item_children(array &$item_list, array $parent, $recursive = true)
|
|||
*/
|
||||
function sort_item_children(array $items)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$result = $items;
|
||||
usort($result, 'sort_thr_received_rev');
|
||||
foreach ($result as $k => $i) {
|
||||
|
@ -1203,6 +1223,7 @@ function sort_item_children(array $items)
|
|||
$result[$k]['children'] = sort_item_children($result[$k]['children']);
|
||||
}
|
||||
}
|
||||
DI::profiler()->stopRecording();
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
@ -1240,7 +1261,9 @@ function add_children_to_list(array $children, array &$item_list)
|
|||
*/
|
||||
function smart_flatten_conversation(array $parent)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
if (!isset($parent['children']) || count($parent['children']) == 0) {
|
||||
DI::profiler()->stopRecording();
|
||||
return $parent;
|
||||
}
|
||||
|
||||
|
@ -1251,6 +1274,7 @@ function smart_flatten_conversation(array $parent)
|
|||
if (isset($child['children']) && count($child['children'])) {
|
||||
// This helps counting only the regular posts
|
||||
$count_post_closure = function($var) {
|
||||
DI::profiler()->stopRecording();
|
||||
return $var['verb'] === Activity::POST;
|
||||
};
|
||||
|
||||
|
@ -1276,6 +1300,7 @@ function smart_flatten_conversation(array $parent)
|
|||
}
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $parent;
|
||||
}
|
||||
|
||||
|
@ -1293,9 +1318,11 @@ function smart_flatten_conversation(array $parent)
|
|||
*/
|
||||
function conv_sort(array $item_list, $order)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$parents = [];
|
||||
|
||||
if (!(is_array($item_list) && count($item_list))) {
|
||||
DI::profiler()->stopRecording();
|
||||
return $parents;
|
||||
}
|
||||
|
||||
|
@ -1355,6 +1382,7 @@ function conv_sort(array $item_list, $order)
|
|||
}
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $parents;
|
||||
}
|
||||
|
||||
|
|
|
@ -152,6 +152,7 @@ class BBCode
|
|||
*/
|
||||
public static function getAttachmentData($body)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$data = [
|
||||
'type' => '',
|
||||
'text' => '',
|
||||
|
@ -167,6 +168,7 @@ class BBCode
|
|||
];
|
||||
|
||||
if (!preg_match("/(.*)\[attachment(.*?)\](.*?)\[\/attachment\](.*)/ism", $body, $match)) {
|
||||
DI::profiler()->stopRecording();
|
||||
return self::getOldAttachmentData($body);
|
||||
}
|
||||
|
||||
|
@ -211,6 +213,7 @@ class BBCode
|
|||
}
|
||||
|
||||
if (!in_array($data['type'], ['link', 'audio', 'photo', 'video'])) {
|
||||
DI::profiler()->stopRecording();
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -232,6 +235,7 @@ class BBCode
|
|||
}
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
@ -247,6 +251,7 @@ class BBCode
|
|||
- (thumbnail)
|
||||
*/
|
||||
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$has_title = !empty($item['title']);
|
||||
$plink = $item['plink'] ?? '';
|
||||
$post = self::getAttachmentData($body);
|
||||
|
@ -398,6 +403,7 @@ class BBCode
|
|||
}
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $post;
|
||||
}
|
||||
|
||||
|
@ -434,6 +440,7 @@ class BBCode
|
|||
*/
|
||||
public static function toPlaintext($text, $keep_urls = true)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
// Remove pictures in advance to avoid unneeded proxy calls
|
||||
$text = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", ' $2 ', $text);
|
||||
$text = preg_replace("/\[img.*?\[\/img\]/ism", ' ', $text);
|
||||
|
@ -443,6 +450,7 @@ class BBCode
|
|||
|
||||
$naked_text = HTML::toPlaintext(self::convert($text, false, 0, true), 0, !$keep_urls);
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $naked_text;
|
||||
}
|
||||
|
||||
|
@ -468,6 +476,7 @@ class BBCode
|
|||
*/
|
||||
public static function scaleExternalImages(string $srctext)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$s = $srctext;
|
||||
|
||||
// Simplify image links
|
||||
|
@ -517,6 +526,7 @@ class BBCode
|
|||
}
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
@ -532,6 +542,7 @@ class BBCode
|
|||
*/
|
||||
public static function limitBodySize($body)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$maxlen = DI::config()->get('config', 'max_import_size', 0);
|
||||
|
||||
// If the length of the body, including the embedded images, is smaller
|
||||
|
@ -603,8 +614,10 @@ class BBCode
|
|||
$new_body = $new_body . $orig_body;
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $new_body;
|
||||
} else {
|
||||
DI::profiler()->stopRecording();
|
||||
return $body;
|
||||
}
|
||||
}
|
||||
|
@ -624,13 +637,13 @@ class BBCode
|
|||
*/
|
||||
public static function convertAttachment($text, $simplehtml = self::INTERNAL, $tryoembed = true, array $data = [], $uriid = 0)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$data = $data ?: self::getAttachmentData($text);
|
||||
if (empty($data) || empty($data['url'])) {
|
||||
DI::profiler()->stopRecording();
|
||||
return $text;
|
||||
}
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
|
||||
if (isset($data['title'])) {
|
||||
$data['title'] = strip_tags($data['title']);
|
||||
$data['title'] = str_replace(['http://', 'https://'], '', $data['title']);
|
||||
|
@ -688,17 +701,20 @@ class BBCode
|
|||
}
|
||||
}
|
||||
|
||||
DI::profiler()->saveTimestamp($stamp1, 'rendering');
|
||||
DI::profiler()->stopRecording();
|
||||
return trim(($data['text'] ?? '') . ' ' . $return . ' ' . ($data['after'] ?? ''));
|
||||
}
|
||||
|
||||
public static function removeShareInformation($Text, $plaintext = false, $nolink = false)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$data = self::getAttachmentData($Text);
|
||||
|
||||
if (!$data) {
|
||||
DI::profiler()->stopRecording();
|
||||
return $Text;
|
||||
} elseif ($nolink) {
|
||||
DI::profiler()->stopRecording();
|
||||
return $data['text'] . ($data['after'] ?? '');
|
||||
}
|
||||
|
||||
|
@ -712,11 +728,13 @@ class BBCode
|
|||
}
|
||||
|
||||
if (empty($data['text']) && !empty($data['title']) && empty($data['url'])) {
|
||||
DI::profiler()->stopRecording();
|
||||
return $data['title'] . $data['after'];
|
||||
}
|
||||
|
||||
// If the link already is included in the post, don't add it again
|
||||
if (!empty($data['url']) && strpos($data['text'], $data['url'])) {
|
||||
DI::profiler()->stopRecording();
|
||||
return $data['text'] . $data['after'];
|
||||
}
|
||||
|
||||
|
@ -728,6 +746,7 @@ class BBCode
|
|||
$text .= "\n[url]" . $data['url'] . '[/url]';
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $text . "\n" . $data['after'];
|
||||
}
|
||||
|
||||
|
@ -821,6 +840,7 @@ class BBCode
|
|||
*/
|
||||
public static function getTagPosition($text, $name, $occurrences = 0)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
if ($occurrences < 0) {
|
||||
$occurrences = 0;
|
||||
}
|
||||
|
@ -833,6 +853,7 @@ class BBCode
|
|||
}
|
||||
|
||||
if ($start_open === false) {
|
||||
DI::profiler()->stopRecording();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -840,6 +861,7 @@ class BBCode
|
|||
$start_close = strpos($text, ']', $start_open);
|
||||
|
||||
if ($start_close === false) {
|
||||
DI::profiler()->stopRecording();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -848,6 +870,7 @@ class BBCode
|
|||
$end_open = strpos($text, '[/' . $name . ']', $start_close);
|
||||
|
||||
if ($end_open === false) {
|
||||
DI::profiler()->stopRecording();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -866,6 +889,7 @@ class BBCode
|
|||
$res['start']['equal'] = $start_equal + 1;
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
@ -880,6 +904,7 @@ class BBCode
|
|||
*/
|
||||
public static function pregReplaceInTag($pattern, $replace, $name, $text)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$occurrences = 0;
|
||||
$pos = self::getTagPosition($text, $name, $occurrences);
|
||||
while ($pos !== false && $occurrences++ < 1000) {
|
||||
|
@ -896,6 +921,7 @@ class BBCode
|
|||
$pos = self::getTagPosition($text, $name, $occurrences);
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
@ -964,12 +990,14 @@ class BBCode
|
|||
*/
|
||||
public static function fetchShareAttributes($text)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
// See Issue https://github.com/friendica/friendica/issues/10454
|
||||
// Hashtags in usernames are expanded to links. This here is a quick fix.
|
||||
$text = preg_replace('/([@!#])\[url\=.*?\](.*?)\[\/url\]/ism', '$1$2', $text);
|
||||
|
||||
$attributes = [];
|
||||
if (!preg_match("/(.*?)\[share(.*?)\](.*)\[\/share\]/ism", $text, $matches)) {
|
||||
DI::profiler()->stopRecording();
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
|
@ -978,6 +1006,7 @@ class BBCode
|
|||
preg_match("/$field=(['\"])(.+?)\\1/ism", $attribute_string, $matches);
|
||||
$attributes[$field] = html_entity_decode($matches[2] ?? '', ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
DI::profiler()->stopRecording();
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
|
@ -1002,6 +1031,7 @@ class BBCode
|
|||
*/
|
||||
public static function convertShare($text, callable $callback, int $uriid = 0)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$return = preg_replace_callback(
|
||||
"/(.*?)\[share(.*?)\](.*)\[\/share\]/ism",
|
||||
function ($match) use ($callback, $uriid) {
|
||||
|
@ -1033,6 +1063,7 @@ class BBCode
|
|||
$text
|
||||
);
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
@ -1052,6 +1083,7 @@ class BBCode
|
|||
*/
|
||||
private static function convertShareCallback(array $attributes, array $author_contact, $content, $is_quote_share, $simplehtml)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$mention = Protocol::formatMention($attributes['profile'], $attributes['author']);
|
||||
|
||||
switch ($simplehtml) {
|
||||
|
@ -1247,19 +1279,23 @@ class BBCode
|
|||
|
||||
public static function cleanPictureLinks($text)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img=(.*)\](.*)\[\/img\]\[\/url\]&Usi", 'self::cleanPictureLinksCallback', $text);
|
||||
$return = preg_replace_callback("&\[url=([^\[\]]*)\]\[img\](.*)\[\/img\]\[\/url\]&Usi", 'self::cleanPictureLinksCallback', $return);
|
||||
DI::profiler()->stopRecording();
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function removeLinks(string $bbcode)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$bbcode = preg_replace("/\[img\=(.*?)\](.*?)\[\/img\]/ism", ' $1 ', $bbcode);
|
||||
$bbcode = preg_replace("/\[img.*?\[\/img\]/ism", ' ', $bbcode);
|
||||
|
||||
$bbcode = preg_replace('/[@!#]\[url\=.*?\].*?\[\/url\]/ism', '', $bbcode);
|
||||
$bbcode = preg_replace("/\[url=[^\[\]]*\](.*)\[\/url\]/Usi", ' $1 ', $bbcode);
|
||||
$bbcode = preg_replace('/[@!#]?\[url.*?\[\/url\]/ism', '', $bbcode);
|
||||
DI::profiler()->stopRecording();
|
||||
return $bbcode;
|
||||
}
|
||||
|
||||
|
@ -1271,8 +1307,11 @@ class BBCode
|
|||
*/
|
||||
public static function setMentionsToNicknames(string $body):string
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$regexp = "/([@!])\[url\=([^\[\]]*)\].*?\[\/url\]/ism";
|
||||
return preg_replace_callback($regexp, ['self', 'mentionCallback'], $body);
|
||||
$body = preg_replace_callback($regexp, ['self', 'mentionCallback'], $body);
|
||||
DI::profiler()->stopRecording();
|
||||
return $body;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1360,6 +1399,8 @@ class BBCode
|
|||
return '';
|
||||
}
|
||||
|
||||
DI::profiler()->startRecording('rendering');
|
||||
|
||||
Hook::callAll('bbcode', $text);
|
||||
|
||||
$a = DI::app();
|
||||
|
@ -1979,6 +2020,7 @@ class BBCode
|
|||
);
|
||||
|
||||
$text = HTML::purify($text, $allowedIframeDomains);
|
||||
DI::profiler()->stopRecording();
|
||||
|
||||
return trim($text);
|
||||
}
|
||||
|
@ -1991,9 +2033,11 @@ class BBCode
|
|||
*/
|
||||
public static function stripAbstract($text)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$text = preg_replace("/[\s|\n]*\[abstract\].*?\[\/abstract\][\s|\n]*/ism", '', $text);
|
||||
$text = preg_replace("/[\s|\n]*\[abstract=.*?\].*?\[\/abstract][\s|\n]*/ism", '', $text);
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
@ -2006,6 +2050,7 @@ class BBCode
|
|||
*/
|
||||
public static function getAbstract($text, $addon = '')
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$abstract = '';
|
||||
$abstracts = [];
|
||||
$addon = strtolower($addon);
|
||||
|
@ -2024,6 +2069,7 @@ class BBCode
|
|||
$abstract = $result[1];
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $abstract;
|
||||
}
|
||||
|
||||
|
@ -2062,6 +2108,7 @@ class BBCode
|
|||
*/
|
||||
public static function toMarkdown($text, $for_diaspora = true)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$original_text = $text;
|
||||
|
||||
// Since Diaspora is creating a summary for links, this function removes them before posting
|
||||
|
@ -2106,13 +2153,9 @@ class BBCode
|
|||
// Maybe we should make this newline at every time before a quote.
|
||||
$text = str_replace(['</a><blockquote>'], ['</a><br><blockquote>'], $text);
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
|
||||
// Now convert HTML to Markdown
|
||||
$text = HTML::toMarkdown($text);
|
||||
|
||||
DI::profiler()->saveTimestamp($stamp1, "parser");
|
||||
|
||||
// Libertree has a problem with escaped hashtags.
|
||||
$text = str_replace(['\#'], ['#'], $text);
|
||||
|
||||
|
@ -2131,6 +2174,7 @@ class BBCode
|
|||
|
||||
Hook::callAll('bb2diaspora', $text);
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
@ -2149,6 +2193,7 @@ class BBCode
|
|||
*/
|
||||
public static function getTags($string)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$ret = [];
|
||||
|
||||
self::performWithEscapedTags($string, ['noparse', 'pre', 'code', 'img'], function ($string) use (&$ret) {
|
||||
|
@ -2199,6 +2244,7 @@ class BBCode
|
|||
}
|
||||
});
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return array_unique($ret);
|
||||
}
|
||||
|
||||
|
@ -2258,6 +2304,7 @@ class BBCode
|
|||
*/
|
||||
public static function setMentions($body, $profile_uid = 0, $network = '')
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
self::performWithEscapedTags($body, ['noparse', 'pre', 'code', 'img'], function ($body) use ($profile_uid, $network) {
|
||||
$tags = self::getTags($body);
|
||||
|
||||
|
@ -2289,6 +2336,7 @@ class BBCode
|
|||
return $body;
|
||||
});
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $body;
|
||||
}
|
||||
|
||||
|
@ -2304,6 +2352,7 @@ class BBCode
|
|||
*/
|
||||
public static function getShareOpeningTag(string $author, string $profile, string $avatar, string $link, string $posted, string $guid = null)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$header = "[share author='" . str_replace(["'", "[", "]"], ["'", "[", "]"], $author) .
|
||||
"' profile='" . str_replace(["'", "[", "]"], ["'", "[", "]"], $profile) .
|
||||
"' avatar='" . str_replace(["'", "[", "]"], ["'", "[", "]"], $avatar) .
|
||||
|
@ -2316,6 +2365,7 @@ class BBCode
|
|||
|
||||
$header .= "']";
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $header;
|
||||
}
|
||||
|
||||
|
@ -2337,6 +2387,7 @@ class BBCode
|
|||
*/
|
||||
public static function embedURL(string $url, bool $tryAttachment = true, string $title = null, string $description = null, string $tags = null): string
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
DI::logger()->info($url);
|
||||
|
||||
// If there is already some content information submitted we don't
|
||||
|
@ -2358,6 +2409,7 @@ class BBCode
|
|||
|
||||
DI::logger()->info('(unparsed): returns: ' . $result);
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
@ -2376,6 +2428,7 @@ class BBCode
|
|||
break;
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $bbcode;
|
||||
}
|
||||
|
||||
|
@ -2383,10 +2436,13 @@ class BBCode
|
|||
|
||||
// Bypass attachment if parse url for a comment
|
||||
if (!$tryAttachment) {
|
||||
DI::profiler()->stopRecording();
|
||||
return "\n" . '[url=' . $url . ']' . $siteinfo['title'] . '[/url]';
|
||||
}
|
||||
|
||||
// Format it as BBCode attachment
|
||||
return "\n" . PageInfo::getFooterFromData($siteinfo);
|
||||
$bbcode = "\n" . PageInfo::getFooterFromData($siteinfo);
|
||||
DI::profiler()->stopRecording();
|
||||
return $bbcode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,6 +143,7 @@ class HTML
|
|||
*/
|
||||
public static function toBBCode($message, $basepath = '')
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$message = str_replace("\r", "", $message);
|
||||
|
||||
$message = Strings::performWithEscapedBlocks($message, '#<pre><code.*</code></pre>#iUs', function ($message) {
|
||||
|
@ -396,6 +397,7 @@ class HTML
|
|||
$message = self::qualifyURLs($message, $basepath);
|
||||
}
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $message;
|
||||
}
|
||||
|
||||
|
@ -585,6 +587,7 @@ class HTML
|
|||
*/
|
||||
public static function toPlaintext(string $html, $wraplength = 75, $compact = false)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$message = str_replace("\r", "", $html);
|
||||
|
||||
$doc = new DOMDocument();
|
||||
|
@ -593,6 +596,7 @@ class HTML
|
|||
$message = mb_convert_encoding($message, 'HTML-ENTITIES', "UTF-8");
|
||||
|
||||
if (empty($message)) {
|
||||
DI::profiler()->stopRecording();
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -606,6 +610,7 @@ class HTML
|
|||
$urls = self::collectURLs($message);
|
||||
|
||||
if (empty($message)) {
|
||||
DI::profiler()->stopRecording();
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -689,6 +694,7 @@ class HTML
|
|||
|
||||
$message = self::quoteLevel(trim($message), $wraplength);
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return trim($message);
|
||||
}
|
||||
|
||||
|
@ -701,9 +707,11 @@ class HTML
|
|||
*/
|
||||
public static function toMarkdown($html)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$converter = new HtmlConverter(['hard_break' => true]);
|
||||
$markdown = $converter->convert($html);
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $markdown;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
namespace Friendica\Content\Text;
|
||||
|
||||
use Friendica\Core\System;
|
||||
use Friendica\DI;
|
||||
use Friendica\Model\Contact;
|
||||
|
||||
|
@ -40,7 +39,7 @@ class Markdown
|
|||
* @return string
|
||||
*/
|
||||
public static function convert($text, $hardwrap = true, $baseuri = null) {
|
||||
$stamp1 = microtime(true);
|
||||
DI::profiler()->startRecording('rendering');
|
||||
|
||||
$MarkdownParser = new MarkdownParser();
|
||||
$MarkdownParser->code_class_prefix = 'language-';
|
||||
|
@ -57,7 +56,7 @@ class Markdown
|
|||
|
||||
$html = $MarkdownParser->transform($text);
|
||||
|
||||
DI::profiler()->saveTimestamp($stamp1, "parser");
|
||||
DI::profiler()->stopRecording();
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
@ -109,6 +108,8 @@ class Markdown
|
|||
*/
|
||||
public static function toBBCode($s)
|
||||
{
|
||||
DI::profiler()->startRecording('rendering');
|
||||
|
||||
// The parser cannot handle paragraphs correctly
|
||||
$s = str_replace(['</p>', '<p>', '<p dir="ltr">'], ['<br>', '<br>', '<br>'], $s);
|
||||
|
||||
|
@ -134,6 +135,7 @@ class Markdown
|
|||
// Don't show link to full picture (until it is fixed)
|
||||
$s = BBCode::scaleExternalImages($s);
|
||||
|
||||
DI::profiler()->stopRecording();
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,9 +236,9 @@ class Addon
|
|||
return $info;
|
||||
}
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
DI::profiler()->startRecording('file');
|
||||
$f = file_get_contents("addon/$addon/$addon.php");
|
||||
DI::profiler()->saveTimestamp($stamp1, "file");
|
||||
DI::profiler()->stopRecording();
|
||||
|
||||
$r = preg_match("|/\*.*\*/|msU", $f, $m);
|
||||
|
||||
|
|
|
@ -52,11 +52,11 @@ class ProfilerCache implements ICache, IMemoryCache
|
|||
*/
|
||||
public function getAllKeys($prefix = null)
|
||||
{
|
||||
$time = microtime(true);
|
||||
$this->profiler->startRecording('cache');
|
||||
|
||||
$return = $this->cache->getAllKeys($prefix);
|
||||
|
||||
$this->profiler->saveTimestamp($time, 'cache');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
@ -66,11 +66,11 @@ class ProfilerCache implements ICache, IMemoryCache
|
|||
*/
|
||||
public function get($key)
|
||||
{
|
||||
$time = microtime(true);
|
||||
$this->profiler->startRecording('cache');
|
||||
|
||||
$return = $this->cache->get($key);
|
||||
|
||||
$this->profiler->saveTimestamp($time, 'cache');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
@ -80,11 +80,11 @@ class ProfilerCache implements ICache, IMemoryCache
|
|||
*/
|
||||
public function set($key, $value, $ttl = Duration::FIVE_MINUTES)
|
||||
{
|
||||
$time = microtime(true);
|
||||
$this->profiler->startRecording('cache');
|
||||
|
||||
$return = $this->cache->set($key, $value, $ttl);
|
||||
|
||||
$this->profiler->saveTimestamp($time, 'cache');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
@ -94,11 +94,11 @@ class ProfilerCache implements ICache, IMemoryCache
|
|||
*/
|
||||
public function delete($key)
|
||||
{
|
||||
$time = microtime(true);
|
||||
$this->profiler->startRecording('cache');
|
||||
|
||||
$return = $this->cache->delete($key);
|
||||
|
||||
$this->profiler->saveTimestamp($time, 'cache');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
@ -108,11 +108,11 @@ class ProfilerCache implements ICache, IMemoryCache
|
|||
*/
|
||||
public function clear($outdated = true)
|
||||
{
|
||||
$time = microtime(true);
|
||||
$this->profiler->startRecording('cache');
|
||||
|
||||
$return = $this->cache->clear($outdated);
|
||||
|
||||
$this->profiler->saveTimestamp($time, 'cache');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
@ -123,11 +123,11 @@ class ProfilerCache implements ICache, IMemoryCache
|
|||
public function add($key, $value, $ttl = Duration::FIVE_MINUTES)
|
||||
{
|
||||
if ($this->cache instanceof IMemoryCache) {
|
||||
$time = microtime(true);
|
||||
$this->profiler->startRecording('cache');
|
||||
|
||||
$return = $this->cache->add($key, $value, $ttl);
|
||||
|
||||
$this->profiler->saveTimestamp($time, 'cache');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $return;
|
||||
} else {
|
||||
|
@ -141,11 +141,11 @@ class ProfilerCache implements ICache, IMemoryCache
|
|||
public function compareSet($key, $oldValue, $newValue, $ttl = Duration::FIVE_MINUTES)
|
||||
{
|
||||
if ($this->cache instanceof IMemoryCache) {
|
||||
$time = microtime(true);
|
||||
$this->profiler->startRecording('cache');
|
||||
|
||||
$return = $this->cache->compareSet($key, $oldValue, $newValue, $ttl);
|
||||
|
||||
$this->profiler->saveTimestamp($time, 'cache');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $return;
|
||||
} else {
|
||||
|
@ -159,11 +159,11 @@ class ProfilerCache implements ICache, IMemoryCache
|
|||
public function compareDelete($key, $value)
|
||||
{
|
||||
if ($this->cache instanceof IMemoryCache) {
|
||||
$time = microtime(true);
|
||||
$this->profiler->startRecording('cache');
|
||||
|
||||
$return = $this->cache->compareDelete($key, $value);
|
||||
|
||||
$this->profiler->saveTimestamp($time, 'cache');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $return;
|
||||
} else {
|
||||
|
|
|
@ -73,7 +73,7 @@ class Renderer
|
|||
*/
|
||||
public static function replaceMacros(string $template, array $vars = [])
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
DI::profiler()->startRecording('rendering');
|
||||
|
||||
// pass $baseurl to all templates if it isn't set
|
||||
$vars = array_merge(['$baseurl' => DI::baseUrl()->get(), '$APP' => DI::app()], $vars);
|
||||
|
@ -90,7 +90,7 @@ class Renderer
|
|||
throw new InternalServerErrorException($message);
|
||||
}
|
||||
|
||||
DI::profiler()->saveTimestamp($stamp1, "rendering");
|
||||
DI::profiler()->stopRecording();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ class Renderer
|
|||
*/
|
||||
public static function getMarkupTemplate($file, $subDir = '')
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
DI::profiler()->startRecording('file');
|
||||
$t = self::getTemplateEngine();
|
||||
|
||||
try {
|
||||
|
@ -119,7 +119,7 @@ class Renderer
|
|||
throw new InternalServerErrorException($message);
|
||||
}
|
||||
|
||||
DI::profiler()->saveTimestamp($stamp1, "file");
|
||||
DI::profiler()->stopRecording();
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
|
|
@ -88,9 +88,9 @@ class Theme
|
|||
return $info;
|
||||
}
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
DI::profiler()->startRecording('file');
|
||||
$theme_file = file_get_contents("view/theme/$theme/theme.php");
|
||||
DI::profiler()->saveTimestamp($stamp1, "file");
|
||||
DI::profiler()->stopRecording();
|
||||
|
||||
$result = preg_match("|/\*.*\*/|msU", $theme_file, $matches);
|
||||
|
||||
|
|
|
@ -468,6 +468,7 @@ class Database
|
|||
public function p($sql)
|
||||
{
|
||||
|
||||
$this->profiler->startRecording('database');
|
||||
$stamp1 = microtime(true);
|
||||
|
||||
$params = DBA::getParam(func_get_args());
|
||||
|
@ -695,7 +696,7 @@ class Database
|
|||
$this->errorno = $errorno;
|
||||
}
|
||||
|
||||
$this->profiler->saveTimestamp($stamp1, 'database');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
if ($this->configCache->get('system', 'db_log')) {
|
||||
$stamp2 = microtime(true);
|
||||
|
@ -727,7 +728,7 @@ class Database
|
|||
public function e($sql)
|
||||
{
|
||||
|
||||
$stamp = microtime(true);
|
||||
$this->profiler->startRecording('database_write');
|
||||
|
||||
$params = DBA::getParam(func_get_args());
|
||||
|
||||
|
@ -779,7 +780,7 @@ class Database
|
|||
$this->errorno = $errorno;
|
||||
}
|
||||
|
||||
$this->profiler->saveTimestamp($stamp, "database_write");
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
@ -914,7 +915,7 @@ class Database
|
|||
*/
|
||||
public function fetch($stmt)
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('database');
|
||||
|
||||
$columns = [];
|
||||
|
||||
|
@ -962,7 +963,7 @@ class Database
|
|||
}
|
||||
}
|
||||
|
||||
$this->profiler->saveTimestamp($stamp1, 'database');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
@ -1589,7 +1590,7 @@ class Database
|
|||
public function close($stmt)
|
||||
{
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('database');
|
||||
|
||||
if (!is_object($stmt)) {
|
||||
return false;
|
||||
|
@ -1615,7 +1616,7 @@ class Database
|
|||
break;
|
||||
}
|
||||
|
||||
$this->profiler->saveTimestamp($stamp1, 'database');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class SessionFactory
|
|||
*/
|
||||
public function createSession(App\Mode $mode, App\BaseURL $baseURL, IConfig $config, Database $dba, ICache $cache, LoggerInterface $logger, Profiler $profiler, array $server = [])
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$profiler->startRecording('session');
|
||||
$session = null;
|
||||
|
||||
try {
|
||||
|
@ -85,7 +85,7 @@ class SessionFactory
|
|||
$session = new Session\Native($baseURL, $handler);
|
||||
}
|
||||
} finally {
|
||||
$profiler->saveTimestamp($stamp1, 'parser');
|
||||
$profiler->stopRecording();
|
||||
return $session;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2726,22 +2726,6 @@ class Item
|
|||
$item['hashtags'] = $tags['hashtags'];
|
||||
$item['mentions'] = $tags['mentions'];
|
||||
|
||||
// Compile eventual content filter reasons
|
||||
$filter_reasons = [];
|
||||
if (!$is_preview && public_contact() != $item['author-id']) {
|
||||
if (!empty($item['content-warning']) && (!local_user() || !DI::pConfig()->get(local_user(), 'system', 'disable_cw', false))) {
|
||||
$filter_reasons[] = DI::l10n()->t('Content warning: %s', $item['content-warning']);
|
||||
}
|
||||
|
||||
$hook_data = [
|
||||
'item' => $item,
|
||||
'filter_reasons' => $filter_reasons
|
||||
];
|
||||
Hook::callAll('prepare_body_content_filter', $hook_data);
|
||||
$filter_reasons = $hook_data['filter_reasons'];
|
||||
unset($hook_data);
|
||||
}
|
||||
|
||||
$body = $item['body'] ?? '';
|
||||
$shared = BBCode::fetchShareAttributes($body);
|
||||
if (!empty($shared['guid'])) {
|
||||
|
@ -2765,6 +2749,22 @@ class Item
|
|||
$item['body'] = $body;
|
||||
$s = $item["rendered-html"];
|
||||
|
||||
// Compile eventual content filter reasons
|
||||
$filter_reasons = [];
|
||||
if (!$is_preview && public_contact() != $item['author-id']) {
|
||||
if (!empty($item['content-warning']) && (!local_user() || !DI::pConfig()->get(local_user(), 'system', 'disable_cw', false))) {
|
||||
$filter_reasons[] = DI::l10n()->t('Content warning: %s', $item['content-warning']);
|
||||
}
|
||||
|
||||
$hook_data = [
|
||||
'item' => $item,
|
||||
'filter_reasons' => $filter_reasons
|
||||
];
|
||||
Hook::callAll('prepare_body_content_filter', $hook_data);
|
||||
$filter_reasons = $hook_data['filter_reasons'];
|
||||
unset($hook_data);
|
||||
}
|
||||
|
||||
$hook_data = [
|
||||
'item' => $item,
|
||||
'html' => $s,
|
||||
|
@ -2858,7 +2858,7 @@ class Item
|
|||
*/
|
||||
private static function replaceVisualAttachments(array $attachments, string $body)
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
DI::profiler()->startRecording('rendering');
|
||||
|
||||
foreach ($attachments['visual'] as $attachment) {
|
||||
if (!empty($attachment['preview'])) {
|
||||
|
@ -2867,7 +2867,7 @@ class Item
|
|||
$body = str_replace($attachment['url'], Post\Media::getUrlForId($attachment['id']), $body);
|
||||
}
|
||||
}
|
||||
DI::profiler()->saveTimestamp($stamp1, 'rendering');
|
||||
DI::profiler()->stopRecording();
|
||||
return $body;
|
||||
}
|
||||
|
||||
|
@ -2881,7 +2881,7 @@ class Item
|
|||
*/
|
||||
private static function addVisualAttachments(array $attachments, array $item, string $content, bool $shared)
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$leading = '';
|
||||
$trailing = '';
|
||||
|
||||
|
@ -2957,7 +2957,7 @@ class Item
|
|||
}
|
||||
}
|
||||
|
||||
DI::profiler()->saveTimestamp($stamp1, 'rendering');
|
||||
DI::profiler()->stopRecording();
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
@ -2973,7 +2973,7 @@ class Item
|
|||
*/
|
||||
private static function addLinkAttachment(int $uriid, array $attachments, string $body, string $content, bool $shared, array $ignore_links)
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
DI::profiler()->startRecording('rendering');
|
||||
// @ToDo Check only for audio and video
|
||||
$preview = empty($attachments['visual']);
|
||||
|
||||
|
@ -3038,7 +3038,7 @@ class Item
|
|||
} elseif (preg_match("/.*(\[attachment.*?\].*?\[\/attachment\]).*/ism", $body, $match)) {
|
||||
$data = BBCode::getAttachmentData($match[1]);
|
||||
}
|
||||
DI::profiler()->saveTimestamp($stamp1, 'rendering');
|
||||
DI::profiler()->stopRecording();
|
||||
|
||||
if (isset($data['url']) && !in_array($data['url'], $ignore_links)) {
|
||||
if (!empty($data['description']) || !empty($data['image']) || !empty($data['preview'])) {
|
||||
|
@ -3086,7 +3086,7 @@ class Item
|
|||
*/
|
||||
private static function addNonVisualAttachments(array $attachments, array $item, string $content)
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
DI::profiler()->startRecording('rendering');
|
||||
$trailing = '';
|
||||
foreach ($attachments['additional'] as $attachment) {
|
||||
if (strpos($item['body'], $attachment['url'])) {
|
||||
|
@ -3112,7 +3112,7 @@ class Item
|
|||
$content .= '<div class="body-attach">' . $trailing . '<div class="clear"></div></div>';
|
||||
}
|
||||
|
||||
DI::profiler()->saveTimestamp($stamp1, 'rendering');
|
||||
DI::profiler()->stopRecording();
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ class HTTPRequest implements IHTTPRequest
|
|||
*/
|
||||
public function get(string $url, array $opts = [], &$redirects = 0)
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('network');
|
||||
|
||||
if (Network::isLocalLink($url)) {
|
||||
$this->logger->info('Local link', ['url' => $url, 'callstack' => System::callstack(20)]);
|
||||
|
@ -80,7 +80,7 @@ class HTTPRequest implements IHTTPRequest
|
|||
|
||||
if (strlen($url) > 1000) {
|
||||
$this->logger->debug('URL is longer than 1000 characters.', ['url' => $url, 'callstack' => System::callstack(20)]);
|
||||
$this->profiler->saveTimestamp($stamp1, 'network');
|
||||
$this->profiler->stopRecording();
|
||||
return CurlResult::createErrorCurl(substr($url, 0, 200));
|
||||
}
|
||||
|
||||
|
@ -99,14 +99,14 @@ class HTTPRequest implements IHTTPRequest
|
|||
|
||||
if (Network::isUrlBlocked($url)) {
|
||||
$this->logger->info('Domain is blocked.', ['url' => $url]);
|
||||
$this->profiler->saveTimestamp($stamp1, 'network');
|
||||
$this->profiler->stopRecording();
|
||||
return CurlResult::createErrorCurl($url);
|
||||
}
|
||||
|
||||
$ch = @curl_init($url);
|
||||
|
||||
if (($redirects > 8) || (!$ch)) {
|
||||
$this->profiler->saveTimestamp($stamp1, 'network');
|
||||
$this->profiler->stopRecording();
|
||||
return CurlResult::createErrorCurl($url);
|
||||
}
|
||||
|
||||
|
@ -208,13 +208,13 @@ class HTTPRequest implements IHTTPRequest
|
|||
$redirects++;
|
||||
$this->logger->notice('Curl redirect.', ['url' => $url, 'to' => $curlResponse->getRedirectUrl()]);
|
||||
@curl_close($ch);
|
||||
$this->profiler->saveTimestamp($stamp1, 'network');
|
||||
$this->profiler->stopRecording();
|
||||
return $this->get($curlResponse->getRedirectUrl(), $opts, $redirects);
|
||||
}
|
||||
|
||||
@curl_close($ch);
|
||||
|
||||
$this->profiler->saveTimestamp($stamp1, 'network');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
return $curlResponse;
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ class HTTPRequest implements IHTTPRequest
|
|||
*/
|
||||
public function post(string $url, $params, array $headers = [], int $timeout = 0, &$redirects = 0)
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('network');
|
||||
|
||||
if (Network::isLocalLink($url)) {
|
||||
$this->logger->info('Local link', ['url' => $url, 'callstack' => System::callstack(20)]);
|
||||
|
@ -236,14 +236,14 @@ class HTTPRequest implements IHTTPRequest
|
|||
|
||||
if (Network::isUrlBlocked($url)) {
|
||||
$this->logger->info('Domain is blocked.' . ['url' => $url]);
|
||||
$this->profiler->saveTimestamp($stamp1, 'network');
|
||||
$this->profiler->stopRecording();
|
||||
return CurlResult::createErrorCurl($url);
|
||||
}
|
||||
|
||||
$ch = curl_init($url);
|
||||
|
||||
if (($redirects > 8) || (!$ch)) {
|
||||
$this->profiler->saveTimestamp($stamp1, 'network');
|
||||
$this->profiler->stopRecording();
|
||||
return CurlResult::createErrorCurl($url);
|
||||
}
|
||||
|
||||
|
@ -303,13 +303,13 @@ class HTTPRequest implements IHTTPRequest
|
|||
$redirects++;
|
||||
$this->logger->info('Post redirect.', ['url' => $url, 'to' => $curlResponse->getRedirectUrl()]);
|
||||
curl_close($ch);
|
||||
$this->profiler->saveTimestamp($stamp1, 'network');
|
||||
$this->profiler->stopRecording();
|
||||
return $this->post($curlResponse->getRedirectUrl(), $params, $headers, $redirects, $timeout);
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
$this->profiler->saveTimestamp($stamp1, 'network');
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
// Very old versions of Lighttpd don't like the "Expect" header, so we remove it when needed
|
||||
if ($curlResponse->getReturnCode() == 417) {
|
||||
|
@ -358,7 +358,7 @@ class HTTPRequest implements IHTTPRequest
|
|||
|
||||
$url = trim($url, "'");
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('network');
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
|
@ -374,7 +374,7 @@ class HTTPRequest implements IHTTPRequest
|
|||
$http_code = $curl_info['http_code'];
|
||||
curl_close($ch);
|
||||
|
||||
$this->profiler->saveTimestamp($stamp1, "network");
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
if ($http_code == 0) {
|
||||
return $url;
|
||||
|
@ -403,7 +403,7 @@ class HTTPRequest implements IHTTPRequest
|
|||
return $url;
|
||||
}
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('network');
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
|
@ -417,7 +417,7 @@ class HTTPRequest implements IHTTPRequest
|
|||
$body = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
$this->profiler->saveTimestamp($stamp1, "network");
|
||||
$this->profiler->stopRecording();
|
||||
|
||||
if (trim($body) == "") {
|
||||
return $url;
|
||||
|
|
|
@ -650,9 +650,9 @@ class Image
|
|||
|
||||
$string = $this->asString();
|
||||
|
||||
$stamp1 = microtime(true);
|
||||
DI::profiler()->stopRecording('file');
|
||||
file_put_contents($path, $string);
|
||||
DI::profiler()->saveTimestamp($stamp1, "file");
|
||||
DI::profiler()->stopRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1557,7 +1557,7 @@ class Transmitter
|
|||
// The contentMap does contain the unmodified HTML.
|
||||
$language = self::getLanguage($item);
|
||||
if (!empty($language)) {
|
||||
$richbody = BBCode::setMentionsToNicknames($item['body']);
|
||||
$richbody = BBCode::setMentionsToNicknames($item['body'] ?? '');
|
||||
$richbody = BBCode::removeAttachment($richbody);
|
||||
|
||||
$data['contentMap'][$language] = BBCode::convertForUriId($item['uri-id'], $richbody, BBCode::EXTERNAL);
|
||||
|
|
|
@ -59,9 +59,9 @@ class ProfilerLogger implements LoggerInterface
|
|||
*/
|
||||
public function emergency($message, array $context = array())
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('file');
|
||||
$this->logger->emergency($message, $context);
|
||||
$this->profiler->saveTimestamp($stamp1, 'file');
|
||||
$this->profiler->stopRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,9 +69,9 @@ class ProfilerLogger implements LoggerInterface
|
|||
*/
|
||||
public function alert($message, array $context = array())
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('file');
|
||||
$this->logger->alert($message, $context);
|
||||
$this->profiler->saveTimestamp($stamp1, 'file');
|
||||
$this->profiler->stopRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,9 +79,9 @@ class ProfilerLogger implements LoggerInterface
|
|||
*/
|
||||
public function critical($message, array $context = array())
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('file');
|
||||
$this->logger->critical($message, $context);
|
||||
$this->profiler->saveTimestamp($stamp1, 'file');
|
||||
$this->profiler->stopRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,9 +89,9 @@ class ProfilerLogger implements LoggerInterface
|
|||
*/
|
||||
public function error($message, array $context = array())
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('file');
|
||||
$this->logger->error($message, $context);
|
||||
$this->profiler->saveTimestamp($stamp1, 'file');
|
||||
$this->profiler->stopRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,9 +99,9 @@ class ProfilerLogger implements LoggerInterface
|
|||
*/
|
||||
public function warning($message, array $context = array())
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('file');
|
||||
$this->logger->warning($message, $context);
|
||||
$this->profiler->saveTimestamp($stamp1, 'file');
|
||||
$this->profiler->stopRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,9 +109,9 @@ class ProfilerLogger implements LoggerInterface
|
|||
*/
|
||||
public function notice($message, array $context = array())
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('file');
|
||||
$this->logger->notice($message, $context);
|
||||
$this->profiler->saveTimestamp($stamp1, 'file');
|
||||
$this->profiler->stopRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,9 +119,9 @@ class ProfilerLogger implements LoggerInterface
|
|||
*/
|
||||
public function info($message, array $context = array())
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('file');
|
||||
$this->logger->info($message, $context);
|
||||
$this->profiler->saveTimestamp($stamp1, 'file');
|
||||
$this->profiler->stopRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,9 +129,9 @@ class ProfilerLogger implements LoggerInterface
|
|||
*/
|
||||
public function debug($message, array $context = array())
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('file');
|
||||
$this->logger->debug($message, $context);
|
||||
$this->profiler->saveTimestamp($stamp1, 'file');
|
||||
$this->profiler->stopRecording();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,8 +139,8 @@ class ProfilerLogger implements LoggerInterface
|
|||
*/
|
||||
public function log($level, $message, array $context = array())
|
||||
{
|
||||
$stamp1 = microtime(true);
|
||||
$this->profiler->startRecording('file');
|
||||
$this->logger->log($level, $message, $context);
|
||||
$this->profiler->saveTimestamp($stamp1, 'file');
|
||||
$this->profiler->stopRecording();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ class Profiler implements ContainerInterface
|
|||
*/
|
||||
private $rendertime;
|
||||
|
||||
private $timestamps = [];
|
||||
|
||||
/**
|
||||
* True, if the Profiler should measure the whole rendertime including functions
|
||||
*
|
||||
|
@ -85,6 +87,59 @@ class Profiler implements ContainerInterface
|
|||
$this->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a profiler recording
|
||||
*
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function startRecording(string $value)
|
||||
{
|
||||
if (!$this->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->timestamps[] = ['value' => $value, 'stamp' => microtime(true), 'credit' => 0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop a profiler recording
|
||||
*
|
||||
* @param string $callstack
|
||||
* @return void
|
||||
*/
|
||||
public function stopRecording(string $callstack = '')
|
||||
{
|
||||
if (!$this->enabled || empty($this->timestamps)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$timestamp = array_pop($this->timestamps);
|
||||
|
||||
$duration = floatval(microtime(true) - $timestamp['stamp'] - $timestamp['credit']);
|
||||
$value = $timestamp['value'];
|
||||
|
||||
foreach ($this->timestamps as $key => $stamp) {
|
||||
$this->timestamps[$key]['credit'] += $duration;
|
||||
}
|
||||
|
||||
$callstack = $callstack ?: System::callstack(4, $value == 'rendering' ? 0 : 1);
|
||||
|
||||
if (!isset($this->performance[$value])) {
|
||||
$this->performance[$value] = 0;
|
||||
}
|
||||
|
||||
$this->performance[$value] += (float) $duration;
|
||||
$this->performance['marktime'] += (float) $duration;
|
||||
|
||||
if (!isset($this->callstack[$value][$callstack])) {
|
||||
// Prevent ugly E_NOTICE
|
||||
$this->callstack[$value][$callstack] = 0;
|
||||
}
|
||||
|
||||
$this->callstack[$value][$callstack] += (float) $duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a timestamp for a value - f.e. a call
|
||||
* Necessary for profiling Friendica
|
||||
|
@ -143,7 +198,7 @@ class Profiler implements ContainerInterface
|
|||
$this->performance['network'] = 0;
|
||||
$this->performance['file'] = 0;
|
||||
$this->performance['rendering'] = 0;
|
||||
$this->performance['parser'] = 0;
|
||||
$this->performance['session'] = 0;
|
||||
$this->performance['marktime'] = 0;
|
||||
$this->performance['marktime'] = microtime(true);
|
||||
$this->performance['classcreate'] = 0;
|
||||
|
@ -165,7 +220,7 @@ class Profiler implements ContainerInterface
|
|||
$this->callstack['network'] = [];
|
||||
$this->callstack['file'] = [];
|
||||
$this->callstack['rendering'] = [];
|
||||
$this->callstack['parser'] = [];
|
||||
$this->callstack['session'] = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -228,6 +283,16 @@ class Profiler implements ContainerInterface
|
|||
}
|
||||
}
|
||||
|
||||
if (isset($this->callstack["rendering"])) {
|
||||
$output .= "\nRendering:\n";
|
||||
foreach ($this->callstack["rendering"] as $func => $time) {
|
||||
$time = round($time, 3);
|
||||
if ($time > $limit) {
|
||||
$output .= $func . ": " . $time . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,6 +101,8 @@ trait AppMockTrait
|
|||
->andReturn($root->url());
|
||||
|
||||
$this->profilerMock = \Mockery::mock(Profiler::class);
|
||||
$this->profilerMock->shouldReceive('startRecording');
|
||||
$this->profilerMock->shouldReceive('stopRecording');
|
||||
$this->profilerMock->shouldReceive('saveTimestamp');
|
||||
$this->dice->shouldReceive('create')
|
||||
->with(Profiler::class)
|
||||
|
|
|
@ -49,6 +49,8 @@ class DatabaseCacheTest extends CacheTest
|
|||
{
|
||||
$logger = new NullLogger();
|
||||
$profiler = Mockery::mock(Profiler::class);
|
||||
$profiler->shouldReceive('startRecording');
|
||||
$profiler->shouldReceive('stopRecording');
|
||||
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
||||
|
||||
// load real config to avoid mocking every config-entry which is related to the Database class
|
||||
|
|
|
@ -51,6 +51,8 @@ class DatabaseLockDriverTest extends LockTest
|
|||
{
|
||||
$logger = new NullLogger();
|
||||
$profiler = Mockery::mock(Profiler::class);
|
||||
$profiler->shouldReceive('startRecording');
|
||||
$profiler->shouldReceive('stopRecording');
|
||||
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
||||
|
||||
// load real config to avoid mocking every config-entry which is related to the Database class
|
||||
|
|
|
@ -69,6 +69,8 @@ class StorageManagerTest extends DatabaseTest
|
|||
$this->logger = new NullLogger();
|
||||
|
||||
$profiler = \Mockery::mock(Profiler::class);
|
||||
$profiler->shouldReceive('startRecording');
|
||||
$profiler->shouldReceive('stopRecording');
|
||||
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
||||
|
||||
// load real config to avoid mocking every config-entry which is related to the Database class
|
||||
|
|
|
@ -27,6 +27,8 @@ class ProcessTest extends DatabaseTest
|
|||
$logger = new NullLogger();
|
||||
|
||||
$profiler = \Mockery::mock(Profiler::class);
|
||||
$profiler->shouldReceive('startRecording');
|
||||
$profiler->shouldReceive('stopRecording');
|
||||
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
||||
|
||||
// load real config to avoid mocking every config-entry which is related to the Database class
|
||||
|
|
|
@ -51,6 +51,8 @@ class DatabaseStorageTest extends StorageTest
|
|||
{
|
||||
$logger = new NullLogger();
|
||||
$profiler = \Mockery::mock(Profiler::class);
|
||||
$profiler->shouldReceive('startRecording');
|
||||
$profiler->shouldReceive('stopRecording');
|
||||
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
||||
|
||||
// load real config to avoid mocking every config-entry which is related to the Database class
|
||||
|
|
|
@ -52,6 +52,8 @@ class FilesystemStorageTest extends StorageTest
|
|||
{
|
||||
$logger = new NullLogger();
|
||||
$profiler = \Mockery::mock(Profiler::class);
|
||||
$profiler->shouldReceive('startRecording');
|
||||
$profiler->shouldReceive('stopRecording');
|
||||
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
||||
|
||||
/** @var MockInterface|L10n $l10n */
|
||||
|
|
|
@ -59,7 +59,9 @@ class ProfilerLoggerTest extends MockedTest
|
|||
$logger = new ProfilerLogger($this->logger, $this->profiler);
|
||||
|
||||
$this->logger->shouldReceive($function)->with($message, $context)->once();
|
||||
$this->profiler->shouldReceive('saveTimestamp')->with(\Mockery::any(), 'file')->once();
|
||||
$this->profiler->shouldReceive('startRecording')->with('file')->once();
|
||||
$this->profiler->shouldReceive('stopRecording');
|
||||
$this->profiler->shouldReceive('saveTimestamp');
|
||||
$logger->$function($message, $context);
|
||||
}
|
||||
|
||||
|
@ -72,7 +74,9 @@ class ProfilerLoggerTest extends MockedTest
|
|||
$logger = new ProfilerLogger($this->logger, $this->profiler);
|
||||
|
||||
$this->logger->shouldReceive('log')->with(LogLevel::WARNING, 'test', ['a' => 'context'])->once();
|
||||
$this->profiler->shouldReceive('saveTimestamp')->with(\Mockery::any(), 'file')->once();
|
||||
$this->profiler->shouldReceive('startRecording')->with('file')->once();
|
||||
$this->profiler->shouldReceive('stopRecording');
|
||||
$this->profiler->shouldReceive('saveTimestamp');
|
||||
|
||||
$logger->log(LogLevel::WARNING, 'test', ['a' => 'context']);
|
||||
}
|
||||
|
|
|
@ -99,14 +99,14 @@ class ProfilerTest extends MockedTest
|
|||
'name' => 'rendering',
|
||||
'functions' => ['test', 'it7'],
|
||||
],
|
||||
'parser' => [
|
||||
'session' => [
|
||||
'timestamp' => time(),
|
||||
'name' => 'parser',
|
||||
'name' => 'session',
|
||||
'functions' => ['test', 'it8'],
|
||||
],
|
||||
'marktime' => [
|
||||
'timestamp' => time(),
|
||||
'name' => 'parser',
|
||||
'name' => 'session',
|
||||
'functions' => ['test'],
|
||||
],
|
||||
// This one isn't set during reset
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue