News:

Want to get involved in developing SMF, then why not lend a hand on our github!

Main Menu

Pretty URLs

Started by SMFHacks.com Team, January 31, 2007, 10:56:43 AM

Previous topic - Next topic

vbgamer45

Proceed make sure you update to the latest smf version though
Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

Gryzor

So you mean I could just ignore the warning?

As for "latest version": the forum wants to update incrementally it would seem, do you mean continue on to update till the latest version as a general advice or go directly to the last one?

Thanks for your reply :)

vbgamer45

Yes just ignore.
Yes upgrade incrementally all the way to the current.
Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

Gryzor


nend

#7404
I haven't replied to this topic awhile, been optimizing the script a little, trying to squeeze some extra performance from it.

On my original cache experiment I believe a few years back, might as well chunk that.  :laugh:

Lately I have been caching only topics as that is one of the main database calls in the script and all the rest is processed which a good server should be able to handle just fine.

My Pretty URLs script now days.
<?php
// NEnd's custom Pretty URLs OB rewrite
// Based on Version 1.0 PrettyUrls-Filters.php

if (!defined('SMF'))
die('Hacking attempt...');

// Rewrite the buffer with Pretty URLs!
function pretty_rewrite_buffer($buffer)
{
global $boardurl$context$modSettings$smcFunc;

// Remove the script tags now
$context['pretty']['scriptID'] = 0;
$context['pretty']['scripts'] = array();
$buffer preg_replace_callback('~<script.+?</script>~s''pretty_scripts_remove'$buffer);

// Find all URLs in the buffer
$context['pretty']['search_patterns'][] = '~(<a[^>]+href=|<link[^>]+href=|<form[^>]+?action=|<meta property=\"og:url\" content=|<meta property=\"og:image\" content=|<meta property=\"og:video\" content=)(\"[^\"#]+|\'[^\'#]+)~';
$urls = array();
$context['pretty']['cached_urls'] = array();
foreach ($context['pretty']['search_patterns'] as $pattern) {
preg_match_all($pattern$buffer$matchesPREG_PATTERN_ORDER);
foreach ($matches[2] as $match) {
// Rip out everything that shouldn't be cached
$match preg_replace(array('~^[\"\']|PHPSESSID=[^;]+|(se)?sc=[^;]+|' $context['session_var'] . '=[^;]+~''~\"~''~;+|=;~''~\?;~''~\?$|;$|=$~'), array('''%22'';''?'''), $match);
// Absolutise relative URLs
if (!preg_match('~^[a-zA-Z]+:|^#|@~'$match) && SMF != 'SSI')
$match $boardurl '/' $match;
if (substr($match,0,7) == 'mailto:' || substr($match,0,10) == 'javascript' || !strstr($match'?'))
continue;
if (substr($match,0,strlen($boardurl)) != $boardurl || substr($match,strlen($boardurl),8) == '/Sources' || substr($match,strlen($boardurl),7) == '/Themes' || substr($match,strlen($boardurl),4) == '/img' || substr($match,strlen($boardurl),8) == '/Smileys' || substr($match,strlen($boardurl),8) == '/avatars')
continue;
// if (($data = cache_get_data('pretty-'.$match, 60)) != null) {
// $context['pretty']['cached_urls'][$match] = unserialize($data);
// } else {
$urls[$match] = array('url' => $match);
// }
}
}

// Procede only if there are actually URLs in the page
if (count($urls) != 0)
{
// Run each filter callback function on each URL
$filter_callbacks unserialize($modSettings['pretty_filter_callbacks']);
foreach ($filter_callbacks as $callback)
$urls call_user_func($callback$urls);

// Fill the cached URLs array
foreach ($urls as $url_id => $url)
{
if (!isset($url['replacement'])) {$url['replacement'] = $url['url'];}
$url['replacement'] = str_replace("\x12"'\''$url['replacement']);
$url['replacement'] = preg_replace(array('~\"~''~;+|=;~''~\?;~''~\?$|;$|=$~'), array('%22'';''?'''), $url['replacement']);
$context['pretty']['cached_urls'][$url_id] = $url['replacement'];
// cache_put_data('pretty-'.$url_id, serialize($url['replacement']), 60);
}
}

// Put the URLs back into the buffer
$context['pretty']['replace_patterns'][] = '~(<a[^>]+href=|<link[^>]+href=|<form[^>]+?action=|<meta property=\"og:url\" content=|<meta property=\"og:image\" content=|<meta property=\"og:video\" content=)(\"[^\"]+\"|\'[^\']+\')~';
foreach ($context['pretty']['replace_patterns'] as $pattern)
$buffer preg_replace_callback($pattern'pretty_buffer_callback'$buffer);

// Restore the script tags
if ($context['pretty']['scriptID'] > 0)
$buffer preg_replace_callback("~\x14([0-9]+)\x14~"'pretty_scripts_restore'$buffer);

// Return the changed buffer.
return $buffer;
}

