Your IP : 216.73.216.240


Current Path : /home/sunflowe/www2/j15/administrator/components/com_rokdownloads/models/
Upload File :
Current File : /home/sunflowe/www2/j15/administrator/components/com_rokdownloads/models/rokdownloads.php

<?php
/**
 * @version $Id: rokdownloads.php 18489 2010-02-03 00:44:48Z btowles $
 * @package RocketTheme
 * @subpackage	RokDownloads
 * @copyright Copyright (C) 2008 RocketWerx. All rights reserved.
 * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
 */

// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die();

jimport( 'joomla.application.component.model' );

/**
 * Rockdownloads Component Rokdownloads Model
 *
 * @package		RocketTheme
 * @subpackage	RokDownloads
 *
 * @since 1.5
 */
class RokdownloadsModelRokdownloads extends JModel
{
	
	var $ignored_filesystem_items = array('.svn','CVS','.DS_Store','index.html','index.htm','.htaccess');
	
	/**
	 * Constructor
	 *
	 * @since 1.5
	 */
	function __construct()
	{
		parent::__construct();

		global $mainframe, $option;

		// Get the pagination request variables
		$limit	   = $mainframe->getUserStateFromRequest( "$option.limit", 'limit', $mainframe->getCfg('list_limit'), 0);
		$limitstart = $mainframe->getUserStateFromRequest( "$option.limitstart", 'limitstart', 0 );

		$this->setState('limit', $limit);
		$this->setState('limitstart', $limitstart);
	}

	/**
	 * Gets the file/folder information from the table for the id passed in.
	 *
	 * @access public
	 * @param number id the id of the file/folder to get info for.
	 * @return TableRokdownload if successfull false if not.
	 * @since 1.5
	 */
	function getFile($id) {
		$row =& $this->getTable();
		if (!$row->load($id)) {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}
		return $row;
	}

	/**
	 * Gets the hierarchy of ordered folders from the database.  It does return the parent folder.
	 *
	 * @access public
	 * @return Array An ordered array of folders if successfull and false if not
	 */
	function getDBFolders($parentFolderId = 1){
        $query = "SELECT node.*, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth "
				."FROM #__rokdownloads AS node,#__rokdownloads AS parent,#__rokdownloads AS sub_parent,"
				."(SELECT node.id, (COUNT(parent.name) - 1) AS depth FROM #__rokdownloads AS node,#__rokdownloads AS parent "
				."WHERE node.lft BETWEEN parent.lft AND parent.rgt "
		        ."AND node.id = " . $parentFolderId . " "
		        ."GROUP BY node.id ORDER BY node.lft ) AS sub_tree "
		        ."WHERE node.lft BETWEEN parent.lft AND parent.rgt " 
		        ."AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt " 
		        ."AND sub_parent.id = sub_tree.id and node.folder = 1 "
				."GROUP BY node.id HAVING depth >= 0 ORDER BY node.lft";

        $dbrows = $this->_getList($query);
		if ($this->_db->getErrorMsg()!='') {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}

		$folders = array();
        foreach ($dbrows  as $dbrow) {
        	$folder = & $this->getTable();
        	$folder->bind($dbrow);
        	$folders[] = $folder;
        }
        return $folders;
	}
	
	/**
	 * Gets the hierarchy of ordered folders from the database.  It does not return the parent folder.
	 *
	 * @access public
	 * @return Array An ordered array of folders if successfull and false if not
	 */
	function getDBSubFolders($parentFolderId = 1){
        $query = "SELECT node.*, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth "
				."FROM #__rokdownloads AS node,#__rokdownloads AS parent,#__rokdownloads AS sub_parent,"
				."(SELECT node.id, (COUNT(parent.name) - 1) AS depth FROM #__rokdownloads AS node,#__rokdownloads AS parent "
				."WHERE node.lft BETWEEN parent.lft AND parent.rgt "
		        ."AND node.id = " . $parentFolderId . " "
		        ."GROUP BY node.id ORDER BY node.lft ) AS sub_tree "
		        ."WHERE node.lft BETWEEN parent.lft AND parent.rgt AND node.lft BETWEEN sub_parent.lft "
		        ."AND sub_parent.rgt AND sub_parent.id = sub_tree.id and node.folder = 1 "
				."GROUP BY node.id HAVING depth >= 1 ORDER BY node.lft";

        $dbrows = $this->_getList($query);
		if ($this->_db->getErrorMsg()!='') {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}

		$folders = array();
        foreach ($dbrows  as $dbrow) {
        	$folder = & $this->getTable();
        	$folder->bind($dbrow);
        	$folders[] = $folder;
        }
        return $folders;
	}
	
