Location: PHPKode > scripts > Bookmarks class > BookmarkUtils.php
<?php
/*
 * This file is part of the Booby project.
 * The booby project is located at the following location:
 * http://www.nauta.be/booby/
 *
 * Booby - Copyright (c) 2003 - 2004 Barry Nauta
 *
 * The Booby project is released under the General Public License
 * More detailes in the file 'gpl.html' or on the following
 * website: http://www.gnu.org and look for licenses
 *
 * Enjoy :-)
 */
require_once ('base/util/StringUtils.php');
require_once ('base/util/ItemUtils.php');
/**
 * Bookmark utilities
 * This file allows import and export from and to opera bookmarks
 *
 * This file is a modified version of the one that can be found in 
 * the bookmark4u project (http://bookmark4u.sourceforge.net/)
 * which I wrote some time ago
 *
 * @author Barry Nauta July 2003
 * @package be.nauta.booby.plugins.bookmarks.util
 * @copyright 
 *
 * Copyright (c) 2003 - 2004 Barry Nauta
 *
 * The Booby project is released under the General Public License
 * More detailes on the following
 * website: <code>http://www.gnu.org</code>
 * and look for licenses
 */
class BookmarkUtils extends ItemUtils
{
	/**
	 * Empty default constructor
	 */
	function BookmarkUtils ()
	{
		parent::ItemUtils();
	}
	/**
	 * import a bookmark file into user's DB
	 * 
	 * @param string userId the identifier for the user
	 * @param string userFile the file that contains the opera bookmarks
	 */
	function importOperaBookmarks ($userId, $userfile, $callback, $parentId) 
	{
		$stringUtils = new StringUtils ();
		
		$bookmarkOperations = $callback; 
		//= new BookmarkOperations ();
	
	  	$name = "NAME=";
	  	$url = "URL=";
	  	$description = "DESCRIPTION=";
	  	$typeIndicator = "Opera Hotlist";
	
		// start at the root
		$top=0;
		$stack = array ();
		$stack[$top++]=$parentId;
	
	  	$fp = fopen($userfile, "r");
		if ($fp == null)
		{
			die ("Failed to open " . $userfile);
		}
	  	// compare the first line. It should indicate that we are
	  	// processing a bookmark file of the Opera browser
	  	$firstLine = fgets($fp, 4096);
	  	if (!$stringUtils->startsWith ($firstLine, $typeIndicator)) 
			die ("Not a valid Opera file");
	  	$processing = false;
	
	  	// process the file
	  	while (!feof($fp)) 
		{
	    	$currentLine = trim (fgets($fp, 4096));
	
	    	// #FOLDER starts a (sub)folder
	    	if ($currentLine == "#FOLDER") 
		{
			$currentBookmark = new Bookmark 
				(null,null,null,null, 
				null,null,null,null, 
				null,null,null,null,null);
			$currentBookmark->isParent=1;	
	      		$processing = true;
	    	}
	    	// #URL starts a bookmark
	    	else if ($currentLine == "#URL") 
		{
			$currentBookmark = new Bookmark 
				(null,null,null,null,
				null,null,null,null, 
				null,null,null,null,null);
			$currentBookmark->isParent=0;	
	      		$processing = true;
	    	}
	    	// - ends a folder
	    	else if ($currentLine == "-") 
		{
			// pop current folder from stack
	      		$parentId = $stack[--$top]; 
	      		$processing = false;
		}
	    	else if ($currentLine == "" && $processing) 
		{
	      	// Ok, we found an empty line, this means that we have 
	      	// either found a folder or bookmark
	      	//
	      	// Attention! We will find an empty line just before a
	      	// folder seperator and just after! Make sure that we
	      	// are not processing the same bookmark twice (this is
	      	// why the boolean 'processing' is used.
	      		if ($currentBookmark->isParent == 1) 
			{
	        		// place the current folder on the stack
	        		$stack [$top++] = $parentId;
				$currentBookmark->parentId=$parentId;
				$parentId=$bookmarkOperations->
					addItem($userId, $currentBookmark);
	      		}
	      		else 
			{
				$currentBookmark->parentId=$parentId;
				$bookmarkOperations->addItem
					($userId, $currentBookmark);
	      		}
	      		$processing = false;
	    	}
	    	// Parse the actual bookmark content. Note that the 'processing'
	    	// boolean is not needed here, but hey.... it cannot hurt
	    	else if ($currentLine != "" && $processing) 
		{
	      		// Parse for the string 'NAME='
	      		if ($stringUtils->startsWith ($currentLine, $name)) 
			{
	        		$currentName= $stringUtils->getProperty ($currentLine, $name);
	        		$currentBookmark->name=$currentName;
	      		}
	      		// Parse for the string 'DESCRIPTION='
	      		else if ($stringUtils->startsWith ($currentLine, $description)) 
			{
	        		$currentDescription = $stringUtils->getProperty 
					($currentLine, $description);
	        		$currentBookmark->description=$currentDescription;
	      		}
	      		// Parse for the string 'URL='
	      		else if ($stringUtils->startsWith ($currentLine, $url)) 
			{
	        		$currentURL = $stringUtils->getProperty ($currentLine, $url);
	        		$currentBookmark->locator=$currentURL;
	      		}
	      		else 
			{
	        		// Ignore the rest.
	      		}
	    	}
	  	}
	  	fclose($fp);
	}
	