// Remove and save script tags
function pretty_scripts_remove($match)
{
global $context;

$context['pretty']['scriptID']++;
$context['pretty']['scripts'][$context['pretty']['scriptID']] = $match[0];
return "\x14" $context['pretty']['scriptID'] . "\x14";
}

// A callback function to replace the buffer's URLs with their cached URLs
function pretty_buffer_callback($matches)
{
global $boardurl$context;

// Is this URL in an attribute, and so will need new quotes?
$addQuotes preg_match('~^[\"\']~'$matches[2]);

// Remove those annoying quotes
$matches[2] = preg_replace('~^[\"\']|[\"\']$~'''$matches[2]);

// Store the parts of the URL that won't be cached so they can be inserted later
preg_match('~PHPSESSID=[^;#&]+~'$matches[2], $PHPSESSID);
preg_match('~(se)?sc=[^;#]+~'$matches[2], $sesc);
preg_match('~' $context['session_var'] . '=[^;#]+~'$matches[2], $session_var);
preg_match('~#.*~'$matches[2], $fragment);

// Rip out everything that won't have been cached
$url_id preg_replace(array('~PHPSESSID=[^;#]+|(se)?sc=[^;#]+|' $context['session_var'] . '=[^;#]+|#.*$~''~\"~''~;+|=;~''~\?;~''~\?$|;$|=$~'), array('''%22'';''?'''), $matches[2]);

// Absolutise relative URLs
if (!preg_match('~^[a-zA-Z]+:|@~'$url_id) && !($url_id == '' && isset($fragment[0])) && SMF != 'SSI')
$url_id $boardurl '/' $url_id;

// Stitch everything back together, clean it up and return
$replacement = isset($context['pretty']['cached_urls'][$url_id]) ? $context['pretty']['cached_urls'][$url_id] : $url_id;
$replacement .= (strpos($replacement'?') === false '?' ';') . (isset($PHPSESSID[0]) ? $PHPSESSID[0] : '') . ';' . (isset($sesc[0]) ? $sesc[0] : '') . (isset($session_var[0]) ? $session_var[0] : '') . (isset($fragment[0]) ? $fragment[0] : '');
$replacement preg_replace(array('~;+|=;~''~\?;~''~\?#|;#|=#~''~\?$|&amp;$|;$|#$|=$~'), array(';''?''#'''), $replacement);
$replacement str_replace('index.php'''$replacement);// Remove index.php, who needs it.
return $matches[1] . ($addQuotes '"' '') . $replacement . ($addQuotes '"' '');
}

// Put the script tags back
function pretty_scripts_restore($match)
{
global $context;

return $context['pretty']['scripts'][(int) $match[1]];
}

// Filter miscellaneous action urls
function pretty_urls_actions_filter($urls)
{
global $boardurl$context$modSettings$scripturl;

$skip_actions = array();
if (isset($modSettings['pretty_skipactions']))
$skip_actions explode(",",$modSettings['pretty_skipactions']);

$pattern '`' $scripturl '(.*)action=([^;]+)`S';
$replacement $boardurl '/$2/$1';
foreach ($urls as $url_id => $url)
if (!isset($url['replacement']))
if (preg_match($pattern$url['url'], $matches))
{
// Don't rewrite these actions
if (!empty($skip_actions))
if (in_array($matches[2],$skip_actions))
continue;

if (in_array($matches[2], $context['pretty']['action_array']))
$urls[$url_id]['replacement'] = preg_replace($pattern$replacement$url['url']);
}
return $urls;
}