	function publish($publishNode){
		$user	=& JFactory::getUser();

		if ($publishNode->isCheckedOut( $user->get('id') )) {
			$this->setError(JText::_('ERROR.UNABLE_TO_PUBLISH') . " " . JText::sprintf("ERROR.CHECKED_OUT_BY_USER", $publishNode->path));
	    	return false;
		}
		
		$query = "UPDATE #__rokdownloads set published = 1 where lft >= " . $publishNode->lft . " and rgt <= " . $publishNode->rgt 
				//." and " 
				;
		$this->_db->setQuery( $query );
	    if (!$this->_db->query())
	    {
	    	$this->setError($this->_db->getErrorMsg());
	    	return false;
	    }
        return true;
	}
	function unpublish ($publishNode) {
		$query = "UPDATE #__rokdownloads set published = 0 where lft >= " . $publishNode->lft . " and rgt <= " . $publishNode->rgt; 
		$this->_db->setQuery( $query );
	    if (!$this->_db->query())
	    {
	    	$this->setError($this->_db->getErrorMsg());
	    	return false;
	    }
        return true;
	}
	
	function getFileFromPath($path = DS) {
		$query = 'SELECT node.* from #__rokdownloads as node where path = "' . JPath::clean($this->_db->getEscaped($path),"/") . '"';
		$this->_db->setQuery( $query );
		$folder = $this->_db->loadObject();
		if ($this->_db->getErrorMsg()!='') {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}
		return $folder;	
	}

	/**
	 * Gets the full hierarchy of ordered folders from the database.
	 *
	 * @access public
	 * @return Array An ordered array of folders if successfull and false if not
	 */
	function getFullDBFolders($excludefolder = null){
		$query = 'SELECT node.*, (COUNT(parent.name) - 1) AS depth  '
				.'FROM #__rokdownloads AS node, '
                .'#__rokdownloads AS parent '
                .'WHERE node.lft BETWEEN parent.lft AND parent.rgt And node.folder = 1 '
                .'GROUP BY node.id '
                .'ORDER BY node.lft';
        $dbrows = $this->_getList($query);
        if (!$dbrows) {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}
        $folders = array();
        foreach ($dbrows  as $dbrow) {

        	if ($excludefolder != null) {
        		if (!(($dbrow->lft >= $excludefolder->lft) && ($dbrow->rgt <= $excludefolder->rgt)))
        		{
        			$folder =& $this->getTable("rokdownloads");
        			$folder->bind($dbrow);
					$folders[] = $folder;
        		}
        	}
        	else {
        		$folder =& $this->getTable("rokdownloads");
        	  	$folder->bind($dbrow);
        		$folders[] = $folder;
        	}

        }
        return $folders;
	}


