aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authormarijus <mario@localhost.localdomain>2014-02-05 14:48:42 +0100
committermarijus <mario@localhost.localdomain>2014-02-05 14:48:42 +0100
commit419e3b5024efec40c98e48c3bf213c4e60d39fae (patch)
treed3754aa1d251308eb6178fe4ab138463ceaaf135 /include
parentd7d2fff24b05bcb3ff3acc215e99f8f7d33d058d (diff)
parent0844110f7b154a0fb5102362fe732c2b091222d7 (diff)
downloadvolse-hubzilla-419e3b5024efec40c98e48c3bf213c4e60d39fae.tar.gz
volse-hubzilla-419e3b5024efec40c98e48c3bf213c4e60d39fae.tar.bz2
volse-hubzilla-419e3b5024efec40c98e48c3bf213c4e60d39fae.zip
Merge branch 'master' of https://github.com/friendica/red into upstream
Diffstat (limited to 'include')
-rw-r--r--include/ItemObject.php10
-rw-r--r--include/attach.php1
-rw-r--r--include/bookmarks.php55
-rw-r--r--include/chat.php8
-rw-r--r--include/config.php8
-rw-r--r--include/conversation.php8
-rwxr-xr-xinclude/items.php29
-rw-r--r--include/menu.php39
-rw-r--r--include/permissions.php3
-rw-r--r--include/spam.php35
-rwxr-xr-xinclude/text.php76
11 files changed, 194 insertions, 78 deletions
diff --git a/include/ItemObject.php b/include/ItemObject.php
index e9a0b65c0..9b1a6fbcd 100644
--- a/include/ItemObject.php
+++ b/include/ItemObject.php
@@ -171,6 +171,15 @@ class Item extends BaseObject {
);
}
+ $has_bookmarks = false;
+ if(is_array($item['term'])) {
+ foreach($item['term'] as $t) {
+ if($t['type'] == TERM_BOOKMARK)
+ $has_bookmarks = true;
+ }
+ }
+
+
if($this->is_commentable()) {
$like = array( t("I like this \x28toggle\x29"), t("like"));
$dislike = array( t("I don't like this \x28toggle\x29"), t("dislike"));
@@ -237,6 +246,7 @@ class Item extends BaseObject {
'star' => ((feature_enabled($conv->get_profile_owner(),'star_posts')) ? $star : ''),
'tagger' => ((feature_enabled($conv->get_profile_owner(),'commtag')) ? $tagger : ''),
'filer' => ((feature_enabled($conv->get_profile_owner(),'filing')) ? $filer : ''),
+ 'bookmark' => (($conv->get_profile_owner() == local_user() && $has_bookmarks) ? t('Bookmark Links') : ''),
'drop' => $drop,
'multidrop' => ((feature_enabled($conv->get_profile_owner(),'multi_delete')) ? $multidrop : ''),
// end toolbar buttons
diff --git a/include/attach.php b/include/attach.php
index dbc489a2d..af1159957 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -26,6 +26,7 @@ function z_mime_content_type($filename) {
'xml' => 'application/xml',
'swf' => 'application/x-shockwave-flash',
'flv' => 'video/x-flv',
+ 'epub' => 'application/epub+zip',
// images
'png' => 'image/png',
diff --git a/include/bookmarks.php b/include/bookmarks.php
new file mode 100644
index 000000000..99cb60e64
--- /dev/null
+++ b/include/bookmarks.php
@@ -0,0 +1,55 @@
+<?php /** @file */
+
+require_once('include/menu.php');
+
+function bookmark_add($channel,$sender,$taxonomy,$private) {
+
+ $iarr = array();
+ $channel_id = $channel['channel_id'];
+
+ if($private)
+ $iarr['contact_allow'] = array($channel['channel_hash']);
+ $iarr['mitem_link'] = $taxonomy['url'];
+ $iarr['mitem_desc'] = $taxonomy['term'];
+ $iarr['mitem_flags'] = 0;
+
+ $m = @parse_url($taxonomy['url']);
+ $zrl = false;
+ if($m['host']) {
+ $r = q("select hubloc_url from hubloc where hubloc_host = '%s' limit 1",
+ dbesc($m['host'])
+ );
+ if($r)
+ $zrl = true;
+ }
+
+ if($zrl)
+ $iarr['mitem_flags'] |= MENU_ITEM_ZID;
+
+ $arr = array();
+ $arr['menu_name'] = substr($sender['xchan_hash'],0,16) . ' ' . $sender['xchan_name'];
+ $arr['menu_desc'] = sprintf( t('%1$s\'s bookmarks'), $sender['xchan_name']);
+ $arr['menu_flags'] = (($sender['xchan_hash'] === $channel['channel_hash']) ? MENU_BOOKMARK : MENU_SYSTEM|MENU_BOOKMARK);
+ $arr['menu_channel_id'] = $channel_id;
+
+ $x = menu_list($arr['menu_channel_id'],$arr['menu_name'],$arr['menu_flags']);
+ if($x)
+ $menu_id = $x[0]['menu_id'];
+ else
+ $menu_id = menu_create($arr);
+ if(! $menu_id) {
+ logger('bookmark_add: unable to create menu ' . $arr['menu_name']);
+ return;
+ }
+ logger('add_bookmark: menu_id ' . $menu_id);
+ $r = q("select * from menu_item where mitem_link = '%s' and mitem_menu_id = %d and mitem_channel_id = %d limit 1",
+ dbesc($iarr['mitem_link']),
+ intval($menu_id),
+ intval($channel_id)
+ );
+ if($r)
+ logger('add_bookmark: duplicate menu entry', LOGGER_DEBUG);
+ if(! $r)
+ $r = menu_add_item($menu_id,$channel_id,$iarr);
+ return $r;
+} \ No newline at end of file
diff --git a/include/chat.php b/include/chat.php
index 08fd154b5..5af3a3a9a 100644
--- a/include/chat.php
+++ b/include/chat.php
@@ -122,10 +122,10 @@ function chatroom_enter($observer_xchan,$room_id,$status,$client) {
intval($room_id)
);
if($r) {
- q("update chatpresence set cp_status = %d and cp_last = '%s' where cp_id = %d limit 1",
- dbesc($status),
+ q("update chatpresence set cp_last = '%s' where cp_id = %d and cp_client = '%s' limit 1",
dbesc(datetime_convert()),
- intval($r[0]['cp_id'])
+ intval($r[0]['cp_id']),
+ dbesc($client)
);
return true;
}
@@ -145,6 +145,7 @@ function chatroom_enter($observer_xchan,$room_id,$status,$client) {
function chatroom_leave($observer_xchan,$room_id,$client) {
if(! $room_id || ! $observer_xchan)
return;
+
$r = q("select * from chatpresence where cp_xchan = '%s' and cp_room = %d and cp_client = '%s' limit 1",
dbesc($observer_xchan),
intval($room_id),
@@ -155,6 +156,7 @@ function chatroom_leave($observer_xchan,$room_id,$client) {
intval($r[0]['cp_id'])
);
}
+
return true;
}
diff --git a/include/config.php b/include/config.php
index bccf0737f..8d98d56fa 100644
--- a/include/config.php
+++ b/include/config.php
@@ -65,7 +65,7 @@ function get_config($family, $key) {
if(! array_key_exists($key,$a->config[$family])) {
return false;
}
- return ((preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$family][$key]))
+ return ((! is_array($a->config[$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$family][$key]))
? unserialize($a->config[$family][$key])
: $a->config[$family][$key]
);
@@ -174,8 +174,8 @@ function get_pconfig($uid,$family, $key, $instore = false) {
if((! array_key_exists($family,$a->config[$uid])) || (! array_key_exists($key,$a->config[$uid][$family])))
return false;
-
- return ((preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$uid][$family][$key]))
+
+ return ((! is_array($a->config[$uid][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$uid][$family][$key]))
? unserialize($a->config[$uid][$family][$key])
: $a->config[$uid][$family][$key]
);
@@ -304,7 +304,7 @@ function get_xconfig($xchan,$family, $key) {
if((! array_key_exists($family,$a->config[$xchan])) || (! array_key_exists($key,$a->config[$xchan][$family])))
return false;
- return ((preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$xchan][$family][$key]))
+ return ((! is_array($a->config[$xchan][$family][$key])) && (preg_match('|^a:[0-9]+:{.*}$|s', $a->config[$xchan][$family][$key]))
? unserialize($a->config[$xchan][$family][$key])
: $a->config[$xchan][$family][$key]
);
diff --git a/include/conversation.php b/include/conversation.php
index 316bc1612..633435871 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -1496,6 +1496,14 @@ function profile_tabs($a, $is_owner=False, $nickname=Null){
'title' => t('Events and Calendar'),
'id' => 'events-tab',
);
+
+ $tabs[] = array(
+ 'label' => t('Bookmarks'),
+ 'url' => $a->get_baseurl() . '/bookmarks',
+ 'sel' => ((argv(0) == 'bookmarks') ? 'active' : ''),
+ 'title' => t('Saved Bookmarks'),
+ 'id' => 'bookmarks-tab',
+ );
}
if($is_owner && feature_enabled($a->profile['profile_uid'],'webpages')) {
diff --git a/include/items.php b/include/items.php
index 2fe923303..860d714d1 100755
--- a/include/items.php
+++ b/include/items.php
@@ -822,7 +822,7 @@ function encode_item_xchan($xchan) {
function encode_item_terms($terms) {
$ret = array();
- $allowed_export_terms = array( TERM_UNKNOWN, TERM_HASHTAG, TERM_MENTION, TERM_CATEGORY );
+ $allowed_export_terms = array( TERM_UNKNOWN, TERM_HASHTAG, TERM_MENTION, TERM_CATEGORY, TERM_BOOKMARK );
if($terms) {
foreach($terms as $term) {
@@ -834,7 +834,7 @@ function encode_item_terms($terms) {
}
function termtype($t) {
- $types = array('unknown','hashtag','mention','category','private_category','file','search');
+ $types = array('unknown','hashtag','mention','category','private_category','file','search','thing','bookmark');
return(($types[$t]) ? $types[$t] : 'unknown');
}
@@ -865,6 +865,12 @@ function decode_tags($t) {
case 'search':
$tag['type'] = TERM_SEARCH;
break;
+ case 'thing':
+ $tag['type'] = TERM_THING;
+ break;
+ case 'bookmark':
+ $tag['type'] = TERM_BOOKMARK;
+ break;
default:
case 'unknown':
$tag['type'] = TERM_UNKNOWN;
@@ -2163,6 +2169,21 @@ function tag_deliver($uid,$item_id) {
$item = $i[0];
+
+ $terms = get_terms_oftype($item['term'],TERM_BOOKMARK);
+
+ if($terms && (! $i[0]['item_restrict'])) {
+ logger('tag_deliver: found bookmark');
+ if(perm_is_allowed($u[0]['channel_id'],$i[0]['author_xchan'],'bookmark') && ($i[0]['author_xchan'] != $u[0]['channel_hash'])) {
+ require_once('include/bookmarks.php');
+ require_once('include/Contact.php');
+ $s = channelx_by_hash($i[0]['author_xchan']);
+ foreach($terms as $t) {
+ bookmark_add($u[0],$s[0],$t,$i[0]['item_private']);
+ }
+ }
+ }
+
if(($item['source_xchan']) && ($item['item_flags'] & ITEM_UPLINK) && ($item['item_flags'] & ITEM_THREAD_TOP) && ($item['edited'] != $item['created'])) {
// this is an update to a post which was already processed by us and has a second delivery chain
// Just start the second delivery chain to deliver the updated post
@@ -2466,7 +2487,7 @@ function check_item_source($uid,$item) {
return false;
- $r = q("select * from source where src_channel_id = %d and src_xchan = '%s' limit 1",
+ $r = q("select * from source where src_channel_id = %d and ( src_xchan = '%s' || src_xchan = '*' ) limit 1",
intval($uid),
dbesc(($item['source_xchan']) ? $item['source_xchan'] : $item['owner_xchan'])
);
@@ -2502,7 +2523,7 @@ function check_item_source($uid,$item) {
foreach($words as $word) {
if(substr($word,0,1) === '#' && $tags) {
foreach($tags as $t)
- if($t['type'] == TERM_HASHTAG && substr($t,1) === $word)
+ if(($t['type'] == TERM_HASHTAG) && ((substr($t,1) === substr($word,1)) || (substr($word,1) === '*')))
return true;
}
if(stristr($text,$word) !== false)
diff --git a/include/menu.php b/include/menu.php
index d69c5d0d3..105e4216b 100644
--- a/include/menu.php
+++ b/include/menu.php
@@ -26,11 +26,12 @@ function menu_fetch($name,$uid,$observer_xchan) {
function menu_render($menu) {
if(! $menu)
return '';
+
for($x = 0; $x < count($menu['items']); $x ++)
- if($menu['items']['mitem_flags'] & MENU_ITEM_ZID)
- $menu['items']['mitem_link'] = zid($menu['items']['mitem_link']);
- if($menu['items']['mitem_flags'] & MENU_ITEM_NEWWIN)
- $menu['items']['newwin'] = '1';
+ if($menu['items'][$x]['mitem_flags'] & MENU_ITEM_ZID)
+ $menu['items'][$x]['mitem_link'] = zid($menu['items'][$x]['mitem_link']);
+ if($menu['items'][$x]['mitem_flags'] & MENU_ITEM_NEWWIN)
+ $menu['items'][$x]['newwin'] = '1';
return replace_macros(get_markup_template('usermenu.tpl'),array(
'$menu' => $menu['menu'],
@@ -74,8 +75,7 @@ function menu_create($arr) {
$r = q("select * from menu where menu_name = '%s' and menu_channel_id = %d limit 1",
dbesc($menu_name),
- intval($menu_channel_id),
- intval($menu_flags)
+ intval($menu_channel_id)
);
if($r)
@@ -101,9 +101,17 @@ function menu_create($arr) {
}
-function menu_list($channel_id, $flags = 0) {
+/**
+ * If $flags is present, check that all the bits in $flags are set
+ * so that MENU_SYSTEM|MENU_BOOKMARK will return entries with both
+ * bits set. We will use this to find system generated bookmarks.
+ */
+
+function menu_list($channel_id, $name = '', $flags = 0) {
- $sel_options = (($flags) ? " and ( menu_flags & " . intval($flags) . " ) " : '');
+ $sel_options = '';
+ $sel_options .= (($name) ? " and menu_name = '" . protect_sprintf(dbesc($name)) . "' " : '');
+ $sel_options .= (($flags) ? " and menu_flags = " . intval($flags) . " " : '');
$r = q("select * from menu where menu_channel_id = %d $sel_options order by menu_name",
intval($channel_id)
@@ -152,7 +160,7 @@ function menu_edit($arr) {
return false;
}
- return q("update menu set menu_name = '%s', menu_desc = '%s', menu_flags = %d,
+ return q("update menu set menu_name = '%s', menu_desc = '%s', menu_flags = %d
where menu_id = %d and menu_channel_id = %d limit 1",
dbesc($menu_name),
dbesc($menu_desc),
@@ -204,7 +212,8 @@ function menu_add_item($menu_id, $uid, $arr) {
$channel = get_app()->get_channel();
}
- if ((! $arr['contact_allow'])
+ if (($channel)
+ && (! $arr['contact_allow'])
&& (! $arr['group_allow'])
&& (! $arr['contact_deny'])
&& (! $arr['group_deny'])) {
@@ -223,11 +232,11 @@ function menu_add_item($menu_id, $uid, $arr) {
$str_contact_deny = perms2str($arr['contact_deny']);
}
-
- $allow_cid = perms2str($arr['allow_cid']);
- $allow_gid = perms2str($arr['allow_gid']);
- $deny_cid = perms2str($arr['deny_cid']);
- $deny_gid = perms2str($arr['deny_gid']);
+// unused
+// $allow_cid = perms2str($arr['allow_cid']);
+// $allow_gid = perms2str($arr['allow_gid']);
+// $deny_cid = perms2str($arr['deny_cid']);
+// $deny_gid = perms2str($arr['deny_gid']);
$r = q("insert into menu_item ( mitem_link, mitem_desc, mitem_flags, allow_cid, allow_gid, deny_cid, deny_gid, mitem_channel_id, mitem_menu_id, mitem_order ) values ( '%s', '%s', %d, '%s', '%s', '%s', '%s', %d, %d, %d ) ",
dbesc($mitem_link),
diff --git a/include/permissions.php b/include/permissions.php
index 45ea7c3eb..420591c54 100644
--- a/include/permissions.php
+++ b/include/permissions.php
@@ -24,11 +24,12 @@ function get_perms() {
'post_mail' => array('channel_w_mail', intval(PERMS_W_MAIL), false, t('Can send me private mail messages'), ''),
'post_photos' => array('channel_w_photos', intval(PERMS_W_PHOTOS), false, t('Can post photos to my photo albums'), ''),
'tag_deliver' => array('channel_w_tagwall', intval(PERMS_W_TAGWALL), false, t('Can forward to all my channel contacts via post @mentions'), t('Advanced - useful for creating group forum channels')),
- 'chat' => array('channel_w_chat', intval(PERMS_W_CHAT), false, t('Can chat with me (when available)'), t('Requires compatible chat plugin')),
+ 'chat' => array('channel_w_chat', intval(PERMS_W_CHAT), false, t('Can chat with me (when available)'), t('')),
'write_storage' => array('channel_w_storage', intval(PERMS_W_STORAGE), false, t('Can write to my "public" file storage'), ''),
'write_pages' => array('channel_w_pages', intval(PERMS_W_PAGES), false, t('Can edit my "public" pages'), ''),
'republish' => array('channel_a_republish', intval(PERMS_A_REPUBLISH), false, t('Can source my "public" posts in derived channels'), t('Somewhat advanced - very useful in open communities')),
+ 'bookmark' => array('channel_a_bookmark', intval(PERMS_A_BOOKMARK), false, t('Can send me bookmarks'), 'Bookmarks from this person will automatically be saved'),
'delegate' => array('channel_a_delegate', intval(PERMS_A_DELEGATE), false, t('Can administer my channel resources'), t('Extremely advanced. Leave this alone unless you know what you are doing')),
);
$ret = array('global_permissions' => $global_perms);
diff --git a/include/spam.php b/include/spam.php
new file mode 100644
index 000000000..8b158b7ae
--- /dev/null
+++ b/include/spam.php
@@ -0,0 +1,35 @@
+<?php /** @file */
+
+
+function string_splitter($s) {
+
+ if(! $s)
+ return array();
+
+ $s = preg_replace('/\pP+/','',$s);
+
+ $x = mb_split("\[|\]|\s",$s);
+
+ $ret = array();
+ if($x) {
+ foreach($x as $y) {
+ if(mb_strlen($y) > 2)
+ $ret[] = substr($y,0,64);
+ }
+ }
+ return $ret;
+}
+
+
+
+function get_words($uid,$list) {
+
+ stringify($list,true);
+
+ $r = q("select * from spam where term in ( " . $list . ") and uid = %d",
+ intval($uid)
+ );
+
+ return $r;
+}
+
diff --git a/include/text.php b/include/text.php
index cf68ee121..266d8952b 100755
--- a/include/text.php
+++ b/include/text.php
@@ -442,7 +442,7 @@ function item_message_id() {
$mid = $hash . '@' . get_app()->get_hostname();
- $r = q("SELECT `id` FROM `item` WHERE `mid` = '%s' LIMIT 1",
+ $r = q("SELECT id FROM item WHERE mid = '%s' LIMIT 1",
dbesc($mid));
if(count($r))
$dups = true;
@@ -459,7 +459,7 @@ function photo_new_resource() {
do {
$found = false;
$resource = hash('md5',uniqid(mt_rand(),true));
- $r = q("SELECT `id` FROM `photo` WHERE `resource_id` = '%s' LIMIT 1",
+ $r = q("SELECT id FROM photo WHERE resource_id = '%s' LIMIT 1",
dbesc($resource)
);
if(count($r))
@@ -593,7 +593,7 @@ function get_tags($s) {
if(substr($mtch,-1,1) === '.')
$mtch = substr($mtch,0,-1);
// ignore strictly numeric tags like #1
- if((strpos($mtch,'#') === 0) && ctype_digit(substr($mtch,1)))
+ if((strpos($mtch,'#') === 0) && ( ctype_digit(substr($mtch,1)) || substr($mtch,1,1) === '^'))
continue;
// try not to catch url fragments
if(strpos($s,$mtch) && preg_match('/[a-zA-z0-9\/]/',substr($s,strpos($s,$mtch)-1,1)))
@@ -601,6 +601,18 @@ function get_tags($s) {
$ret[] = $mtch;
}
}
+
+ // bookmarks
+
+ if(preg_match_all('/#\^\[(url|zrl)(.*?)\](.*?)\[\/(url|zrl)\]/',$s,$match,PREG_SET_ORDER)) {
+ foreach($match as $mtch) {
+ $ret[] = $mtch[0];
+ }
+ }
+
+
+ // logger('get_tags: ' . print_r($ret,true));
+
return $ret;
}
@@ -889,8 +901,8 @@ function smilies($s, $sample = false) {
|| (local_user() && intval(get_pconfig(local_user(),'system','no_smilies'))))
return $s;
- $s = preg_replace_callback('{<(pre|code)>(?<target>.*?)</\1>}ism','smile_encode',$s);
- $s = preg_replace_callback('/<[a-z]+ (?<target>.*?)>/ism','smile_encode',$s);
+ $s = preg_replace_callback('{<(pre|code)>.*?</\1>}ism','smile_shield',$s);
+ $s = preg_replace_callback('/<[a-z]+ .*?>/ism','smile_shield',$s);
$texts = array(
'&lt;3',
@@ -981,20 +993,18 @@ function smilies($s, $sample = false) {
$s = str_replace($params['texts'],$params['icons'],$params['string']);
}
- $s = preg_replace_callback(
- '/<!--base64:(.*?)-->/ism',
- function ($m) { return base64url_decode($m[1]); },
- $s
- );
+ $s = preg_replace_callback('/<!--base64:(.*?)-->/ism', 'smile_unshield', $s);
return $s;
}
+function smile_shield($m) {
+ return '<!--base64:' . base64url_encode($m[0]) . '-->';
+}
-function smile_encode($m) {
- $cleartext = $m['target'];
- return str_replace($cleartext,'<!--base64:' . base64url_encode($cleartext) . '-->',$m[0]);
+function smile_unshield($m) {
+ return base64url_decode($m[1]);
}
// expand <3333 to the correct number of hearts
@@ -1518,20 +1528,6 @@ function return_bytes ($size_str) {
}
}
-function generate_user_guid() {
- $found = true;
- do {
- $guid = random_string(16);
- $x = q("SELECT `uid` FROM `user` WHERE `guid` = '%s' LIMIT 1",
- dbesc($guid)
- );
- if(! count($x))
- $found = false;
- } while ($found == true );
- return $guid;
-}
-
-
function base64url_encode($s, $strip_padding = true) {
@@ -1549,23 +1545,6 @@ function base64url_decode($s) {
logger('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true));
return $s;
}
-
-/*
- * // Placeholder for new rev of salmon which strips base64 padding.
- * // PHP base64_decode handles the un-padded input without requiring this step
- * // Uncomment if you find you need it.
- *
- * $l = strlen($s);
- * if(! strpos($s,'=')) {
- * $m = $l % 4;
- * if($m == 2)
- * $s .= '==';
- * if($m == 3)
- * $s .= '=';
- * }
- *
- */
-
return base64_decode(strtr($s,'-_','+/'));
}
@@ -1670,17 +1649,12 @@ function item_post_type($item) {
}
-function normalise_openid($s) {
- return trim(str_replace(array('http://','https://'),array('',''),$s),'/');
-}
-
-
function undo_post_tagging($s) {
$matches = null;
- $cnt = preg_match_all('/([@#])\[zrl=(.*?)\](.*?)\[\/zrl\]/ism',$s,$matches,PREG_SET_ORDER);
+ $cnt = preg_match_all('/([@#])(\!*)\[zrl=(.*?)\](.*?)\[\/zrl\]/ism',$s,$matches,PREG_SET_ORDER);
if($cnt) {
foreach($matches as $mtch) {
- $s = str_replace($mtch[0], $mtch[1] . $mtch[3],$s);
+ $s = str_replace($mtch[0], $mtch[1] . $mtch[2] . str_replace(' ','_',$mtch[4]),$s);
}
}
return $s;