// Filter topic urls
function pretty_urls_topic_filter($urls)
{
global $context$modSettings$scripturl$smcFunc$sourcedir;

$pattern '`' $scripturl '(.*[?;&])topic=([.a-zA-Z0-9]+)(.*)`S';
$query_data = array();
foreach ($urls as $url_id => $url)
{
// Get the topic data ready to query the database with
if (!isset($url['replacement']))
if (preg_match($pattern$url['url'], $matches))
{
if (strpos($matches[2], '.') !== false)
list ($urls[$url_id]['topic_id'], $urls[$url_id]['start']) = explode('.'$matches[2]);
else
{
$urls[$url_id]['topic_id'] = $matches[2];
$urls[$url_id]['start'] = '0';
}
$urls[$url_id]['topic_id'] = (int) $urls[$url_id]['topic_id'];
$urls[$url_id]['match1'] = $matches[1];
$urls[$url_id]['match3'] = $matches[3];
if (($data cache_get_data('pretty-topic-'.$urls[$url_id]['topic_id'].$urls[$url_id]['start'].$urls[$url_id]['match1'].$urls[$url_id]['match3'], 240)) != null) {
$urls[$url_id]['replacement'] = unserialize($data);
} else {
$query_data[] = $urls[$url_id]['topic_id'];
}
}
}

// Query the database with these topic IDs
if (count($query_data) != 0)
{
// Look for existing topic URLs
$query_data array_keys(array_flip($query_data));
$topicData = array();
$unpretty_topics = array();

$query $smcFunc['db_query']('''
SELECT t.id_topic, t.id_board, p.pretty_url
FROM {db_prefix}topics AS t
LEFT JOIN {db_prefix}pretty_topic_urls AS p ON (t.id_topic = p.id_topic)
WHERE t.id_topic IN ({array_int:topic_ids})'
,
array('topic_ids' => $query_data)
);

while ($row $smcFunc['db_fetch_assoc']($query)) {
if (isset($row['pretty_url'])) {
$topicData[$row['id_topic']] = array(
'pretty_board' => (isset($context['pretty']['board_urls'][$row['id_board']]) ? $context['pretty']['board_urls'][$row['id_board']] : $row['id_board']),
'pretty_url' => $row['pretty_url'],
);
} else {
$unpretty_topics[] = $row['id_topic'];
}
}

$smcFunc['db_free_result']($query);
$context['pretty']['db_count']++;

// Generate new topic URLs if required
if (count($unpretty_topics) != 0) {
require_once($sourcedir '/Subs-PrettyUrls.php');

// Get the topic subjects
$new_topics = array();
$new_urls = array();
$query_check = array();
$existing_urls = array();
$add_new = array();

$query $smcFunc['db_query']('''
SELECT t.id_topic, t.id_board, m.subject
FROM {db_prefix}topics AS t
INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
WHERE t.id_topic IN ({array_int:topic_ids})'
,
array('topic_ids' => $unpretty_topics)
);

while ($row $smcFunc['db_fetch_assoc']($query))
$new_topics[] = array(
'id_topic' => $row['id_topic'],
'id_board' => $row['id_board'],
'subject' => $row['subject'],
);
$smcFunc['db_free_result']($query);
$context['pretty']['db_count']++;

// Generate URLs for each new topic
foreach ($new_topics as $row)
{
$pretty_text substr(pretty_generate_url($row['subject']), 080);
// A topic in the recycle board doesn't deserve a proper URL
if (($modSettings['recycle_enable'] && $row['id_board'] == $modSettings['recycle_board']) || $pretty_text == '')
// Use 'tID_TOPIC' as a pretty url
$pretty_text 't' $row['id_topic'];
// No duplicates and no numerical URLs - that would just confuse everyone!
if (in_array($pretty_text$new_urls) || is_numeric($pretty_text))
// Add suffix '-ID_TOPIC' to the pretty url
$pretty_text substr($pretty_text070) . '-' $row['id_topic'];
$query_check[] = $pretty_text;
$new_urls[$row['id_topic']] = $pretty_text;
}

// Find any duplicates of existing URLs
$query $smcFunc['db_query']('''
SELECT pretty_url
FROM {db_prefix}pretty_topic_urls
WHERE pretty_url IN ({array_string:new_urls})'
,
array('new_urls' => $query_check)
);
while ($row $smcFunc['db_fetch_assoc']($query)) {
$existing_urls[] = $row['pretty_url'];
}
$smcFunc['db_free_result']($query);
$context['pretty']['db_count']++;

// Finalise the new URLs ...
foreach ($new_topics as $row) {
$pretty_text $new_urls[$row['id_topic']];
// Check if the new URL is already in use
if (in_array($pretty_text$existing_urls))
$pretty_text substr($pretty_text070) . '-' $row['id_topic'];
$add_new[] = array($row['id_topic'], $pretty_text);
// Add to the original array of topic URLs
$topicData[$row['id_topic']] = array(
'pretty_board' => (isset($context['pretty']['board_urls'][$row['id_board']]) ? $context['pretty']['board_urls'][$row['id_board']] : $row['id_board']),
'pretty_url' => $pretty_text,
);
}
// ... and add them to the database!
$smcFunc['db_insert']('',
'{db_prefix}pretty_topic_urls',
array('id_topic' => 'int''pretty_url' => 'string'),
$add_new,
array()
);
$context['pretty']['db_count']++;
}

// Build the replacement URLs
foreach ($urls as $url_id => $url) {
if (isset($url['topic_id']) && isset($topicData[$url['topic_id']])) {
$start $url['start'] != '0' || is_numeric($topicData[$url['topic_id']]['pretty_url']) ? $url['start'] . '/' '';
$urls[$url_id]['replacement'] = $modSettings['pretty_root_url'] . '/' $topicData[$url['topic_id']]['pretty_board'] . '/' $topicData[$url['topic_id']]['pretty_url'] . '/' $start $url['match1'] . $url['match3'];
cache_put_data('pretty-topic-'.$urls[$url_id]['topic_id'].$urls[$url_id]['start'].$urls[$url_id]['match1'].$urls[$url_id]['match3'], serialize($urls[$url_id]['replacement']), 240);
}
}
}
return $urls;
}

// Filter board urls
function pretty_urls_board_filter($urls)
{
global $scripturl$modSettings$context;

$pattern '`' $scripturl '(.*[?;&])board=([.0-9]+)(.*)`S';
foreach ($urls as $url_id => $url)
// Split out the board URLs and replace them
if (!isset($url['replacement']))
if (preg_match($pattern$url['url'], $matches))
{
if (strpos($matches[2], '.') !== false)
list ($board_id$start) = explode('.'$matches[2]);
else
{
$board_id $matches[2];
$start '0';
}
$board_id = (int) $board_id;
$start $start != '0' $start '/' '';
$urls[$url_id]['replacement'] = $modSettings['pretty_root_url'] . '/' . (isset($context['pretty']['board_urls'][$board_id]) ? $context['pretty']['board_urls'][$board_id] : $board_id) . '/' $start $matches[1] . $matches[3];
}
return $urls;
}

// Filter profiles
function pretty_profiles_filter($urls)
{
global $boardurl$scripturl$smcFunc$context;

$pattern '`' $scripturl '(.*)action=profile;u=([0-9]+)(.*)`S';
$query_data = array();
foreach ($urls as $url_id => $url)
{
// Get the profile data ready to query the database with
if (!isset($url['replacement']))
if (preg_match($pattern$url['url'], $matches))
{
$urls[$url_id]['profile_id'] = (int) $matches[2];
$urls[$url_id]['match1'] = $matches[1];
$urls[$url_id]['match3'] = $matches[3];
$query_data[] = $urls[$url_id]['profile_id'];
}
}

// Query the database with these profile IDs
if (count($query_data) != 0)
{
$query $smcFunc['db_query']('''
SELECT id_member, member_name
FROM {db_prefix}members
WHERE id_member IN ({array_int:member_ids})'
,
array('member_ids' => $query_data));

$memberNames = array();
while ($row $smcFunc['db_fetch_assoc']($query))
$memberNames[$row['id_member']] = rawurlencode($row['member_name']);
$smcFunc['db_free_result']($query);
$context['pretty']['db_count']++;

// Build the replacement URLs
foreach ($urls as $url_id => $url)
if (isset($url['profile_id']))
if (strpos($memberNames[$url['profile_id']], '%2F') !== false)
$urls[$url_id]['replacement'] = $boardurl '/profile/' $url['match1'] . 'user=' $memberNames[$url['profile_id']] . $url['match3'];
else
$urls[$url_id]['replacement'] = $boardurl '/profile/' $memberNames[$url['profile_id']] . '/' $url['match1'] . $url['match3'];
}
return $urls;
}