	/**
	 * Gets the list of files (non recursive) for the passed in folder
	 *
	 * @access public
	 * @param TableRokdownloads folder the folder to get the file for
	 * @return Array An array of TableRokdownloads objects that are the files in the folder
	 */
	function getDBFilesForFolder($folder){
		$query = "SELECT node.*, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth "
				."FROM #__rokdownloads AS node,#__rokdownloads AS parent,#__rokdownloads AS sub_parent,"
				."(SELECT node.id, (COUNT(parent.name) - 1) AS depth FROM #__rokdownloads AS node,#__rokdownloads AS parent "
				."WHERE node.lft BETWEEN parent.lft AND parent.rgt "
		        ."AND node.id = " . $folder->id . " "
		        ."GROUP BY node.id ORDER BY node.lft ) AS sub_tree "
		        ."WHERE node.lft BETWEEN parent.lft AND parent.rgt AND node.lft BETWEEN sub_parent.lft "
		        ."AND sub_parent.rgt AND sub_parent.id = sub_tree.id and node.folder = 0 "
				."GROUP BY node.id HAVING depth = 1 ORDER BY node.lft";
		$dbrows = $this->_getList($query);
		if ($this->_db->getErrorMsg()!='') {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}
        $folders = array();
        if (count($dbrows) > 0){
	        foreach ($dbrows as $dbrow) {
	        	$folder = & $this->getTable();
	        	$folder->bind($dbrow);
	        	$folders[] = $folder;
	        }
        }
        return $folders;
	}

	function getFilesystemFolders() {
		// Get the list of folders
		jimport('joomla.filesystem.folder');
		$jfolders = JFolder::listFolderTree(COM_ROKDOWNLOADS_BASE, '.', 100);
		$folders = array();
        foreach ($jfolders  as $jfolder) {
        	$folder = & $this->getTable();
        	$folder->fromJFolder($jfolder);
        	$folders[] = $folder;
        }
        return $folders;
	}

	function getFilesystemFilesFromFolder($folder) {
		jimport('joomla.filesystem.folder');
		$files = array();
		if (JFolder::exists(JPath::clean(COM_ROKDOWNLOADS_BASE.$folder->path))) {
			$fileList = JFolder::files(JPath::clean(COM_ROKDOWNLOADS_BASE.$folder->path), '.', false, false, $this->ignored_filesystem_items);
			if (count($fileList) > 0) {
				foreach($fileList as $file) {
					$fileObj = & $this->getTable();
					if (!$fileObj->fromFilesystem(JPath::clean(COM_ROKDOWNLOADS_BASE.$folder->path."/".$file))){
						//TODO: not sure what to do with an error here
					}
					$files[] = $fileObj;
				}
			}
		}
		return $files;
	}
	
	function deleteNode(&$node) {	
		jimport('joomla.filesystem.folder');
		jimport('joomla.filesystem.file');	
		// Lock Table
		$DBL = new DB($this->_db);
		$DBL->lock();
		
		$width = $node->rgt - $node->lft + 1;
		
		if ($node->folder) {
			if (JFolder::exists(JPath::clean(COM_ROKDOWNLOADS_BASE.$node->path))) {
				if (!JFolder::delete(COM_ROKDOWNLOADS_BASE.$node->path)) {
					$this->setError(JText::sprintf('ERROR.UNABLE_TO_DELETE_NODE', $node->path));
					$DBL->unlock();
		    		return false;
				}
			}
		}
		else {
			if (JFile::exists(JPath::clean(COM_ROKDOWNLOADS_BASE.$node->path))) {
				if (!JFile::delete(JPath::clean(COM_ROKDOWNLOADS_BASE.$node->path))) {
					$this->setError(JText::sprintf('ERROR.UNABLE_TO_DELETE_NODE', $node->path));
					$DBL->unlock();
		    		return false;
				}
			}
		}
		
		// Get the parents current rgt
		$query = "DELETE FROM #__rokdownloads WHERE lft BETWEEN ". $node->lft . " AND " . $node->rgt; 
		$this->_db->setQuery( $query );
	    if (!$this->_db->query())
	    {
	    	$this->setError($this->_db->getErrorMsg());
	    	$DBL->unlock();
	    	return false;
	    }

		// Update lfts and rgts
		$query = "UPDATE #__rokdownloads SET rgt = rgt - " . $width . " WHERE rgt > " . $node->rgt;
		$this->_db->setQuery( $query );
	    if (!$this->_db->query())
	    {
	    	$this->setError($this->_db->getErrorMsg());
	    	$DBL->unlock();
	    	return false;
	    }
	    $query = "UPDATE #__rokdownloads SET lft = lft - " . $width . " WHERE lft > " . $node->rgt;
		$this->_db->setQuery( $query );
	    if (!$this->_db->query())
	    {
	    	$this->setError($this->_db->getErrorMsg());
	    	$DBL->unlock();
	    	return false;
	    }

		$DBL->unlock();
		return true;
	}