	/**
	 * Export users bookmarks (starting from a certain Id)
	 * 
	 * @param string id the identifier for the user
	 * @param integer parent the identifier for the parent id of the bookmarks
	 * (to enable recursive functioncall)
	 */
	function exportOperaBookmarks ($id, $parent, $callback) 
	{
		$bookmarkOperations = $callback; 
	  	$bookmarks = $bookmarkOperations->getChildren ($id, $parent);
	
		$newline="\n";
		$cnt_c = 0;
		$cnt_b = 0;
	  for ($i=0;$i<count($bookmarks); $i++)
	  {
		$currentBookmark = $bookmarks[$i];
	
	    if ($currentBookmark->isParent == '1') { # folder
	      $cnt_c++;
	      echo("#FOLDER$newline");
	      echo("\tNAME=" . $currentBookmark->name . "$newline");
	      echo("\tCREATED=$newline");
	      echo("\tVISITED=0$newline");
	      echo("\tORDER=$cnt_c$newline");
	      echo("\tEXPANDED=YES$newline");
	      echo("\tPERSONALBAR_POS=-1$newline");
	      echo("\tDESCRIPTION=".$currentBookmark->description."$newline");
	      echo("\tSHORT NAME=$newline$newline"); 
	

	      $this->exportOperaBookmarks($id, $currentBookmark->itemId, $callback);
	
	      echo("$newline-$newline");
	    } 
	    else
	    {
	      $cnt_b++;
	      echo("#URL$newline");
	      echo("\tNAME=" . $currentBookmark->name . "$newline");
	      echo("\tURL=" . $currentBookmark->locator . "$newline");
	      echo("\tCREATED=$newline");
	      echo("\tVISITED=0$newline");
	      echo("\tPERSONALBAR_POS=-1$newline");
	      echo("\tPANEL_POS=-1$newline");
	      echo("\tDESCRIPTION=". $currentBookmark->description. "$newline");
	      echo("\tSHORT NAME=$newline"); 
	      echo("\tORDER=$cnt_b$newline$newline");
	    }
	  }
	}
	