// Filter Aeva Media URLs
function pretty_aeva_filter($urls)
{
global $boardurl;

$pattern = array(
'~.*[?;&]action=media;sa=media;in=([0-9]+);(thumba?|preview)(.*)~S',
'~.*[?;&]action=media;sa=(album|item|media);in=([0-9]+)(.*)~S',
'~.*[?;&]action=media(.*)~S',
);
$replacement = array(
$boardurl '/media/$2/$1/?$3',
$boardurl '/media/$1/$2/?$3',
$boardurl '/media/?$1',
);
foreach ($urls as $url_id => $url)
if (!isset($url['replacement']) && strpos($url['url'], 'action=media') !== false)
$urls[$url_id]['replacement'] = preg_replace($pattern$replacement$url['url']);
return $urls;
}

?>


As you can see my attempt was to make the cache smaller by filtering out stuff I know didn't need to be processed.

Line 19 & 62, implemented support for Open Graph standard.
Line 30 no ? mark in URL means no processing needed.
Line 32, If the base URL is not that of the site, then it is external and needs no processing, also if it leads to any of these well known folders & unique folders of mine then no processing.
Line 34 - 38 & 57, commented out, old full site URL cache system I was using.
Line 173 - 177, new topic only cache system query I am now using.
Line 296, new topic only cache system save.
Line 1 - 395, maybe some stuff in there I forgot I did,  ::)