	function insertNodeAtEndOfParent(&$newNode, $parent) { 
		if ($parent->rgt == -1 || $parent->lft == -1){
			//TODO: output some sort of error
			$this->setError(JText::_("ERROR.INVALID_PARENT_NODE_ON_INSERT"));
			return false;
		}

		$user = &JFactory::getUser();

		// A transaction should really begin here and not do a LOCK TABLES
		// But it is not supported yet

		// Lock Table
		$DBL = new DB($this->_db);
		$DBL->lock();

		// Get the parents current rgt
		$query = "SELECT rgt from #__rokdownloads where id = " . $parent->id;
		$this->_db->setQuery( $query );
		$dbparent = $this->_db->loadObject();

		// Update lfts and rgts
		$query = 'UPDATE #__rokdownloads SET rgt = rgt + 2 WHERE rgt >= ' . $dbparent->rgt;
		$this->_db->setQuery( $query );
	    if (!$this->_db->query())
	    {
	    	$this->setError($this->_db->getErrorMsg());
	    	$DBL->unlock();
	    	return false;
	    }


	    $query = 'UPDATE #__rokdownloads SET lft = lft + 2 WHERE lft >= ' . $dbparent->rgt;
		$this->_db->setQuery( $query );
	    if (!$this->_db->query())
	    {
	    	$this->setError($this->_db->getErrorMsg());
	    	$DBL->unlock();
	    	return false;
	    }

		// Update the new nodes fields and insert into the DB
		$newNode->lft = $dbparent->rgt;
		$newNode->rgt = $dbparent->rgt+1;

		// set the user id
		$newNode->created_by = $user->id;
		$newNode->modified_by = $user->id;

		if ($newNode->access == -1) $newNode->access = $parent->access;
		if ($newNode->created_time == '0000-00-00 00:00:00') $newNode->created_time = gmdate('Y-m-d H:i:s');
		if ($newNode->modified_time == '0000-00-00 00:00:00') $newNode->modified_time = $newNode->created_time;
		

		if (!$this->_db->insertObject('#__rokdownloads', $newNode, 'id'))
		{
	    	$this->setError($this->_db->getErrorMsg());
	    	$DBL->unlock();
	    	return false;
	    }

		// UNLOCK the Tables
		// This should be a transaction commit
		$DBL->unlock();

		return true;
	}

	function reorderNode(&$movingNode, $whereNodeId=1, $where='inside')
	{
		jimport('joomla.filesystem.folder');
		jimport('joomla.filesystem.file');

		$whereNode =& $this->getFile($whereNodeId);
		
		if ($whereNode->rgt == -1 || $whereNode->lft == -1){
			$this->setError(JText::_("ERROR.INVALID_PARENT_NODE_ON_INSERT"));
			return false;
		}

		$user = &JFactory::getUser();
		
		// check to make sure the nodes dont already exist if moving to a different dir
		if (dirname($whereNode->getFullPath()) != dirname($movingNode->getFullPath())) {
			switch ($where) {
				case ('inside'):
					$checkpath = JPath::clean($whereNode->getFullPath().DS.$movingNode->name);
					$shortpath = JPath::clean($whereNode->path.'/'.$movingNode->name,'/');
					break;
				default:
					$checkpath = JPath::clean(dirname($whereNode->getFullPath()).DS.$movingNode->name);
					$shortpath = dirname(JPath::clean($whereNode->path)."/".$movingNode->name,"/");
					break;
			}
			if (JFolder::exists($checkpath) || JFile::exists($checkpath)){
				$this->setError(JText::sprintf("ERROR.PATH_ALREADY_EXISTS", $shortpath));
		    	return false;
			}
		}
				
		// A transaction should really begin here and not do a LOCK TABLES
		// But it is not supported yet

		// Lock Table
		$DBL = new DB($this->_db);

		$DBL->lock();

		// Get Top Level Objects rgt
		$query = "SELECT rgt from #__rokdownloads where lft = 1";
		$this->_db->setQuery( $query );
		$tl = $this->_db->loadObject();
		$TLrgt = $tl->rgt;

		//Get the original Moving Nodes left and right
		$MNorgt = $movingNode->rgt;
		$MNolft = $movingNode->lft;
		$width = $MNorgt-$MNolft+1;

		//move the moving node (and all subnodes) outside of the tree
		$query = "UPDATE #__rokdownloads set rgt= ".$TLrgt." + rgt, lft=".$TLrgt."+lft WHERE lft >= ".$MNolft." AND rgt <= ".$MNorgt;
		$this->_db->setQuery( $query );
	    if (!$this->_db->query())
	    {
	    	$this->setError($this->_db->getErrorMsg());
	    	$DBL->unlock();
	    	return false;
	    }

		//Slide all nodes down to fill hole
		$query = "UPDATE #__rokdownloads set rgt=rgt-" . $width. " where rgt > ".$MNorgt;
		$this->_db->setQuery( $query );
	    if (!$this->_db->query())
	    {
	    	$this->setError($this->_db->getErrorMsg());
	    	$DBL->unlock();
	    	return false;
	    }

	    $query = "UPDATE #__rokdownloads set lft=lft-" . $width. " where lft > ".$MNorgt;
		$this->_db->setQuery( $query );
	    if (!$this->_db->query())
	    {
	    	$this->setError($this->_db->getErrorMsg());
	    	$DBL->unlock();
	    	return false;
	    }

	    //Get the Parents new info
		// Get the parents current rgt
		$whereNode =& $this->getFile($whereNodeId);

		switch ($where) {
			case ('inside'):
				//Make hole of new node(s) at new parents location
				$query = "UPDATE #__rokdownloads set rgt=rgt+" . $width. " where rgt >= " . $whereNode->rgt;
				$this->_db->setQuery( $query );
			    if (!$this->_db->query())
			    {
			    	$this->setError($this->_db->getErrorMsg());
			    	$DBL->unlock();
			    	return false;
			    }

			    $query = "UPDATE #__rokdownloads set lft=lft+" . $width. " where lft >= " . $whereNode->rgt;
				$this->_db->setQuery( $query );
			    if (!$this->_db->query())
			    {
			    	$this->setError($this->_db->getErrorMsg());
			    	$DBL->unlock();
			    	return false;
			    }

			    $topath = $whereNode->path;
		    	if ($topath != "/") {
		    		$topath .= "/";
		    	}
			    //Move the nodes into the hole and update paths
				$query = 'UPDATE #__rokdownloads set path=concat("'.$this->_db->getEscaped(JPath::clean($topath,"/")).'","'.$this->_db->getEscaped($movingNode->name).'",substr(path from length("'.$this->_db->getEscaped(JPath::clean($movingNode->path,"/")).'")+1)), '
						.'lft=((lft-'.$TLrgt.'-'.$MNolft.')+'.$whereNode->rgt.'), rgt=((rgt-'.$TLrgt.'-'.$MNolft.')+'.$whereNode->rgt.') where lft > '. $TLrgt;
				$this->_db->setQuery( $query );
			    if (!$this->_db->query())
			    {
			    	$this->setError($this->_db->getErrorMsg());
			    	$DBL->unlock();
			    	return false;
			    }

				// Move on Filesystem
				$moveresult = false;
				if ($movingNode->folder) {
			    	$moveresult = JFolder::move($movingNode->getFullPath(), $whereNode->getFullPath().DS.$movingNode->name);
				}
				else 
				{
					$moveresult = JFile::move($movingNode->getFullPath(),$whereNode->getFullPath().DS.$movingNode->name);
				}
				if (!$moveresult) {
					$this->setError(JText::_('ERROR.MOVING_FILE'));
					$DBL->unlock();
					return false;	
				}
				break;
			case ('before'):
				//Make hole of new node(s) at new location
				$query = "UPDATE #__rokdownloads set rgt=rgt+" . $width. " where rgt >= " . $whereNode->lft;
				$this->_db->setQuery( $query );
			    if (!$this->_db->query())
			    {
			    	$this->setError($this->_db->getErrorMsg());
			    	$DBL->unlock();
			    	return false;
			    }

			    $query = "UPDATE #__rokdownloads set lft=lft+" . $width. " where lft >= " . $whereNode->lft;
				$this->_db->setQuery( $query );
			    if (!$this->_db->query())
			    {
			    	$this->setError($this->_db->getErrorMsg());
			    	$DBL->unlock();
			    	return false;
			    }

			    //Move the nodes into the hole and update paths
		    	$topath = dirname($whereNode->path);
		    	if ($topath != DS) {
		    		$topath .= DS;
		    	}
			    //Move the nodes into the hole and update paths
				$query = 'UPDATE #__rokdownloads set path=concat("'.$this->_db->getEscaped(JPath::clean($topath,"/")).'","'.$this->_db->getEscaped($movingNode->name).'",substr(path from length("'.$this->_db->getEscaped(JPath::clean($movingNode->path,"/")).'")+1)), '
						.'lft=((lft-'.$TLrgt.'-'.$MNolft.')+'.$whereNode->lft.'), rgt=((rgt-'.$TLrgt.'-'.$MNolft.')+'.$whereNode->lft.') where lft > '. $TLrgt;
				$this->_db->setQuery( $query );
			    if (!$this->_db->query())
			   {
			    	$this->setError($this->_db->getErrorMsg());
			    	$DBL->unlock();
			    	return false;
			    }

				if (dirname($movingNode->getFullPath()) != dirname($whereNode->getFullPath())) {
					if ($movingNode->folder) {
			    		$moveresult = JFolder::move($movingNode->getFullPath(), dirname($whereNode->getFullPath()).DS.$movingNode->name);
					}
					else {
						$moveresult = JFile::move($movingNode->getFullPath(), dirname($whereNode->getFullPath()).DS.$movingNode->name);
					}
					if (!$moveresult) {
						$this->setError(JText::_('ERROR.MOVING_FILE'));
						$DBL->unlock();
						return false;	
					}
				}
			break;

			case ('after'):
				//Make hole of new node(s) at new location
				$query = "UPDATE #__rokdownloads set rgt=rgt+" . $width. " where rgt > " . $whereNode->rgt;
				$this->_db->setQuery( $query );
			    if (!$this->_db->query())
			    {
			    	$this->setError($this->_db->getErrorMsg());
			    	$DBL->unlock();
			    	return false;
			    }

			    $query = "UPDATE #__rokdownloads set lft=lft+" . $width. " where lft > " . $whereNode->rgt;
				$this->_db->setQuery( $query );
			    if (!$this->_db->query())
			    {
			    	$this->setError($this->_db->getErrorMsg());
			    	$DBL->unlock();
			    	return false;
			    }

			    //Move the nodes into the hole and update paths
		    	$topath = dirname($whereNode->path);
		    	if ($topath != DS) {
		    		$topath .= DS;
		    	}
				$query = 'UPDATE #__rokdownloads set path=concat("'.$this->_db->getEscaped(JPath::clean($topath,"/")).'","'.$this->_db->getEscaped($movingNode->name).'",substr(path from length("'.$this->_db->getEscaped(JPath::clean($movingNode->path,"/")).'")+1)), '
						.'lft=((lft-'.$TLrgt.'-'.$MNolft.')+'.($whereNode->rgt+1).'), rgt=((rgt-'.$TLrgt.'-'.$MNolft.')+'.($whereNode->rgt+1).') where lft > '. $TLrgt;
				$this->_db->setQuery( $query );
			    if (!$this->_db->query())
			    {
			    	$this->setError($this->_db->getErrorMsg());
			    	$DBL->unlock();
			    	return false;
			    }

				if (dirname($movingNode->getFullPath()) != dirname($whereNode->getFullPath())) {
					if ($movingNode->folder) {
			    		$moveresult = JFolder::move($movingNode->getFullPath(), dirname($whereNode->getFullPath()).DS.$movingNode->name);
					}
					else {
						$moveresult= JFile::move($movingNode->getFullPath(), dirname($whereNode->getFullPath()).DS.$movingNode->name);
					}
					if (!$moveresult) {
						$this->setError(JText::_('ERROR.MOVING_FILE'));
						$DBL->unlock();
						return false;	
					}
				}
			break;
		}
		$DBL->unlock();
		return true;
	}
	
