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();
 }
示例#2
0
 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;
 }
示例#3
0
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);
    */
}
示例#4
0
 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;
 }
示例#5
0
文件: frontend.php 项目: naka211/kkvn
 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", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" . $feedback);
                                     $br = $dom->createElement('br');
                                     $item->insertBefore($br);
                                     $titlespace = $dom->createElement("span", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" . $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;
 }
示例#6
0
文件: Cache.php 项目: Hordeer/Cache
	/**
	* Создать кэш страницы
	* 
	* @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;
	}
示例#7
0
 /**
  *
  * @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;
 }