	/**
	 * Imports bookmarks from a netscape file for a certain user
	 *
	 * @param string userId the identifier for the user
	 * @param string userfile the file that contains the netscape bookmarks
	 */
	function importNetscapeBookmarks($userId, $userfile, $callback, $parentId) 
	{
		$stringUtils = new StringUtils ();
		$bookmarkOperations = $callback; 
	
	  	$fp = fopen($userfile, "r");
	
	  	// check the first line which identifies the type
	  	$firstLine = fgets($fp, 4096);
	  	$typeIndicator = "<!DOCTYPE NETSCAPE-Bookmark-file-1>";
	
	  	if (!$stringUtils->startsWith ($firstLine, $typeIndicator))
			die ("Not a valid Netscape file");
	
	  	while (!feof($fp)) 
	  	{
	    		$currentLine = fgets($fp, 4096);
	
	    		// Start a folder. Only used for indentation
	    	
	    		if (ereg("^[ ]*<DL", $currentLine)) 
	    		{  
	    			// nothing....
	    		} 
	    		// Ends a (sub)folder. Only used for indentation
	    		else if (ereg("^[ ]*<\/DL", $currentLine)) 
	    		{  
	      			$top--;
	      			// Hmm.. this seems to be a bug.... Next line should not be here.
	      			if ($top < 0) { $top = 0; }
	      			$parentId = $stack[$top]; 
	    		} 
	    		// Starts a bookmark
	    		else if (ereg("^[ ]*<DT", $currentLine)) 
	    		{
	      			if (ereg("<A", $currentLine)) 
	      			{ 
					$currentBookmark = new Bookmark 
						(null, null, null, null,
			 			null, null, null, null,	
			 			null, null, null, null, null);
	
	        			$locator = ereg_replace("([^H]*HREF=\")([^\"]*)(\".*)", "\\2", $currentLine);
					$currentBookmark->locator = $locator;
	        			$name = ereg_replace("^( *<DT><[^>]*>)([^<]*)(.*)", "\\2", $currentLine);
					$currentBookmark->name = $name;
					$currentBookmark->isParent = 0;
					$currentBookmark->parentId = $parentId;
	
					$bookmarkOperations->addItem
						($userId, $currentBookmark);
	      			} 
	      			// Start a folder
	      			else 
	      			{ 
	      				// the actual folder definition
	        			$name = ereg_replace("^( *<DT><[^>]*>)([^<]*)(.*)", "\\2", $currentLine);
					$currentBookmark = new Bookmark 
						(null, null, null, null,
			 			null, null, null, null,	
			 			null, null, null, null, null);
					$currentBookmark->isParent = 1;
					$currentBookmark->parentId = $parentId;
					$currentBookmark->name = $name;
	
					// put the current folder on the stack
	        			$stack[$top] = $parentId;
	        			$top++;
	
					// rertieve the new parent id by adding
					// its 
					$parentId = 
					$bookmarkOperations->addItem
						($userId, $currentBookmark);
	      			}
	    		}
	  	}
	  	fclose($fp);
	}
	
	/**
	 * Export bookmarks for a certain user starting at a certain 
	 * item
	 * 
	 * @param string userId the indentifier for the user for which we would
	 * like to export bookmarks
	 * @param integer rootId the identifier for the item and all its children
	 * which we would like to export.
	 */
	function exportNetscapeBookmarks ($userId, $rootId, $callback)
	{
		global $indentLevel;
		$newline = "\n";
			// This is not correct if we would like to generate a proper
			// bookmark file from a subfolder
		if ($rootId == 0)
		{
			echo ('<!DOCTYPE NETSCAPE-Bookmark-file-1>'.$newline);
			echo ('<META HTTP-EQUIV="Content-Type" ');
			echo ('CONTENT="text/html; charset=UTF-8">'.$newline);
			echo ('<TITLE>Bookmarks</TITLE>'.$newline);
			echo ('<H1>Bookmarks</H1>'.$newline.$newline);
	
			echo ('<DL><p>'.$newline);
		}
	
		$bookmarkOperations = $callback; 
		//= new BookmarkOperations ();
		$children = $bookmarkOperations->getChildren ($userId, $rootId);
		for ($i=0; $i<count($children); $i++)
		{
			$current = $children [$i];
	
			// We have a folder
			if ($current->isParent==1)
			{
				// print the appropriate indentation
				for ($j=0; $j<$indentLevel; $j++)
				{
					echo ('    ');
				}
				// print name
				echo ('<DT><H3>'.$current->name.'</H3>'.$newline);
				for ($j=0; $j<$indentLevel; $j++)
				{
					echo ('    ');
				}
				echo ('<DL><p>'.$newline);
	
				// and do the same recursively for this folders
				// children
				$indentLevel++;
				$this->exportNetscapeBookmarks ($userId,
					$current->itemId, $bookmarkOperations);
				$indentLevel--;
				for ($j=1; $j<$indentLevel; $j++, $callback)
				{
					echo ('    ');
				}
				echo ('</DL><p>'.$newline);
			}
			// we have a node (bookmark)
			else
			{
				for ($j=0; $j<$indentLevel; $j++)
				{
					echo ('    ');
				}
				echo ('<DT>');
				echo ('<A HREF="'.$current->locator.'">');
				echo ($current->name.'</A>'.$newline);
			}
		}
		// proper closing
		if ($rootId == null)
		{
			echo ('</DL><p>'.$newline);
		}
	}
}
?>
Return current item: Bookmarks class