	function findUnregistered() {
		$dbfolders =  & $this->getFullDBFolders();
		for ($i=0, $n=count($dbfolders); $i < $n; $i++){
			$this->importUnregisteredFiles($dbfolders[$i]);
		}
	}
	function importUnregisteredFolders(){
		$dbfolders =  & $this->getFullDBFolders();
		$fsfolders =  & $this->getFilesystemFolders();


		// Find all folders that are already registered
		for ($i=0, $n=count($dbfolders); $i < $n; $i++){
		        for ($j=0, $m=count($fsfolders); $j < $m; $j++){
		                if (JPath::clean($dbfolders[$i]->path) == JPath::clean($fsfolders[$j]->path)) {
		                        $dbfolders[$i]->_fsid = $fsfolders[$j]->_fsid;
		                        $dbfolders[$i]->_fsparent = $fsfolders[$j]->_fsparent;
		                        unset($fsfolders[$j]);
		                        break;
		                }
		        }
		        // reindex array
		        $fsfolders = array_values($fsfolders);
		}

		// Find parents for folders that are not registered and insert into db
		for ($j=0, $m=count($fsfolders); $j < $m; $j++){
		        for ($i=0, $n=count($dbfolders); $i < $n; $i++){
		                if ($fsfolders[$j]->_fsparent == $dbfolders[$i]->_fsid) {
		                        $this->insertNodeAtEndOfParent($fsfolders[$j], $dbfolders[$i]);
		                        $dbfolders[] = $fsfolders[$j];
		                        break;
		                }
		        }
		}
	}

