function prepareContent($content) { if (!$content) { return ''; } $dom = new domDocument(); $dom->loadHTML('<?xml encoding="UTF-8">' . $content); $images = $dom->getElementsByTagName('img'); foreach ($images as $image) { $src = $image->getAttribute('src'); $image->setAttribute('src', site_url($src)); } return $dom->saveHTML(); }
function noticeInfos($notice_id, $enrich_params) { global $lang; if ($enrich_params['label'] != "") { $titre = $enrich_params['label']; } else { $rqt = "select tit1 from notices where notice_id='{$notice_id}'"; $res = pmb_mysql_query($rqt); if (pmb_mysql_num_rows($res)) { $titre = pmb_mysql_result($res, 0, 0); } } $curl = new Curl(); //on fait un premier appel pour regarder si on a quelque chose chez Wikipédia... $url = "http://" . substr($lang, 0, 2) . ".wikipedia.org/w/api.php?format=json&action=opensearch&search=" . rawurlencode($titre) . "&limit=20"; $json = $curl->get($url); $search = json_decode($json); if (count($search[1]) == 1 || $enrich_params['label'] != "") { if ($enrich_params['label']) { $title = $enrich_params['label']; } else { $title = $search[1][0]; } $url = "http://" . substr($lang, 0, 2) . ".wikipedia.org/w/api.php?format=json&action=query&titles=" . rawurlencode($title) . "&prop=revisions&rvprop=content&rvparse=1"; $json = $curl->get($url); $response = json_decode($json); $html_to_return = ""; foreach ($response->query->pages as $page) { foreach ($page->revisions[0] as $rev) { $html_to_return .= utf8_decode($rev); } } $html_to_return = str_replace("href=\"/", "target='_blank' href=\"http://" . substr($lang, 0, 2) . ".wikipedia.org/", $html_to_return); @ini_set("zend.ze1_compatibility_mode", "0"); $dom = new domDocument(); $dom->loadHTML($html_to_return); $spans = $dom->getElementsByTagName("span"); for ($i = 0; $i < $spans->length; $i++) { for ($j = 0; $j < $spans->item($i)->attributes->length; $j++) { if ($spans->item($i)->attributes->item($j)->name == "class" && $spans->item($i)->attributes->item($j)->nodeValue == "editsection") { $spans->item($i)->parentNode->removeChild($spans->item($i)); } } } $html_to_return = $dom->saveHTML(); @ini_set("zend.ze1_compatibility_mode", "1"); } else { if (count($search[1]) > 1) { //si plus d'un résultat on propose le choix... $html_to_return = "\n\t\t\t<div id='wiki_bio_" . $notice_id . "'>\n\t\t\t\t<table>"; for ($i = 0; $i < count($search[1]); $i++) { if ($i % 4 == 0) { $html_to_return .= "\n\t\t\t\t\t<tr>"; } $html_to_return .= "\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<a href='#' onclick='load_wiki(\"" . $notice_id . "\",\"wiki\",\"" . htmlentities(utf8_decode($search[1][$i]), ENT_QUOTES, $charset) . "\");return false;' >" . utf8_decode($search[1][$i]) . "</a>\n\t\t\t\t\t\t</td>"; if ($i % 4 == 3) { $html_to_return .= "\n\t\t\t\t\t</tr>"; } } $html_to_return .= "\n\t\t\t\t</table>\n\t\t\t</div>"; } else { $html_to_return = $this->msg['wikipedia_no_informations']; } } return $html_to_return; }
function wikiUpdate($specimen) { global $connection; // Get the wikipedia page $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "http://en.wikipedia.org/w/api.php"); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, 'action=parse&prop=text&page=' . $specimen . '&format=json'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); // Parse the json file and get the html code $o = json_decode($output); $html = $o->parse->text->{'*'}; $dom = new domDocument(); libxml_use_internal_errors(true); $dom->loadHTML('<?xml encoding="utf-8" ?>' . $html); // This ensures that loadHTML interprets the string as utf-8 and not iso-8859-1 libxml_use_internal_errors(false); $ps = $dom->getElementsByTagName('p'); // Extract the initial text (at least 700 characters) $wiki = array(); $strlen = 0; $i = 0; do { $x = $ps->item($i); // delete links, sups and spans $delist = array(); $links = $x->getElementsByTagName('a'); foreach ($links as $link) { $txt = new domText($link->nodeValue); $link->parentNode->insertBefore($txt, $link); $delist[] = $link; } $links = $x->getElementsByTagName('sup'); foreach ($links as $link) { $delist[] = $link; } $links = $x->getElementsByTagName('span'); foreach ($links as $link) { $delist[] = $link; } foreach ($delist as $del) { $del->parentNode->removeChild($del); } if (strlen($x->nodeValue)) { $wiki[] = $x; $strlen += strlen($x->nodeValue); } $i++; } while ($strlen < 2000); $str = ""; foreach ($wiki as $w) { $str .= $dom->saveHTML($w); } date_default_timezone_set('Europe/Paris'); $date = new DateTime(); $domx = new DOMXPath($dom); $binomial = $domx->query("//span[@class='binomial']/i")->item(0)->nodeValue; $info = array('description' => array('description' => $str . '<a href="https://en.wikipedia.org/wiki/' . $specimen . '">More on Wikipedia</a>', 'acknowledgements' => '', 'commonName' => $specimen, 'lastUpdated' => "last updated: " . $date->format('d F Y'), 'scientificName' => $binomial), 'url' => '/data/' . $specimen . '/', 'mesh' => 'mesh.ply', 'mri' => array('atlas' => array(array('name' => 'Telencephalon', 'description' => 'Telencephalon', 'filename' => 'Telencephalon.nii.gz')), 'brain' => 'MRI-n4.nii.gz', 'dim' => array(200, 280, 160)), 'name' => $specimen, 'picture' => array('file' => 'picture.jpg', 'width' => 200, 'height' => 200, 'name' => $specimen . ' (' . $binomial . ')')); header('Content-type: text/html; charset=UTF-8'); print "<html><body><xmp style='white-space:pre-wrap'>"; print json_encode($info, JSON_PRETTY_PRINT); print "</xmp></body></html>"; //$str = iconv("UTF-8", "ISO-8859-1//IGNORE", $str); //header('Content-type: text/html; charset=ISO-8859-1'); //echo "<META http-equiv='Content-Type' content='text/html; charset=UTF-8'>"; //echo "<META http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>"; //echo htmlspecialchars_decode($str, ENT_QUOTES); //echo mb_convert_encoding($str,"HTML-ENTITIES","UTF-8"); //echo html_entity_decode($str); // Get the info.txt file corresponding to the $specimen /* $info=json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT']."/data/".$specimen."/info.txt")); $info->description->description=$str; date_default_timezone_set('Europe/Paris'); $date=new DateTime(); $info->description->lastUpdated="last updated: ".$date->format('d F Y'); //file_put_contents($_SERVER['DOCUMENT_ROOT']."/data/".$specimen."/info.txt",json_encode($info,JSON_PRETTY_PRINT)); echo "Description updated for ".$specimen."<br>"; print json_encode($info,JSON_PRETTY_PRINT); */ }
function noticeInfos($notice_id) { global $lang; $rqt = "select tit1 from notices where notice_id='{$notice_id}'"; $res = mysql_query($rqt); if (mysql_num_rows($res)) { $titre = mysql_result($res, 0, 0); $curl = new Curl(); //on fait un premier appel pour regarder si on a quelque chose chez Wikipédia... $url = "http://" . substr($lang, 0, 2) . ".wikipedia.org/w/api.php?format=json&action=opensearch&search=" . rawurlencode($titre); $json = $curl->get($url); $search = json_decode($json); if (count($search[1]) > 0) { $url = "http://" . substr($lang, 0, 2) . ".wikipedia.org/w/api.php?format=json&action=query&titles=" . rawurlencode($search[1][0]) . "&prop=revisions&rvprop=content&rvparse=1"; $json = $curl->get($url); $response = json_decode($json); $html_to_return = ""; foreach ($response->query->pages as $page) { foreach ($page->revisions[0] as $rev) { $html_to_return .= utf8_decode($rev); } } $html_to_return = str_replace("href=\"/", "target='_blank' href=\"http://" . substr($lang, 0, 2) . ".wikipedia.org/", $html_to_return); @ini_set("zend.ze1_compatibility_mode", "0"); $dom = new domDocument(); $dom->loadHTML($html_to_return); $spans = $dom->getElementsByTagName("span"); for ($i = 0; $i < $spans->length; $i++) { for ($j = 0; $j < $spans->item($i)->attributes->length; $j++) { if ($spans->item($i)->attributes->item($j)->name == "class" && $spans->item($i)->attributes->item($j)->nodeValue == "editsection") { $spans->item($i)->parentNode->removeChild($spans->item($i)); } } } $html_to_return = $dom->saveHTML(); @ini_set("zend.ze1_compatibility_mode", "1"); } else { $html_to_return = $this->msg['wikipedia_no_informations']; } } return $html_to_return; }
public static function remove($subscriber, $subscriberId, $cle = '') { $db = JFactory::getDBO(); $listUnsubA = array(); //unsubscribe listIds $allAvailableListsA = JRequest::getVar('sub_list_id', ''); $unsubListValA = JRequest::getVar('unsubscribed', ''); $textarea_msg = JRequest::getVar('textareamess', ' ', 'post'); foreach ($allAvailableListsA as $key => $unsublist) { if (!empty($unsubListValA[$key]) == 1) { $listidUnsubA[] = $unsublist; } } if (!empty($subscriberId) and !empty($cle)) { if (md5($subscriber->email) == $cle) { if (!empty($listidUnsubA)) { $query = 'UPDATE `#__jnews_listssubscribers` SET '; $query .= ' `unsubdate`=' . time(); $query .= ' ,`unsubscribe`=1'; $query .= ' WHERE `subscriber_id`= ' . $subscriberId; $query .= ' AND `list_id` IN (' . implode(',', $listidUnsubA) . ')'; $db->setQuery($query); $result = $db->query(); $query = 'SELECT * FROM `#__jnews_lists` WHERE `id` IN (' . implode(',', $listidUnsubA) . ')'; $db->setQuery($query); $listsO = $db->loadObjectList(); } //check if we have subscription to any auto-responder $query = 'SELECT `id` FROM `#__jnews_lists` '; $query .= ' WHERE `list_type`= 2 '; $query .= ' AND `id` IN (' . implode(',', $listidUnsubA) . ')'; $db->setQuery($query); $loadResultArray = $db->loadObjectList(); $autoRespondListA = jnews::convertObjectList2Array($loadResultArray); if (!empty($autoRespondListA)) { $query = 'DELETE FROM `#__jnews_queue` '; $query .= ' WHERE `subscriber_id`= ' . $subscriberId; $query .= ' AND `mailing_id` IN ( SELECT `mailing_id` FROM `#__jnews_listmailings` WHERE `list_id` IN (' . implode(',', $autoRespondListA) . ') )'; $db->setQuery($query); $db->query(); } foreach ($listsO as $key => $list) { //we send the unsubscription notification to the subscriber if it is turn to yes if ($list->unsubscribesend == 1) { jNews_ProcessMail::sendUnsubcribeEmail($subscriber, $subscriberId, $list); } //we send the unsubscription notification to the list owner if it is turn to yes if ($GLOBALS[JNEWS . 'level'] > 2 && $list->unsubscribenotifyadmin == 1 && !empty($list->notifyadminmsg) && !empty($list->owner)) { $my = JFactory::getUser($list->owner); if ($list->notifyadminmsg != "") { $dom = new domDocument(); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; if ($dom->loadHTML("<html><body>" . $list->notifyadminmsg . "</body></html>")) { $xpath = new DOMXpath($dom); $elements = $xpath->query("/html/descendant::*[contains(text(),'LISTNAME')]/.."); if (!is_null($elements)) { $feedback = _JNEWS_UNSUBSCRIBE_MESSAGE_TEXTAREA_TITLE; foreach ($elements as $element) { $item = $dom->createElement("span", " " . $feedback); $br = $dom->createElement('br'); $item->insertBefore($br); $titlespace = $dom->createElement("span", " " . $textarea_msg); $item->appendChild($titlespace); if ($element->nextSibling != null) { $appen = $element->nextSibling; } else { $appen = $element; } if ($element->parentNode != null) { $inss = $element->parentNode; } else { $inss = $element; } $inss->insertBefore($item, $appen); } $dom->formatOutput = true; $lisnotifyadminmsg = $dom->saveHTML(); } $res_search = preg_match("/(?:<body[^>]*>)(.*)<\\/body>/isU", $lisnotifyadminmsg, $matches); if ($res_search > 0 && isset($matches[1]) && $matches[1] !== "") { $list->notifyadminmsg = $matches[1]; } } } } jNews_ProcessMail::sendNotification($list->notifyadminmsg, $subscriber, $my, $list, JNEWS_SITE_NAME . ' ' . _JNEWS_UNSUBS_NOTIFYSUBJECT); } if (!empty($GLOBALS[JNEWS . 'unsubscribe_notification'])) { $listOfAdminA = explode(',', $GLOBALS[JNEWS . 'unsubscribe_notification']); if (!empty($listOfAdminA)) { foreach ($listOfAdminA as $oneAdmin) { if (empty($oneAdmin)) { continue; } $owner = new stdClass(); $owner->name = $oneAdmin; $owner->email = $oneAdmin; jNews_ProcessMail::sendNotification(_JNEWS_UNSUBSCRIBE_ADMIN_NOTIFICATION, $newSubscriber, $owner, $list, JNEWS_SITE_NAME . ' ' . _JNEWS_UNSUBS_NOTIFYSUBJECT); } } } } } return $result; }
/** * Создать кэш страницы * * @param string название кэша * @param string ссылка на страницу сайта, которую надо закешировать */ public function create($name, $url) { if(!preg_match("/^[0-9a-z-_]+$/i",$name)) { $this->log("ERROR: ".$this->message(1), $name); return false; } // проверим название if(!preg_match("|^([^/]*(//)*[^/]+)|i",$url, $match)) { $this->log("ERROR: ".$this->message(2), $url); return false; } // проверим домен $this->domen = $match[2]; $this->name = $name; $this->url = $url; $this->resource = array(); # 0. Проверяем есть ли уже кэш $f = glob(getenv("DOCUMENT_ROOT").$this->path.$this->name.'.*',GLOB_NOSORT); if(count($f)) { $this->log("ERROR: ".$this->message(0), $this->path.basename($f[0])); return false; } # 1. Получить страницу list($header, $body) = $this->connect($url); // Если тело пустое if(empty($body)) return false; # 2. Определяем кодировку страницы и тип файла foreach($header as $v) { // Тип файла if(!preg_match("/^Content-type: ([^;]+)/i", $v, $match)) continue; $ext = $this->getExt($match[1], $url); // Разновидность типа (text, image) $type = explode('/',$match[1]); switch($type[0]) { case 'text': // папка создается только для определенного типа файлов if(in_array($ext,array('html','shtml','htm','xml','css'))) { // создаем папку для дополнительных ресурсов if(!is_dir(getenv("DOCUMENT_ROOT").$this->path.$this->name)) mkdir(getenv("DOCUMENT_ROOT").$this->path.$this->name); } // Кодировка страницы if(preg_match("/^Content-type: [^;]+; charset=([a-z0-9-]+)/i", $v, $match)) $charset = $match[1]; break; case 'image': case 'application': default: file_put_contents(getenv("DOCUMENT_ROOT").$this->path.$this->name.'.'.$ext, $body); return true; break; } break; } // Не определен тип файла if(!$ext) { $this->log( "Error: undefined extension", $url ); return false; } // Не определена кодировка if(!$charset) { if(!($charset = mb_detect_encoding($body, array('UTF-8', 'Windows-1251')))) { $this->log( "Error: undefined charset", $url ); return false; } } // Если кодировка не UTF-8, перекодируем контент if($charset != 'UTF-8') { $temp_body = iconv($charset,'UTF-8//TRANSLIT',$body); if($temp_body) $body = $temp_body; else $body = iconv('Windows-1251','UTF-8//TRANSLIT',$body); $body = preg_replace_callback("/<meta([^>]+)>/mi", array($this, 'changeCharset'), $body); // меняем кодировку в документе, чтобы правильно отработал domDocument } // создаем новый dom-объект $dom = new domDocument; // загружаем html в объект @$dom->loadHTML($body); # 3. Узнаем полный базовый адрес документа $base = $dom->documentElement->getElementsByTagName('base'); foreach ($base as $val) { // Модифицируем путь до файлов $this->domen = $val->getAttribute('href'); // Удаляем последний слэш, по ресурсам это выгодней, такие пути чаще встречаются /img/n.gif $this->domen = preg_replace("|/$|", '', $this->domen); // Удаляем base if($this->quality == 'low') $this->deleteNode($val); } # 4. Ссылки (Модифицируем, чтобы относительные адреса не ссылались на кэш) if($this->quality == 'low') { $a = $dom->getElementsByTagName('a'); foreach ($a as $i=>$val) { if(!$val->getAttribute('href')) continue; if(!preg_match("|^/|i",$val->getAttribute('href'))) continue; // если начинается со слэша $val->setAttribute('href',$this->domen.$val->getAttribute('href')); } } # 4. Изображения $img = $dom->getElementsByTagName('img'); foreach ($img as $i=>$val) { $this->lastTag = 'img #'.$i; if($val->getAttribute('src')) $val->setAttribute('src',$this->getSource($val->getAttribute('src'))); # обычное изображение if($val->getAttribute('data-thumb')) $val->setAttribute('src',$this->getSource($val->getAttribute('data-thumb'))); # youtube.com } # 5. Стили, фавиконка $link = $dom->getElementsByTagName('link'); foreach ($link as $i=>$val) { if(!$val->getAttribute('href')) continue; $this->lastTag = 'link #'.$i; if(in_array($val->getAttribute('rel'), array('shortcut icon','stylesheet'))) $val->setAttribute('href',$this->getSource($val->getAttribute('href'))); } # 7. Объект $object = $dom->getElementsByTagName('object'); foreach ($object as $i=>$val) { $this->lastTag = 'object #'.$i; if($val->getAttribute('data')) $val->setAttribute('data',$this->getSource($val->getAttribute('data'))); } # 7. Апплеты $applet = $dom->getElementsByTagName('applet'); foreach ($applet as $i=>$val) { $this->lastTag = 'applet #'.$i; if($val->getAttribute('code')) $val->setAttribute('code',$this->getSource($val->getAttribute('code'))); } # 7. Видео $video = $dom->getElementsByTagName('video'); foreach ($video as $i=>$val) { $this->lastTag = 'video #'.$i; if($val->getAttribute('poster')) $val->setAttribute('poster',$this->getSource($val->getAttribute('poster'))); if($val->getAttribute('src')) $val->setAttribute('src',$this->getSource($val->getAttribute('src'))); } # 7. Видео $param = $dom->getElementsByTagName('param'); foreach ($param as $i=>$val) { if(!in_array($val->getAttribute('name'),array('movie','base'))) continue; if(!$val->getAttribute('value')) continue; $this->lastTag = 'param #'.$i; $val->setAttribute('value',$this->getSource($val->getAttribute('value'))); } // список тегов из которых надо получить ресурсы $tags = array('audio', 'embed', 'source', 'frame', 'script', 'iframe'); foreach($tags as $v) { $t = $dom->getElementsByTagName($v); foreach ($t as $i=>$val) { if(!$val->getAttribute('src')) continue; $this->lastTag = $v.' #'.$i; $val->setAttribute('src',$this->getSource($val->getAttribute('src'))); } } # 7. Согласно качеству преобразуем объект в строку switch($this->quality) { case 'high': $body = preg_replace("/<base[^>]+>/mi",'',$body); // удаляем base break; case 'low': $body = $dom->saveHTML(); break; } // Получаем ресурсы из css $body = $this->getSourceFromCSS($body,$url); if($this->quality == 'high') { // заменяем все ресурсы foreach($this->resource as $val) { $body = str_replace(array("'".$val['true-path']."'","\"".$val['true-path']."\""),'"'.$val['new-name'].'"',$body); } // Меняем относительные ссылки на постоянные, чтобы они вели не на мой сайт $body = preg_replace_callback("|(<a[^>]+)|mi", array($this, 'changeHREF'), $body); // Обрабатываем conditional comments $body = preg_replace_callback("/<!--\[if\s(?:[^<]+|<(?!!\[endif\]-->))*<!\[endif\]-->/mi", array($this, 'conditionalComments'), $body); } # 10. Сохраняем страницу file_put_contents(getenv("DOCUMENT_ROOT").$this->path.$this->name.'.'.$ext, $body); return true; }
/** * * @get text between tags * @param string $tag The tag name * @param string $html The XML or XHTML string * @param int $strict Whether to use strict mode * @param string $encoding * @return array */ private function getTextBetweenTags($tag, $html, $strict = 0, $encoding = "UTF-8") { global $PAGE, $CFG; if (!isset($CFG->filter_jsxgraph_divid)) { set_config('filter_jsxgraph_divid', 'box'); } if (!isset($CFG->filter_jsxgraph_boardvar)) { set_config('filter_jsxgraph_boardvar', 'board'); } if (!isset($CFG->filter_jsxgraph_width)) { set_config('filter_jsxgraph_width', '500'); } if (!isset($CFG->filter_jsxgraph_height)) { set_config('filter_jsxgraph_height', '400'); } // a new dom object $dom = new domDocument(); $dom->formatOutput = true; // load the html into the object if ($strict == 1) { $dom->loadXML($html); } else { libxml_use_internal_errors(true); $htmlutf8 = mb_convert_encoding($html, 'HTML-ENTITIES', $encoding); $dom->loadHTML($htmlutf8); libxml_use_internal_errors(false); } // discard white space $dom->preserveWhiteSpace = false; $dom->strictErrorChecking = false; $dom->recover = true; // the tag by its tag name $content = $dom->getElementsByTagname($tag); if (count($content) > 0) { $PAGE->requires->js(new moodle_url($CFG->wwwroot . '/filter/jsxgraph/jsxgraphcore.js')); } // Iterate backwards through the jsxgraph tags $i = $content->length - 1; while ($i > -1) { $item = $content->item($i); // Read attributes $w = $item->getAttribute('width'); if ($w == "") { $w = $CFG->filter_jsxgraph_width; } $h = $item->getAttribute('height'); if ($h == "") { $h = $CFG->filter_jsxgraph_height; } $b = $item->getAttribute('box'); if ($b == "") { $b = $CFG->filter_jsxgraph_divid . $i; } $brd = $item->getAttribute('board'); if ($brd == "") { $brd = $CFG->filter_jsxgraph_boardvar . $i; } /* Create new div element containing JSXGraph */ $out = $dom->createElement('div'); $a = $dom->createAttribute('id'); $a->value = $b; $out->appendChild($a); $a = $dom->createAttribute('class'); $a->value = "jxgbox"; $out->appendChild($a); $a = $dom->createAttribute('style'); $a->value = "width:" . $w . "px; height:" . $h . "px; "; $out->appendChild($a); $t = $dom->createTextNode(""); $out->appendChild($t); $out = $dom->appendChild($out); // Replace <jsxgraph> by <div> $item->parentNode->replaceChild($out, $item); $code = ""; $needGXT = false; $url = $item->getAttribute('file'); if ($url != "") { $code = "var " . $brd . " = JXG.JSXGraph.loadBoardFromFile('" . $b . "', '" . $url . "', 'Geonext');"; $needGXT = true; } else { $url = $item->getAttribute('filestring'); if ($url != "") { $code = "var " . $brd . " = JXG.JSXGraph.loadBoardFromString('" . $b . "', '" . $url . "', 'Geonext');"; $needGXT = true; } else { // Plain JavaScript code $code = $item->nodeValue; } } // Place JavaScript code at the end of the page. $PAGE->requires->js_init_call($code); if ($needGXT) { $PAGE->requires->js(new moodle_url($CFG->wwwroot . '/filter/jsxgraph/GeonextReader.js')); } --$i; } // remove DOCTYPE $dom->removeChild($dom->firstChild); // remove <html><body></body></html> //$dom->replaceChild($dom->firstChild->firstChild->firstChild, $dom->firstChild); //return $dom->saveXML(); $str = $dom->saveHTML(); $str = str_replace("<body>", "", $str); $str = str_replace("</body>", "", $str); $str = str_replace("<html>", "", $str); $str = str_replace("</html>", "", $str); return $str; }