/** * Get a very short desc. Used in the widget list. * * @return string The block title, the first 60 characters of the block * content or an empty string. */ function get_short_desc() { if (empty($this->disp_params['title'])) { return strmaxlen($this->disp_params['content'], 60, NULL, 'formvalue'); } return format_to_output($this->disp_params['title']); }
/** * Get "nice" title of the Item * @return string */ function get_title($params = array()) { global $ReqURL, $Blog, $MainList; // Set default post navigation $def_post_navigation = empty($Blog) ? 'same_blog' : $Blog->get_setting('post_navigation'); // Make sure we are not missing any param: $params = array_merge(array('before' => '', 'after' => '', 'format' => 'htmlbody', 'link_type' => '#', 'link_class' => '#', 'max_length' => '', 'target_blog' => '', 'nav_target' => NULL, 'post_navigation' => $def_post_navigation, 'title_field' => 'title'), $params); // Set post navigation target $nav_target = $params['nav_target'] === NULL && isset($MainList) && !empty($MainList->nav_target) ? $MainList->nav_target : $params['nav_target']; $blogurl = ''; if (!empty($Blog) && $this->check_cross_post_nav($params['target_blog'], $Blog->ID)) { $blogurl = $Blog->gen_blogurl(); } $title = format_to_output($this->{$params}['title_field'], $params['format']); if ($params['max_length'] != '') { // Crop long title $title = strmaxlen($title, intval($params['max_length'])); } if (empty($title)) { return; } if ($params['link_type'] == '#') { // Use default link type from settings: if ($this->is_intro()) { // This is an intro, do not link title by default: $params['link_type'] = 'none'; } elseif (is_same_url($this->get_permanent_url('', $blogurl, '&'), $ReqURL)) { // We are on the single url already: $params['link_type'] = 'none'; } else { if ($this->ptyp_ID == 3000) { // tblue> This is a sidebar link, link to its "link to" URL by default: $params['link_type'] = 'linkto_url'; } else { // This is a normal post: use default link strategy from Blog settings: $this->get_Blog(); $params['link_type'] = $this->Blog->get_setting('title_link_type'); } } } switch ($params['link_type']) { case 'auto': $url = empty($this->url) ? $this->get_permanent_url() : $this->url; break; case 'permalink': $url = $this->get_permanent_url('', $blogurl); break; case 'linkto_url': $url = $this->url; break; case 'admin_view': $url = '?ctrl=items&blog=' . $this->get_blog_ID() . '&p=' . $this->ID; break; case 'none': default: } if (!empty($url)) { // url is set, also add navigation param if it is necessary $url = $this->add_navigation_param($url, $params['post_navigation'], $nav_target); } $link_class = ''; if ($params['link_class'] != '#') { $link_class = ' class="' . $params['link_class'] . '"'; } $r = $params['before']; if (!empty($url)) { $r .= '<a href="' . $url . '"' . $link_class . '>' . $title . '</a>'; } else { $r .= $title; } $r .= $params['after']; return $r; }
/** * Generate the excerpt for post * * @param string * @return string */ function phpbb_generate_excerpt($content) { $content = trim(strip_tags($content)); return strmaxlen($content, 254, '…'); }
/** * Get a function trace from {@link debug_backtrace()} as html table. * * Adopted from {@link http://us2.php.net/manual/de/function.debug-backtrace.php#47644}. * * @todo dh> Add support for $is_cli = true (e.g. in case of MySQL error) * * @param integer|NULL Get the last x entries from the stack (after $ignore_from is applied). Anything non-numeric means "all". * @param array After a key/value pair matches a stack entry, this and the rest is ignored. * For example, array('class' => 'DB') would exclude everything after the stack * "enters" class DB and everything that got called afterwards. * You can also give an array of arrays which means that every condition in one of the given array must match. * @param integer Number of stack entries to include, after $ignore_from matches. * @return string HTML table */ function debug_get_backtrace($limit_to_last = NULL, $ignore_from = array('function' => 'debug_get_backtrace'), $offset_ignore_from = 0) { if (!function_exists('debug_backtrace')) { return 'Function debug_backtrace() is not available!'; } $r = ''; $backtrace = debug_backtrace(); $count_ignored = 0; // remember how many have been ignored $limited = false; // remember if we have limited to $limit_to_last if ($ignore_from) { // we want to ignore from a certain point $trace_length = 0; $break_because_of_offset = false; for ($i = count($backtrace); $i > 0; $i--) { // Search the backtrace from behind (first call). $l_stack =& $backtrace[$i - 1]; if ($break_because_of_offset && $offset_ignore_from < 1) { // we've respected the offset, but need to break now break; // ignore from here } foreach ($ignore_from as $l_ignore_key => $l_ignore_value) { // Check if we want to ignore from here if (is_array($l_ignore_value)) { // It's an array - all must match foreach ($l_ignore_value as $l_ignore_mult_key => $l_ignore_mult_val) { if (!isset($l_stack[$l_ignore_mult_key]) || strcasecmp($l_stack[$l_ignore_mult_key], $l_ignore_mult_val)) { continue 2; // next ignore setting, because not all match. } } if ($offset_ignore_from-- > 0) { $break_because_of_offset = true; break; } break 2; // ignore from here } elseif (isset($l_stack[$l_ignore_key]) && !strcasecmp($l_stack[$l_ignore_key], $l_ignore_value)) { if ($offset_ignore_from-- > 0) { $break_because_of_offset = true; break; } break 2; // ignore from here } } $trace_length++; } $count_ignored = count($backtrace) - $trace_length; $backtrace = array_slice($backtrace, 0 - $trace_length); // cut off ignored ones } $count_backtrace = count($backtrace); if (is_numeric($limit_to_last) && $limit_to_last < $count_backtrace) { // we want to limit to a maximum number $limited = true; $backtrace = array_slice($backtrace, 0, $limit_to_last); $count_backtrace = $limit_to_last; } $r .= '<div style="padding:1ex; margin-bottom:1ex; text-align:left; color:#000; background-color:#ddf;"> <h3>Backtrace:</h3>' . "\n"; if ($count_backtrace) { $r .= '<ol style="font-family:monospace;">'; $i = 0; foreach ($backtrace as $l_trace) { if (++$i == $count_backtrace) { $r .= '<li style="padding:0.5ex 0;">'; } else { $r .= '<li style="padding:0.5ex 0; border-bottom:1px solid #77d;">'; } $args = array(); if (isset($l_trace['args']) && is_array($l_trace['args'])) { // Prepare args: foreach ($l_trace['args'] as $l_arg) { $l_arg_type = gettype($l_arg); switch ($l_arg_type) { case 'integer': case 'double': $args[] = $l_arg; break; case 'string': $args[] = '"' . strmaxlen(str_replace("\n", '\\n', $l_arg), 255, NULL, 'htmlspecialchars') . '"'; break; case 'array': $args[] = 'Array(' . count($l_arg) . ')'; break; case 'object': $args[] = 'Object(' . get_class($l_arg) . ')'; break; case 'resource': $args[] = htmlspecialchars((string) $l_arg); break; case 'boolean': $args[] = $l_arg ? 'true' : 'false'; break; default: $args[] = $l_arg_type; } } } $call = "<strong>\n"; if (isset($l_trace['class'])) { $call .= htmlspecialchars($l_trace['class']); } if (isset($l_trace['type'])) { $call .= htmlspecialchars($l_trace['type']); } $call .= htmlspecialchars($l_trace['function']) . "( </strong>\n"; if ($args) { $call .= ' ' . implode(', ', $args) . ' '; } $call .= '<strong>)</strong>'; $r .= $call . "<br />\n"; $r .= '<strong>'; if (isset($l_trace['file'])) { $r .= "File: </strong> " . $l_trace['file']; } else { $r .= '[runtime created function]</strong>'; } if (isset($l_trace['line'])) { $r .= ' on line ' . $l_trace['line']; } $r .= "</li>\n"; } $r .= '</ol>'; } else { $r .= '<p>No backtrace available.</p>'; } // Extra notes, might be to much, but explains why we stopped at some point. Feel free to comment it out or remove it. $notes = array(); if ($count_ignored) { $notes[] = 'Ignored last: ' . $count_ignored; } if ($limited) { $notes[] = 'Limited to' . ($count_ignored ? ' remaining' : '') . ': ' . $limit_to_last; } if ($notes) { $r .= '<p class="small">' . implode(' - ', $notes) . '</p>'; } $r .= "</div>\n"; return $r; }
/** * Get current Comment for an XML-RPC request. * * @param xmlrpcmsg XML-RPC Message * @param integer idx of comment ID param * @return Comment or NULL */ function &xmlrpcs_get_Comment($m, $id_param) { global $xmlrpcs_errcode, $xmlrpcs_errmsg, $xmlrpcerruser; $id = $m->getParam($id_param); $id = $id->scalarval(); /** * @var CommentCache */ $CommentCache =& get_CommentCache(); /** * @var Comment */ $edited_Comment =& $CommentCache->get_by_ID($id, false, false); if (empty($edited_Comment)) { // Comment not found $xmlrpcs_errcode = $xmlrpcerruser + 9; $xmlrpcs_errmsg = 'Requested comment (' . $id . ') does not exist.'; $r = NULL; return $r; } logIO('Requested Comment: ' . $edited_Comment->ID . ' - ' . strmaxlen($edited_Comment->content, 30)); return $edited_Comment; }
if ($commented_Item->comment_status != 'open') { trackback_response(1, 'Sorry, this item does not accept trackbacks.'); // exits } // CHECK content if ($error = validate_url($url, 'commenting')) { $Messages->add(T_('Supplied URL is invalid: ') . $error, 'error'); } if ($Messages->has_errors()) { trackback_response(1, $Messages->get_string('', '', "\n")); // exits } // TODO: dh> title and excerpt should be htmlbody, too, no? $title = strmaxlen(strip_tags($title), 255, '...', 'raw'); $excerpt = strmaxlen(strip_tags($excerpt), 255, '...', 'raw'); $blog_name = strmaxlen($blog_name, 255, '...', 'htmlbody'); $comment = ''; if (!empty($title)) { $comment .= '<strong>' . $title . '</strong>'; if (!empty($excerpt)) { $comment .= '<br />'; } } $comment .= $excerpt; $comment = format_to_post($comment, 1); // includes antispam if (empty($comment)) { // comment should not be empty! $Messages->add(T_('Please do not send empty comment'), 'error'); } /**
function get_maxlen_name($maxlen = 50) { return strmaxlen($this->get_name(), $maxlen, NULL, 'raw'); }
function display_list_comments($limit = 6) { global $Blog, $app_version; if (version_compare($app_version, '4.0') < 0) { $CommentList = new CommentList($Blog, "'comment'", array('published'), '', '', 'DESC', '', $limit); } else { $CommentList = new CommentList2($Blog, $limit); // Filter list: $CommentList->set_filters(array('types' => array('comment'), 'statuses' => array('published'), 'post_ID' => NULL, 'order' => 'DESC')); // Get ready for display (runs the query): $CommentList->display_init(); } if ($CommentList->result_num_rows > 0) { while ($Comment =& $CommentList->get_next()) { $Comment->get_Item(); echo '<li class="clearfix"><a class="fadeThis" href="' . $Comment->get_permanent_url() . '"><span class="avatar post-thumb">' . $this->get_avatar($Comment, 'crop-48x48', 48) . '</span><span class="clearfix entry">' . $Comment->get_author_name() . ': <span class="details">' . strmaxlen($Comment->get_content('text'), 60) . '</span></span></a></li>'; } } return false; }
function send_a_tweet($content, &$Item, &$xmlrpcresp) { // Uses either plugin CollSettings or UserSettings $oauth = $this->get_oauth_info(array('user_ID' => $Item->get_creator_User()->ID, 'blog_ID' => $Item->get_Blog()->ID)); if (empty($oauth['msg_format']) || empty($oauth['token']) || empty($oauth['token_secret'])) { // Not found, fallback to Trying to get twitter account for User: $xmlrpcresp = T_('You must configure a twitter username/password before you can post to twitter.'); return false; } $content = array_merge(array('title' => '', 'excerpt' => '', 'url' => ''), $content); $msg = str_replace(array('$title$', '$excerpt$'), array($content['title'], $content['excerpt']), $oauth['msg_format']); $msg_len = evo_strlen($msg); $full_url_len = evo_strlen($content['url']); $base_url_len = evo_strlen($Item->get_Blog()->get_baseurl_root()); if (evo_strpos($msg, '$url$') === 0 && $base_url_len + $msg_len - 5 > $this->message_length_limit) { // The message is too long and is starting with $url$ $max_len = $this->message_length_limit + $full_url_len - $base_url_len; $msg = strmaxlen(str_replace('$url$', $content['url'], $msg), $max_len, '...'); } elseif (evo_strpos(strrev($msg), 'p2b# $lru$') === 0 && $base_url_len + $msg_len - 10 > $this->message_length_limit) { // The message is too long and is ending on '$url$ #b2p' // Strip $url$, crop the message, and add URL to the end $max_len = $this->message_length_limit - $base_url_len - 1; // save room for space character $msg = strmaxlen(str_replace('$url$ #b2p', '', $msg), $max_len, '...'); $msg .= ' ' . $content['url'] . ' #b2p'; } elseif (evo_strpos(strrev($msg), '$lru$') === 0 && $base_url_len + $msg_len - 5 > $this->message_length_limit) { // Same as above, but without '#b2p' suffix $max_len = $this->message_length_limit - $base_url_len - 1; // save room for space character $msg = strmaxlen(str_replace('$url$', '', $msg), $max_len, '...'); $msg .= ' ' . $content['url']; } elseif (evo_strpos($msg, '$url$') !== false && $base_url_len + $msg_len - 5 > $this->message_length_limit) { // Message is too long and $url$ is somewhere in the middle // We can't do much, it will be rejected by Twitter // TODO: find a way to trim X chars before the URL and Y chars after $msg = str_replace('$url$', $content['url'], $msg); } else { // We don't want to add URL. Crop the message if needed $msg = strmaxlen(str_replace('$url$', $content['url'], $msg), $this->message_length_limit, '...'); } require_once 'twitteroauth/twitteroauth.php'; $connection = new TwitterOAuth(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, $oauth['token'], $oauth['token_secret']); $result = $connection->post('statuses/update', array('status' => $msg)); if (empty($result)) { $xmlrpcresp = 'Unknown error while posting "' . $msg . '" to account @' . $oauth['contact']; return false; } elseif (!empty($result->error)) { $xmlrpcresp = $result->error; return false; } if (empty($oauth['contact'])) { $oauth['contact'] = $this->get_twitter_contact($oauth['token'], $oauth['token_secret']); } $xmlrpcresp = T_('Posted to account @') . $oauth['contact']; return true; }
/** * Format a SQL query * @static * @param string SQL * @param boolean Format with/for HTML? */ function format_query($sql, $html = true, $maxlen = NULL) { $sql = trim(str_replace("\t", ' ', $sql)); if ($maxlen) { $sql = strmaxlen($sql, $maxlen, '...'); } $new = ''; $word = ''; $in_comment = false; $in_literal = false; for ($i = 0, $n = strlen($sql); $i < $n; $i++) { $c = $sql[$i]; if ($in_comment) { if ($in_comment === '/*' && substr($sql, $i, 2) == '*/') { $in_comment = false; } elseif ($c == "\n") { $in_comment = false; } } elseif ($in_literal) { if ($c == $in_literal) { $in_literal = false; } } elseif ($c == '#' || $c == '-' && substr($sql, $i, 3) == '-- ') { $in_comment = true; } elseif (ctype_space($c)) { $uword = strtoupper($word); if (in_array($uword, array('SELECT', 'FROM', 'WHERE', 'GROUP', 'ORDER', 'LIMIT', 'VALUES', 'AND', 'OR', 'LEFT', 'RIGHT', 'INNER'))) { $new = rtrim($new) . "\n" . str_pad($word, 6, ' ', STR_PAD_LEFT) . ' '; # Remove any trailing whitespace after keywords while (ctype_space($sql[$i + 1])) { ++$i; } } else { $new .= $word . $c; } $word = ''; continue; } $word .= $c; } $sql = trim($new . $word); if ($html) { // poor man's indent $sql = preg_replace_callback("~^(\\s+)~m", create_function('$m', 'return str_replace(" ", " ", $m[1]);'), $sql); $sql = nl2br($sql); } return $sql; }
/** * Test {@link strmaxlen()} */ function test_strmaxlen() { $this->assertEqual(strmaxlen('foo', 3), 'foo'); $this->assertEqual(strmaxlen('foo', 2), 'f…'); $this->assertEqual(strmaxlen('foo', 2, '.'), 'f.'); $this->assertEqual(strmaxlen('foobar', 6, '...'), 'foobar'); $this->assertEqual(strmaxlen('foobar', 5, '...'), 'fo...'); $this->assertEqual(strmaxlen('foobar', 5, '&…'), 'foo&…'); $this->assertEqual(strmaxlen('M?', 2), 'M?', 'Do not cut utf8 char in the middle'); $this->assertEqual(strmaxlen('1', 1, '…'), '1'); $this->assertEqual(strmaxlen('1', 1, '...'), '1'); $this->assertEqual(strmaxlen('123', 1, '...'), '...'); $this->assertEqual(strmaxlen('12345', 1, '...'), '...'); $this->assertEqual(strmaxlen('1&2', 3, NULL, 'htmlbody'), '1&2'); $this->assertEqual(strmaxlen('1&2', 3, NULL, 'raw'), '1&2'); $this->assertEqual(strmaxlen('1&2', 3), '1&2'); $this->assertEqual(strmaxlen('1&2', 10, NULL, 'htmlbody'), '1&2'); $this->assertEqual(strmaxlen('1&2', 10, NULL, 'formvalue'), '1&amp;2'); # special cases, where entities must not get cut in the middle $this->assertEqual(strmaxlen('1&2', 5, NULL, 'htmlbody'), '1…'); $this->assertEqual(strmaxlen('1&22', 7, NULL, 'htmlbody'), '1&…'); $this->assertEqual(strmaxlen('1&2', 3, NULL, 'formvalue'), '1…'); $this->assertEqual(strmaxlen('1& 2', 3, NULL, 'formvalue'), '1&…'); $this->assertEqual(strmaxlen('1&2', 3, NULL, 'formvalue'), '1&2'); $this->assertEqual(strmaxlen('12345678901234567890&', 21, NULL, 'formvalue'), '12345678901234567890…'); $this->assertEqual(strmaxlen('123456789012345&', 21, NULL, 'formvalue'), '123456789012345&amp;'); $this->assertEqual(strmaxlen('foo ', 3), 'foo'); $this->assertEqual(strmaxlen('foo ', 4), 'foo'); $this->assertEqual(strmaxlen('foo bar', 3), 'fo…'); $this->assertEqual(strmaxlen('foo bar', 4), 'foo…'); $this->assertEqual(strmaxlen('foo bar', 5), 'foo…'); $this->assertEqual(strmaxlen('foo bar', 6), 'foo b…'); // test cut_at_whitespace: $this->assertEqual(strmaxlen('foo bar', 5, ''), 'foo b'); $this->assertEqual(strmaxlen('foo bar', 5, '', 'raw', true), 'foo'); $this->assertEqual(strmaxlen('foo bar', 5, '.', 'raw', true), 'foo.'); $this->assertEqual(strmaxlen('foo bar', 4, '.', 'raw', true), 'foo.'); $this->assertEqual(strmaxlen('foo bar', 2, '', 'raw', true), 'fo'); $this->assertEqual(strmaxlen('foo bar', 2, '..', 'raw', true), '..'); $this->assertEqual(strmaxlen("foo\nbar", 2, '', 'raw', true), 'fo'); $this->assertEqual(strmaxlen("foo\nbar", 3, '', 'raw', true), 'foo'); $this->assertEqual(strmaxlen("foo\nbar", 4, '', 'raw', true), 'foo'); }
/** * Get a blog full name with link to edit * * @param string Blog full name * @param integer Blog ID * @return string Link */ function blog_row_fullname($coll_fullname, $coll_ID) { global $current_User, $admin_url; $coll_fullname = strmaxlen($coll_fullname, 40, NULL, 'raw'); if ($current_User->check_perm('blog_properties', 'edit', false, $coll_ID)) { // Blog setting & can edit $edit_url = $admin_url . '?ctrl=coll_settings&tab=general&blog=' . $coll_ID; $r = '<a href="' . $edit_url . '" title="' . T_('Edit properties...') . '">'; $r .= $coll_fullname; $r .= '</a>'; } else { $r = $coll_fullname; } return $r; }
/** * Show affected comments * * @param array affected Comment list, all comments in this list must have the same status * @param string Comment visibility status in this list * @param string ban keyword * @param integer The number of corresponding comments on which current user has no permission */ function echo_affected_comments($affected_comments, $status, $keyword, $noperms_count) { global $current_User; $num_comments = count($affected_comments); if ($num_comments == 0) { if ($noperms_count == 0) { // There isn't any affected comment witch corresponding status printf('<p>' . T_('No %s comments match the keyword [%s].') . '</p>', '<strong>' . $status . '</strong>', htmlspecialchars($keyword)); } else { // There are affected comment witch corresponding status, but current user has no permission printf('<p>' . T_('There are %d matching %s comments, but you have no permission to edit them.') . '</p>', $noperms_count, '<strong>' . $status . '</strong>'); } return; } echo '<p>'; if ($current_User->check_perm('blogs', 'editall', false)) { // current User has rights to permanently delete comments $checkbox_status = 'checked="checked"'; } else { // current User doesn't have rights to permanently delete comments, so disable delete checkbox $checkbox_status = 'disabled="disabled"'; } echo '<input type="checkbox" name="del' . $status . '" id="del' . $status . '_cb" value="1" ' . $checkbox_status . '/>'; echo '<label for="del' . $status . '_cb"> '; echo sprintf(T_('Delete the following %s %s comments:'), $num_comments == 500 ? '500+' : $num_comments, '<strong>' . $status . '</strong>'); echo '</label>'; echo '</p>'; echo '<table class="grouped" cellspacing="0">'; echo '<thead><tr>'; echo '<th class="firstcol">' . T_('Date') . '</th>'; echo '<th class="center">' . T_('Auth. IP') . '</th>'; echo '<th>' . T_('Author') . '</th>'; echo '<th>' . T_('Auth. URL') . '</th>'; echo '<th>' . T_('Content starts with...') . '</th>'; echo '<th class="shrinkwrap">' . T_('Action') . '</th>'; echo '</tr></thead>'; $count = 0; foreach ($affected_comments as $Comment) { echo '<tr class="' . ($count % 2 == 1 ? 'odd' : 'even') . '">'; echo '<td class="firstcol timestamp">' . mysql2localedatetime_spans($Comment->get('date')) . '</td>'; echo '<td class="center">' . $Comment->get('author_IP') . '</td>'; echo '<td>' . $Comment->get_author_name() . '</td>'; echo '<td>'; disp_url($Comment->get_author_url(), 50); echo '</td>'; echo '<td>' . strmaxlen(strip_tags($Comment->get_content('raw_text')), 71) . '</td>'; // no permission check, because affected_comments contains current user editable comments echo '<td class="shrinkwrap">' . action_icon(T_('Edit...'), 'edit', '?ctrl=comments&action=edit&comment_ID=' . $Comment->ID) . '</td>'; echo '</tr>'; $count++; } echo "</tbody></table>"; }
/** * Displays keywords used for search leading to this page */ function stats_search_keywords($keyphrase, $length = 45) { global $evo_charset; if (empty($keyphrase)) { return '<span class="note">[' . T_('n.a.') . ']</span>'; } // Save original string $keyphrase_orig = $keyphrase; $keyphrase = strmaxlen($keyphrase, $length, '...', 'raw'); // Convert keyword encoding, some charsets are supported only in PHP 4.3.2 and later. // This fixes encoding problem for Cyrillic keywords // See http://forums.b2evolution.net/viewtopic.php?t=17431 $keyphrase = htmlentities($keyphrase, ENT_COMPAT, $evo_charset); return '<span title="' . format_to_output($keyphrase_orig, 'htmlattr') . '">' . $keyphrase . '</span>'; }
/** * Get autogenerated excerpt, derived from {@link Item::$content}. * * @param integer Crop length * @param string Suffix, if cropped * @return string */ function get_autogenerated_excerpt($crop_length = 254, $suffix = '…') { // autogenerated excerpt should NEVER show anything after <!-- more --> or after <!-- page --> $content_parts = $this->get_content_parts(array('disppage' => 1)); $excerpt_content = array_shift($content_parts); $r = str_replace('<p>', ' <p>', $excerpt_content); $r = str_replace('<br', ' <br', $excerpt_content); $r = trim(strip_tags($r)); // fp> this is borked: $r = preg_replace('~(\r?\n)+~', '\n', $r); $r = trim($r); $r = strmaxlen($r, $crop_length, $suffix); return $r; }