	function importUnregisteredFiles($folder) {
		$dbfiles = &$this->getDBFilesForFolder($folder);
		$fsfiles = &$this->getFilesystemFilesFromFolder($folder);

		//Remove already registered files form the list
		if (count($dbfiles) > 0) {
			foreach ($dbfiles as $dbfile) {
				for ($i=0, $n=count($fsfiles); $i<$n; $i++){
					if (JPath::clean($dbfile->path) == JPath::clean($fsfiles[$i]->path)){
						unset($fsfiles[$i]);
						break;
					}
				}
				$fsfiles = array_values($fsfiles);
			}
		}
		
		// insert unregistered files into DB
		if (count($fsfiles) > 0) {
			foreach ($fsfiles as $fsfile) {
				$this->insertNodeAtEndOfParent($fsfile, $folder);
			}
		}
	}

	function getFolderTree($parentId=1){
		$dbfolders =  & $this->getDBFolders($parentId);
		$tree = array ();
   		$parents = array();
   		$dirs = array();

		for ($i=0,$n=count($dbfolders);$i<$n;$i++) {
			// add row to dirs
			$dirs[$i] = $dbfolders[$i];

			// Check to see if the stack has anything in it
			if (count($parents)>0) {
	           	// Remove all nodes who are below us from parent tree
	           	while (count($parents)> 0 && $dirs[$parents[count($parents)-1]]->rgt < $dbfolders[$i]->rgt) {
	               $lastparent = array_pop($parents);
	        	}
	        	// The last one removed must be a top level parent
	        	if (count($parents) == 0) {
	        		$tree[] =& $dirs[$lastparent];
	        	}
	   		}

   		 	// If there is still a parent add the child to it
        	if (count($parents)>0) {
				$dirs[$parents[count($parents)-1]]->_children[] = & $dirs[$i];
        	}

			// Add row to the parents
			$parents[] = $i;

			// If last iteration, roll up to catch last top level parent
			if ($i == $n-1)
			{
				while (count($parents)> 0) {
	               $lastparent = array_pop($parents);
	        	}
	        	$tree[] =& $dirs[$lastparent];
			}
		}

		return $tree;
	}
	function getSubFolderTree($parentId=1){
		$dbfolders =  & $this->getDBSubFolders($parentId);
		$tree = array ();
   		$parents = array();
   		$dirs = array();

		for ($i=0,$n=count($dbfolders);$i<$n;$i++) {
			// add row to dirs
			$dirs[$i] = $dbfolders[$i];

			// Check to see if the stack has anything in it
			if (count($parents)>0) {
	           	// Remove all nodes who are below us from parent tree
	           	while (count($parents)> 0 && $dirs[$parents[count($parents)-1]]->rgt < $dbfolders[$i]->rgt) {
	               $lastparent = array_pop($parents);
	        	}
	        	// The last one removed must be a top level parent
	        	if (count($parents) == 0) {
	        		$tree[] =& $dirs[$lastparent];
	        	}
	   		}

   		 	// If there is still a parent add the child to it
        	if (count($parents)>0) {
				$dirs[$parents[count($parents)-1]]->_children[] = & $dirs[$i];
        	}

			// Add row to the parents
			$parents[] = $i;

			// If last iteration, roll up to catch last top level parent
			if ($i == $n-1)
			{
				while (count($parents)> 0) {
	               $lastparent = array_pop($parents);
	        	}
	        	$tree[] =& $dirs[$lastparent];
			}
		}

		return $tree;
	}
	