vbgamer45

Thanks nend testing out the changes on my sites now.
Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

aquagrrl

I am having problems with pretty urls - the home page of my forums just stopped working (white screen of death) and I eventually got it fixed by turning off pretty URLs. I uninstalled it, updated to the most recent version (I had 1.1.2 and upgraded to 1.1.3). Still no dice. I moved it to a new host to test, convinced it was a problem with the host overselling. Nope, it didn't work there either.

PHP error log shows something, but I don't know what it means or how to fix:
[12-Mar-2016 17:32:41 US/Central] PHP Fatal error:  ob_start(): Cannot use output buffering in output buffering display handlers in /home/terminus/public_html/seahorsetalk/Sources/Subs.php on line 2900


Subs.php line 2900:
ob_start('ob_sessrewrite');

But I'm stuck here. This appears to be a core SMF piece. Any thoughts on what to do to fix this would be greatly appreciated. I have all my URLs broken at the moment.

vbgamer45

Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

aquagrrl

The consensus of those two threads seems to be it's a problem with the host. It could be. But had duplicated the forum to two different servers on two different hosts. They could both be broken, but it seems unlikely. Not impossible, but it does seem to suggest to me that it it's a consistent issue.

Commenting out ob_start('ob_sessrewrite'); fixes the problem with pretty url, but I don't think I'm supposed to do that. :/

Jade Elizabeth

Quote from: aquagrrl on March 13, 2016, 12:07:58 AM
The consensus of those two threads seems to be it's a problem with the host. It could be. But had duplicated the forum to two different servers on two different hosts. They could both be broken, but it seems unlikely. Not impossible, but it does seem to suggest to me that it it's a consistent issue.

Commenting out ob_start('ob_sessrewrite'); fixes the problem with pretty url, but I don't think I'm supposed to do that. :/

Ask your host if there's any reason why it's not working...hopefully they will fix it :).
Once proud Documentation Writer and Help Squad Leader | Check out my new adult coloring career: Color With Jade/Patreon.

Xpresskonami

hello. please is there anyway I can stop all These characters " {", " }
", " |", " \", " ^", " ~", " [", " ]", and " `". in my url link.

for example this link

http://blogurl/forum/i-reply-you-'oh-what-a-child!-(see-response-hehe)'/

want to change it to this


http://blogurl/forum/i-reply-you-oh-what-a-child-see-response-hehe/

Xpresskonami


vbgamer45

You would have to edit the code. I don't know where exactly without looking
Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

Xpresskonami

where can I find the code in the script ????

anikpand

Hello Guys

I am getting 404 not found Error with Pretty URL mod , i have set Permission on htacess  file even though its not working

should i keep any input in Skip Actions List , Please help me to fix this or suggest any other way to do it.

vbgamer45

Are you running on a windows server if so you need ISAPI Rewrite
Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

anikpand

yes windows server where i can find , what are the steps please guide me

vbgamer45

http://www.isapirewrite.com/ for IIS 5 and 6


For IIS 7 I am not sure you will have to research .htaccess
Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

vbgamer45

Community Suite for SMF - Take your forum to the next level built for SMF, Gallery,Store,Classifieds,Downloads,more!

SMFHacks.com -  Paid Modifications for SMF

Mods:
EzPortal - Portal System for SMF
SMF Gallery Pro
SMF Store SMF Classifieds Ad Seller Pro

anikpand

Buddy i just need how can i do it its extension will be exe  , Do i need to put any thing on my Shared space  or any thing else , sorry for bothering you , Please help me

Advertisement: