0x1998 - MANAGER
Edit File: remositoryContainer.php
<?php /************************************************************** * This file is part of Remository * Copyright (c) 2006-17 Martin Brampton * * License: GNU General Public License version 2 or later; see LICENSE.txt * * For support and other information, visit http://remository.com * To contact Martin Brampton, write to martin@remository.com * * Remository started life as the psx-dude script by psx-dude@psx-dude.net * It was enhanced by Matt Smith up to version 2.10 * Since then development has been primarily by Martin Brampton, * with contributions from other people gratefully accepted */ defined('_JEXEC') or die; class InvalidFilenameException extends Exception { } class remositoryContainer extends remositoryAbstract { public static $actions = array('upload', 'download', 'edit', 'selfApprove'); /** @var int ID for container record in database */ public $id=0; /** @var int ID of parent container in database if a folder */ public $parentid=0; /** @var string Name of container */ public $name=''; /** @var string Alias for container name - used in SEF */ public $alias=''; /** @var string Path for storing files */ public $filepath=''; /** @var string Container description */ public $description=''; /** @var bool Is the container published? */ public $published=false; /** @var int Count of contained folders */ public $foldercount=0; /** @var int Files in the container count */ public $filecount=0; /** @var string Icon - not sure how this is used */ public $icon=''; /** @var Visitor options 1=upload, 2=download, 3=both, 0=neither */ public $registered='2'; /** @var User options 1=upload, 2=download, 3=both, 0=neither */ public $userupload='3'; /** @var bool Count downloads using a subscription manager if present */ public $countdown=0; /** @var bool Descendants included in this container download count via subscription manager */ public $childcountdown=0; /** @var bool Count uploads using a subscription manager if present */ public $countup=0; /** @var bool Descendants included in this container upload count via subscription manager */ public $childcountup=0; /** @var bool Is the file to be stored as a text string? */ public $plaintext=0; /** @var int Group of users that has access to this container */ public $groupid=0; /** @var int Editor group of users */ public $editgroup=0; /** @var bool Auto-approve for Admin - Yes or No (Global applies) */ public $adminauto=0; /** @var bool Auto-approve for user - Yes or No (Global applies)*/ public $userauto=0; /** @var int Auto-approve group of users */ public $autogroup=0; /** @var int User ID for personal folder */ public $userid=0; /** @var string for container_image` */ public $container_image=''; /** * File object constructor * @param int Container ID from database or null */ public function __construct ( $id=0 ) { $this->id = $id; if ($id) { $cmanager = remositoryContainerManager::getInstance(); $category = $cmanager->getContainer($id); if ($category) $this->setValues($category); } } public function __clone () { $this->id = 0; $this->name = $this->alias = $this->description = ''; $this->foldercount = $this->filecount = 0; $this->countdown = $this->childcountdown = $this->countup = $this->childcountup = 0; } protected function tableName () { return '#__downloads_containers'; } function delete ($managePhysicalFolder = false) { if($managePhysicalFolder && is_dir($this->filepath)){ @rmdir($this->filepath); } $manager = remositoryContainerManager::getInstance(); $manager->delete($this->id); } function deleteAll ($managePhysicalFolder = false) { $folders = $this->getChildren(false); foreach ($folders as $folder) $folder->deleteAll ($managePhysicalFolder); $files = $this->getFiles(true); foreach ($files as $file) $file->deleteFile(); $tempfiles = $this->getTempFiles(); foreach ($tempfiles as $file) $file->deleteFile(); $this->delete($managePhysicalFolder); } /** * Save the container : if existing, update it ; if not existing, create it * @param type $managePhysicalFolder : if true, the physical folder will be created (if not existing) * throw Exception if the current physical folder can't be created (when $managePhysicalFolder is set to true) */ function saveValues ($managePhysicalFolder = false) { $interface = remositoryInterface::getInstance(); $database = $interface->getDB(); $this->forceBools(); $new = $this->id ? false : true; if ($new) { $sql = $this->insertSQL(); remositoryRepository::doSQL ($sql); $this->id = $database->insertid(); } else { $sql = $this->updateSQL(); remositoryRepository::doSQL ($sql); } remositoryContainerManager::getInstance()->storeContainer($this, $new); if($managePhysicalFolder && ! is_dir($this->filepath)) { //we (try to) create the folder try{ if(! mkdir($this->filepath, 0777, true)) { throw new Exception(_DOWN_SUBCONTAINER_CREATE_FOLDER_ERR02); } } catch (Exception $e) { throw new Exception(_DOWN_SUBCONTAINER_CREATE_FOLDER_ERR02); } } } function notSQL () { return array ('id', 'actions'); } function setMetaData () { $interface = remositoryInterface::getInstance(); $interface->prependMetaTag('description', strip_tags($this->name)); if ($this->keywords) $interface->prependMetaTag('keywords', $this->keywords); else $interface->prependMetaTag('keywords', $this->name); } /** * * @param type $name : new container name * @param type $autogeneratePhysicalFolder : if set to true, generate a folder with a name generated from the container name formating * @return type * throw Exception when the physical folder can't be created ($autogeneratePhysicalFolder is set to true) */ function makeCopyAsChild ($name, $autogeneratePhysicalFolder=false) { $copy = clone $this; $copy->parentid = $this->id; $copy->name = $name; $copy->alias = $copy->description = ''; $copy->filecount = $copy->foldercount = 0; if ($autogeneratePhysicalFolder AND $this->filepath) { if (!is_dir($this->filepath)){ throw new Exception(_DOWN_SUBCONTAINER_CREATE_FOLDER_ERR01); } $folderName = $this->formatFolderName($name); if (strlen($folderName) == 0) { throw new InvalidFilenameException(_DOWN_SUBCONTAINER_CREATE_FOLDER_WARN01); } $copy->filepath .= $folderName.'/'; } $copy->saveValues($autogeneratePhysicalFolder); $authoriser = aliroAuthorisationAdmin::getInstance(); foreach (self::$actions as $action) { $roles = $authoriser->permittedRoles ($action, 'remosFolder', $this->id); foreach (array_keys($roles) as $role) $authoriser->permit ($role, 2, $action, 'remosFolder', $copy->id); } return $copy; } function isCategory () { if ($this->parentid == 0) return true; else return false; } function getCategoryName ($showself=false) { $category = $this->getCategory(); if ($this->parentid OR $showself) return $category->name; return '*'; } function getCategory () { $container = $this; while (is_object($container)) { $category = $container; $container = $category->getParent(); } return $category; } function getFamilyNames ($include=false) { $names = ''; $parent = $this->getParent(); if ($parent AND $parent->parentid) { $names .= '/'.$parent->name; $grandparent = $parent->getParent(); if ($grandparent AND $grandparent->parentid) { $names = '/'.$grandparent->name.$names; $greatgrandparent = $grandparent->getParent(); if ($greatgrandparent->parentid) $names = '..'.$names; } } if ($include AND $this->id AND $this->parentid) $names = $names.'/'.$this->name; if ($names) return $names; return '-'; } function getAllFamilyNames () { $names = $this->name; $parent = $this->getParent(); if ($parent) $names = $parent->getAllFamilyNames().'/'.$names; return $names; } function downloadForbidden (&$user) { $authoriser = aliroAuthoriser::getInstance(); if ($authoriser->checkPermission ('aUser', $user->id, 'download', 'remosFolder', $this->id) OR $authoriser->checkPermission ('aUser', $user->id, 'edit', 'remosFolder', $this->id) ) return false; if ($user->isLogged()) { echo '<br/> <br/> '._DOWN_MEMBER_ONLY_WARN.$this->name; return true; } echo '<br/> <br/> '._DOWN_REG_ONLY_WARN; return true; } function isCounted () { if ($this->countdown) return true; else { $ancestor = $this; while ($ancestor = new remositoryContainer($ancestor->parentid)) { if ($ancestor->countdown AND $ancestor->childcountdown) return true; } } return false; } function getChildren ($published=true, $search='') { return remositoryContainerManager::getInstance()->getChildren($this->id, $published, $search); } function getSelectedChildren ($limitstart, $limit, $search='') { $children = remositoryContainerManager::getInstance()->getChildren($this->id, false, $search); return array_slice($children, $limitstart, $limit); } function countChildren ($search='') { $children = remositoryContainerManager::getInstance()->getChildren($this->id, false, $search); return count($children); } public function descendantSQL ($operation, $actions='') { $familylist = remositoryContainerManager::getInstance()->listGivenAndDescendants($this->id); return $familylist ? "$operation #__downloads_containers AS c $actions WHERE c.id IN ($familylist) AND c.id != $this->id" : ''; } function countDescendants ($search='') { return remositoryContainerManager::getInstance()->countDescendants($this->id, $search); } function getDescendants ($limitstart=0, $limit=99999, $search='') { return remositoryContainerManager::getInstance()->getDescendants($this->id, $limitstart, $limit, $search); } function getDescendantIDs ($search='') { return remositoryContainerManager::getInstance()->getDescendantIDs($this->id, $search); } function makeDescendantsInherit () { $fields = $this->inheritableFields(); foreach ($fields as $field) { $value = $this->$field; $update[] = "c.$field='$value'"; } $setter = 'SET '.implode(', ',$update); $sql = $this->descendantSQL('UPDATE', $setter); if ($sql) remositoryRepository::doSQL($sql); } function inheritableFields () { return array ('filepath'); } function memoContainer ($container) { $fields = $this->inheritableFields(); foreach ($fields as $field) { $this->$field = $container->$field; } } function isDownloadable (&$user) { if ($user->isAdmin()) return true; $authoriser = aliroAuthoriser::getInstance(); return ($authoriser->checkPermission ('aUser', $user->id, 'download', 'remosFolder', $this->id) OR $authoriser->checkPermission ('aUser', $user->id, 'edit', 'remosFolder', $this->id) ); } function getVisibleChildren ($user) { $manager = remositoryContainerManager::getInstance(); return $manager->getVisibleChildren ($this->id, $user); } function checkFilePath () { if ($this->plaintext) $this->filepath = ''; else { $this->filepath=trim(str_replace("\\","/",$this->filepath)); if (!$this->filepath) { $repository = remositoryRepository::getInstance(); if (!$repository->Use_Database) { if ($parent = $this->getParent() AND $parent->filepath) $this->filepath = $parent->filepath; else $this->filepath = $repository->Down_Path; } } if ($this->filepath) { $dir = new remositoryDirectory($this->filepath, true); $this->filepath = $dir->getPath(); } } } public function getParent () { return remositoryContainerManager::getInstance()->getParent($this->parentid); } function increment ($by='0') { $parent = $this->getParent(); if ($parent != null) $parent->increment($by); $this->filecount = $this->filecount+$by; $sql="UPDATE #__downloads_containers SET filecount=$this->filecount WHERE id=$this->id"; remositoryRepository::doSQL($sql); } function areFilesVisible (&$user) { $repository = remositoryRepository::getInstance(); if ($repository->See_Files_no_download OR $user->isAdmin()) return true; return $this->isDownloadable($user); } function getFiles ($published, $orderby=_REM_DEFAULT_ORDERING, $search='', $limitstart=0, $limit=0, $descendants=false) { $sql = remositoryFile::getFilesSQL($published, false, $this->id, $descendants, $orderby, $search, $limitstart, $limit); return remositoryRepository::doSQLget($sql, 'remositoryFile'); } function getFileCount ($published, $orderby=_REM_DEFAULT_ORDERING, $search='', $descendants=false) { $sql = remositoryFile::getFilesSQL($published, true, $this->id, $descendants, $orderby, $search); $interface = remositoryInterface::getInstance(); $database = $interface->getDB(); $database->setQuery($sql); return $database->loadResult(); } function getFeaturedFiles ($published) { return remositoryFile::getFeaturedFiles($published, $this->id); } function getFilesCount ($search='', $remUser, $descendants=false) { $interface = remositoryInterface::getInstance(); $database = $interface->getDB(); if ($remUser->isAdmin()) $published = false; else $published = true; $sql = remositoryFile::getFilesSQL($published, true, $this->id, $descendants, 2, $search); $database->setQuery( $sql ); return $database->loadResult(); } function setFileCount ($chain=null) { $newfilecount = 0; $newfoldercount = 0; $children = $this->getChildren(false); foreach ($children as $child) { $counts = $child->setFileCount($chain); $newfilecount = $newfilecount + $counts[0]; $newfoldercount = $newfoldercount + $counts[1]; } $newfilecount = $newfilecount + remositoryContainerManager::getInstance()->getFileCount($this->id); $newfoldercount = $newfoldercount + count($children); if ($newfilecount != $this->filecount OR $newfoldercount != $this->foldercount) { $this->filecount = $newfilecount; $this->foldercount = $newfoldercount; $sql="UPDATE #__downloads_containers SET filecount=$this->filecount, foldercount=$this->foldercount WHERE id=$this->id"; remositoryRepository::doSQL($sql); } return array($this->filecount,$this->foldercount); } function getTempFiles ($search='') { $interface = remositoryInterface::getInstance(); if ($this->id == 0) return array(); // Change for multiple repositories // $repnum = max(1,remositoryRepository::getParam($_REQUEST, 'repnum', 1)); // $sql = "SELECT * FROM #__downloads_files WHERE repnum = $repnum AND containerid = $this->id AND metatype > 0"; $sql = "SELECT * FROM #__downloads_files WHERE containerid = $this->id AND metatype > 0"; if ($search) { $search = $interface->getEscaped($search); $sql .= " AND LOWER(filetitle) LIKE '%$search%'"; } $results = remositoryRepository::doSQLget($sql,'remositoryTempFile'); foreach ($results as $key=>$result) $results[$key]->containerid = -$result->containerid; return $results; } // This is used admin side, and wants all containers, whether they can accept files or not function getSelectList ($type, $parm, &$user, $notThis=0) { $repository = remositoryRepository::getInstance(); if ($this->id){ $selector[] = $repository->makeOption(0,_DOWN_NO_PARENT); } else $selector = array(); $this->addSelectList('',$selector,$notThis,$user); return $repository->selectList( $selector, $type, $parm, $this->id ); } // This is used on user side for uploads, only want containers that can accept files function getPartialSelectList ($type, $parm, &$user, $notThis=0) { $repository = remositoryRepository::getInstance(); $selector = array(); $this->addSelectList('', $selector, $notThis, $user, true); return (count($selector) ? $repository->selectList( $selector, $type, $parm, $this->id ) : ''); } // $category->addSelectList('', $selector, null, $this->remUser, true, 'download'); function addSelectList ($prefix, &$selector, $notThis, &$user, $usable=false, $action='upload') { if ($notThis AND $this->id == $notThis) return; $repository = remositoryRepository::getInstance(); if ($user->isAdmin()) { $published = false; $addthis = true; } else { $published = true; $authoriser = aliroAuthoriser::getInstance(); if ($authoriser->checkPermission ('aUser', $user->id, $action, 'remosFolder', $this->id) OR $authoriser->checkPermission ('aUser', $user->id, 'edit', 'remosFolder', $this->id) ) $addthis = true; else $addthis = false; } if ($usable AND $this->filepath AND (!file_exists($this->filepath) OR !is_writeable($this->filepath))) $addthis = false; if ($addthis AND ((!$notThis) OR ($this->id != $notThis))) { $name = $this->id ? $this->name : _DOWN_NO_PARENT; $selector[] = $repository->makeOption($this->id, $prefix.htmlspecialchars($name)); } foreach ($this->getChildren($published) as $container) $container->addSelectList($prefix.$this->name.'/',$selector,$notThis,$user, $usable, $action); } function getURL () { $func = remositoryRepository::getParam ($_REQUEST, 'func'); $type = 'direct' == substr($func,0,6) ? 'directlist' : 'select'; return remositoryRepository::getInstance()->remositoryFunctionURL($type, $this->id); } private function isLoneCategory () { if (0 == $this->parentid) { $manager = remositoryContainerManager::getInstance(); return 1 == count($manager->getCategories()) ? true : false; } return false; } public function showPathway () { $interface = remositoryInterface::getInstance(); $parent = $this->getParent(); $html = ($parent != null) ? $parent->showPathway() : ''; if ($this->isLoneCategory()) return $html; $name = htmlspecialchars($this->name); $imagelink = remositoryRepository::getInstance()->remositoryImageURL('arrow.png',9,9); $html .= <<<PATH_WAY $imagelink {$this->getURL()} $name </a> PATH_WAY; return $html; } // Alternative to use the CMS pathway instead of a separate Remository one public function showCMSPathway () { $parent = $this->getParent(); if (!is_null($parent)) $parent->showCMSPathway(); if ($this->isLoneCategory()) return; $interface = remositoryInterface::getInstance(); $link = remositoryRepository::getInstance()->RemositoryRawFunctionURL('select', $this->id); $interface->appendPathWay(htmlspecialchars($this->name), $link); } public static function getIcons () { return remositoryRepository::getIcons ('folder_icons'); } public static function togglePublished ($idlist, $value) { $cids = implode( ',', $idlist ); $sql = "UPDATE #__downloads_containers SET published=$value". "\nWHERE id IN ($cids)"; remositoryRepository::doSQL ($sql); } /************ Originally ADDED BY GEBUS, modified by Martin ************/ // All of these operations refer to actions on a container public function updatePermitted ($user) { return $this->checkUserAccess ($user, 'Allow_User_Edit'); } public function createPermitted ($user) { return $this->checkUserAccess ($user, 'Allow_User_Edit'); } public function deletePermitted ($user) { return $this->checkUserAccess ($user, 'Allow_User_Edit'); } public function submitFilesPermitted ($user) { return ($this->checkUserAccess ($user, 'Allow_User_Sub', 'upload') OR $this->checkUserAccess ($user, 'Allow_User_Sub', 'edit')); } protected function checkUserAccess ($user, $config, $type='edit') { if ($user->isAdmin()) return true; if (!($this->id AND remositoryRepository::getInstance()->$config)) return false; return aliroAuthoriser::getInstance()->checkPermission ('aUser', $user->id, $type, 'remosFolder', $this->id); } /*function normalize ($string) { $table = array( 'Š'=>'S', 'š'=>'s', 'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z', 'Č'=>'C', 'č'=>'c', 'Ć'=>'C', 'ć'=>'c', 'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E', 'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O', 'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss', 'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e', 'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b', 'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r', ); return strtr($string, $table); }*/ /** * Format a string to a filename : lower case, special stressed letters converted, special char removed, space(s) replaced by one score * @param type $string : string to be formatted to filename * @return type */ function formatFolderName($string){ $string = preg_replace("/([ ]+)/", "-", preg_replace("/([\\\\\/:*?“<>|[]&$,]+)/", "", $string ) ); return $string; } }