	function newFolder($newFolderName, $parentNode){
		jimport('joomla.filesystem.folder');
		jimport('joomla.filesystem.file');
		// make it safe
		$parentpath = JPath::clean(COM_ROKDOWNLOADS_BASE.$parentNode->path);
		$newpath = JPath::clean(COM_ROKDOWNLOADS_BASE.$parentNode->path.DS.$newFolderName); 
		// check to make sure the new folder does not already exsist
		if (JFolder::exists($newpath) || JFile::exists($newpath)) {
			$this->setError(JText::sprintf("ERROR.FOLDER_ALREADY_EXISTS", $newpath));
			return false;	
		}
		// create new folder on filesystem
		if (!JFolder::create($newpath)){
			$this->setError(JText::_("ERROR.CREATING_FOLDER"));
			return false;
		}
		// get JFolder of new folder
		$newfolders = JFolder::listFolderTree($parentpath, "^".$newFolderName);
		$newfolder = & $this->getTable();
        $newfolder->fromJFolder($newfolders[0]);
		// add to the db at the end of the parent
		if (!$this->insertNodeAtEndOfParent($newfolder, $parentNode)){
			$this->setError("ERROR.ADDING_FOLDER_TO_DB");
	    	return false;
		}
		return true;
	}
}

class DB {
	var $_db;
	var $locked = false;

	function __construct(&$db)
	{
		$this->_db = &$db;
	}
	function DB(&$db){
		$this->_db = &$db;
	}

    function lock () {
    	if (!$this->locked) {
	        $query = ('LOCK TABLE #__rokdownloads WRITE');
	        $this->_db->setQuery( $query );
			$this->_db->query();
			$this->locked=true;
    	}
    }
	function unlock() {
		if ($this->locked) {
			$query = 'UNLOCK TABLES';
			$this->_db->setQuery( $query );
			$this->_db->query();
			$this->locked=false;
		}
	}
    function _destructor() {
        $this->unlock();
    }
}
?>