diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..10fc578bba --- /dev/null +++ b/.travis.yml @@ -0,0 +1,13 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + +before_install: + - wget http://cs.sensiolabs.org/get/php-cs-fixer.phar + +script: + - dist/scripts/tests/syntax.sh + - dist/scripts/tests/codestyle.sh diff --git a/README.md b/README.md index e8b4855c44..b4a0021ce3 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This is the main source code repository of AjaXplorer, containing all the PHP server and HTML5 Web GUI. It was migrated from previous Sourceforge SVN repository, which is hence deprecated. -* Latest Stable release : 5.0.0 +* Latest Stable release : 5.0.3 * Latest Dev release : 4.3.4 (RC for AjaXplorer5) * License: [AGPLv3](https://www.gnu.org/licenses/agpl.html) * Lead developer : Charles du Jeu (cdujeu): [Github](https://github.com/cdujeu) | [Twitter](https://twitter.com/AjaXplorer) @@ -17,6 +17,15 @@ Please DO NOT send emails to Charles, but use the forum located on http://forum. ### How to contribute / Developer Resources +#### Coding guidelines + +To enforce some coding standards we are using PHP-CS-Fixer +``` +wget http://cs.sensiolabs.org/get/php-cs-fixer.phar +php php-cs-fixer.phar fix -v --fixers=indentation,linefeed,trailing_spaces,visibility,short_tag,braces,php_closing_tag,controls_spaces,eof_ending ajaxplorer-core/ +``` +See https://github.com/fabpot/PHP-CS-Fixer#usage + #### Fixing the Core If you think you have found a bug and a way to fix it neatly in the code, use a Pull Request to report this change back to us! diff --git a/core/src/conf/RELEASE_NOTE b/core/src/conf/RELEASE_NOTE index ede3c7d393..da49c3b1a6 100644 --- a/core/src/conf/RELEASE_NOTE +++ b/core/src/conf/RELEASE_NOTE @@ -1,10 +1,75 @@ AjaXplorer ##VERSION_NUMBER## Release Note +This is a bugfix and security release. Update is highly recommended and automatic using the in-app upgrade mechanism. Most important fixes are: + +- Vulnerabilities fixed and security enforced: new algorithm used for hashing passwords, enforce tokens generation, etc. PHP Mcrypt extension is now more than ever required. +- Stabilize authentification (groups, LDAP) on the 5.X branch +- Stabilize alternative uploaders remote drivers (Jumploader) +- Many GUI bugs fixed + License : Affero GPL Copyright : Charles du Jeu 2013 Demo : http://demo.ajaxplorer.info/ Date : ##VERSION_DATE## Rev Number : ##REVISION## +Contributors: thomasCresson, echampet, joubertredrat, BlackLionPT + +Detailed changeLog + +Add X-Accel-Redirect support for Nginx (a sibiling of X-Sendfile) (details) +New ability in FormManager button: simply trigger client action. (details) +Always pass an ID for the event (not only alerts), and keep track of the last passed ID: triggers desktop notifications if active and possible. (details) +class.remote_fsAccessDriver.php: Fix some option loading error while using the function Ajxp_PLUGIN::init(repository, options) manifest.xml: Disabling the remote_fs driver by default class.JumploaderProcessor.php: - Cross session resume implementation (doesn't work with smb) - partitioning now works with FTP - upload validation process now working for FTP and FS (details) +previous commit (#69597c9010cb41b77b2e76cc2aae5b46a6eb9e57) broke the ability to upload folder tree on FS now fixed (details) +We can now use jumploader with SMB, SFTP, FS and FTP drivers (details) +Add the property "PORT" for the sftp repository creation (could not log with the wrong port number) (details) +now getting the file "jumploader_z.jar" and putting it into the plugin folder (details) +can now upload mutliple files through jumploader with FTP (details) +can now upload multiple files through Jumploader on a FTP repository (details) +Translated every single "en.php" file (into Portuguese (Portugal)) found in the plugins directory, copying the "en.php" and changing the copies name to "pt.php" plus 3 new flags in the ".gif" format and the ".png" image saying "Drop files here". Hope this is useful! (details) +Fixed a few typos in the translations (details) +Fixed a few typos in the translations (details) +Always rtrim() groupPath from /, if not /. Close #251 (details) +Optimization: getRepositoriesList was called inside foreach loop! (details) +Replace dirname() by forwardSlashDirname() when manipulating groupPath to avoid errors on Windows. (details) +Fixed some url construction problems. Add ENCFS_UID as a plugin option because it was hardcoded and set to 33. (details) +ENCFS plugin now works with Centos 6 and Debian Ubuntu (details) +Fix #268, there was a double "basegroup filtering". (details) +Throw comprehensive exception in cleanDibiDriverParameters (details) +Implement a remote search feature for users. Declare specific remote_indexation attribute in nodes to force search engine to query server, even in "local" mode. Ability to open a user at the correct page (details) +Move MAILER from global_param to param (details) +Security enforcements: > Switch password hashing from md5 to more secure hashing (backward compatible). > Do not use the server time() as the base for the tokens (secure token & remember me cookie token) as it's too predictible > Make sure the remember me cookie has httpOnly and Secure flags. (details) +New parameters LOCAL_PREFIX and ROLE_MAP for auth.remote plugin : map CMS roles to ajaxplorer Roles. Remote plugin must pass the "role" key in the user array. Implement pagination, as the plugin is finally serial based. (details) +Fix #263 (details) +Fix #253 Fix #254 (details) +Fix #227 (duplicate menus) (details) +Use "button" type to download the Jumploader applet and install it at the right place. (details) +Typo in testParameters() function (details) +A Small fix on a send header instruction to implement a header to lighttpd server version 1.4.X. More info in http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file (details) +Notification problems with ftp fixed (details) +Fix case sensitivity (details) +LDAP: enable group(s) to role(s) mapping, and group(s) to one group mapping (defining filter) Multi Auth: fix groups listing Update Conf backends: createGroup can automatically update (details) +Wrong commit (details) +Fix auth.multi updateUserObject call in user-choice mode. (details) +Fix auth.ldap groups management. Still to be tested deeply on various systems. (details) +Fix wrong extractRealId call (details) +Do not skip the group mapping recompute to make sure the upper rights are applied (details) +Should fix error on deletion when action.antivirus is active (details) +Add configurable limit for action.share plugin (details) +Use plugin Id instead of Name in class.ShareCenter.js ajxp_plugin[@name='share'] -> ajxp_plugin[@id='action.share'] (details) +Fix groups when creating user from inside subgroup (fix #269) (details) +Can now upload file larger than 2G with Jumploader. (details) +Shorter string on small screens (details) +Make sure AJXP_ADMIN_LOGIN is not taken for a groupAdmin Fix #278 in javascript (details) + + +------------------------------------- + +License : Affero GPL +Copyright : Charles du Jeu 2013 +Demo : http://demo.ajaxplorer.info/ +Date : 18th July 2013 +Rev Number : #97582cc1938c708acd9479f4b2d03036be78729e Contributors: thomasCresson, josh4trunks, chusopr, mquandalle This is a bugfix release from v5.0.1. Update is automatic using the in-app upgrade mechanism, and is recommended. Most important fixes are: diff --git a/core/src/core/classes/class.AJXP_Cache.php b/core/src/core/classes/class.AJXP_Cache.php index 8e4e2820de..2118210ea4 100644 --- a/core/src/core/classes/class.AJXP_Cache.php +++ b/core/src/core/classes/class.AJXP_Cache.php @@ -25,30 +25,31 @@ * @package AjaXplorer * @subpackage Core */ -class AJXP_Cache { - - private static $instance; +class AJXP_Cache +{ + private static $instance; - protected $cacheDir; - protected $cacheId; - protected $masterFile; - protected $dataCallback; - protected $idComputerCallback; - - /** - * Create an AJXP_Cache instance - * @param string $pluginId - * @param string $filepath - * @param Function $dataCallback A function to generate the data cache. If no callback provided, will simply use the content of the master item as the cache data + protected $cacheDir; + protected $cacheId; + protected $masterFile; + protected $dataCallback; + protected $idComputerCallback; + + /** + * Create an AJXP_Cache instance + * @param string $pluginId + * @param string $filepath + * @param Function $dataCallback A function to generate the data cache. If no callback provided, will simply use the content of the master item as the cache data * @param string $idComputerCallback A function to generate the ID of the cache. If not provided, will generate a random hash - * @return AJXP_Cache - */ - public static function getItem($pluginId, $filepath, $dataCallback=null, $idComputerCallback = null){ - if($dataCallback == null){ - $dataCallback = array("AJXP_Cache", "simpleCopy"); - } - return new AJXP_Cache($pluginId,$filepath, $dataCallback, $idComputerCallback); - } + * @return AJXP_Cache + */ + public static function getItem($pluginId, $filepath, $dataCallback=null, $idComputerCallback = null) + { + if ($dataCallback == null) { + $dataCallback = array("AJXP_Cache", "simpleCopy"); + } + return new AJXP_Cache($pluginId,$filepath, $dataCallback, $idComputerCallback); + } /** * The default dataCallback @@ -57,9 +58,10 @@ public static function getItem($pluginId, $filepath, $dataCallback=null, $idComp * @param string $target * @return void */ - public static function simpleCopy($master, $target){ - file_put_contents($target, file_get_contents($master)); - } + public static function simpleCopy($master, $target) + { + file_put_contents($target, file_get_contents($master)); + } /** * Clear a cache item associated with the master filepath @@ -68,13 +70,14 @@ public static function simpleCopy($master, $target){ * @param String $filepath * @return void */ - public static function clearItem($pluginId, $filepath){ - $inst = new AJXP_Cache($pluginId,$filepath, false); - AJXP_Logger::debug("SHOULD REMOVE ".$inst->getId()); - if(file_exists($inst->getId())){ - @unlink($inst->getId()); - } - } + public static function clearItem($pluginId, $filepath) + { + $inst = new AJXP_Cache($pluginId,$filepath, false); + AJXP_Logger::debug("SHOULD REMOVE ".$inst->getId()); + if (file_exists($inst->getId())) { + @unlink($inst->getId()); + } + } /** * Actual Cache object. Should not be used directly, but via the factory static method getItem() @@ -84,90 +87,95 @@ public static function clearItem($pluginId, $filepath){ * @param null $idComputerCallback * @return void */ - public function AJXP_Cache($pluginId, $filepath, $dataCallback, $idComputerCallback = NULL){ - $this->cacheDir = (defined('AJXP_SHARED_CACHE_DIR')?AJXP_SHARED_CACHE_DIR:AJXP_CACHE_DIR); - $this->masterFile = $filepath; - $this->dataCallback = $dataCallback; - if($idComputerCallback != null){ - $this->idComputerCallback = $idComputerCallback; - } - $this->cacheId = $this->buildCacheId($pluginId, $filepath); - } + public function AJXP_Cache($pluginId, $filepath, $dataCallback, $idComputerCallback = NULL) + { + $this->cacheDir = (defined('AJXP_SHARED_CACHE_DIR')?AJXP_SHARED_CACHE_DIR:AJXP_CACHE_DIR); + $this->masterFile = $filepath; + $this->dataCallback = $dataCallback; + if ($idComputerCallback != null) { + $this->idComputerCallback = $idComputerCallback; + } + $this->cacheId = $this->buildCacheId($pluginId, $filepath); + } /** * Load the actual data, either from the cache or from the master, and save it in the cache if necessary. * @return string */ - public function getData(){ - if(!$this->hasCachedVersion()){ - AJXP_Logger::debug("caching data", $this->dataCallback); - $result = call_user_func($this->dataCallback, $this->masterFile, $this->cacheId); - if($result !== false){ - $this->touch(); - } - }else{ - AJXP_Logger::debug("getting from cache"); - } - return file_get_contents($this->cacheId); - } + public function getData() + { + if (!$this->hasCachedVersion()) { + AJXP_Logger::debug("caching data", $this->dataCallback); + $result = call_user_func($this->dataCallback, $this->masterFile, $this->cacheId); + if ($result !== false) { + $this->touch(); + } + } else { + AJXP_Logger::debug("getting from cache"); + } + return file_get_contents($this->cacheId); + } /** * Check if the cache dir is writeable * @return bool */ - public function writeable(){ - return is_dir($this->cacheDir) && is_writeable($this->cacheDir); - } + public function writeable() + { + return is_dir($this->cacheDir) && is_writeable($this->cacheDir); + } /** * The unique ID of the item * @return string */ - public function getId(){ - return $this->cacheId; - } + public function getId() + { + return $this->cacheId; + } /** * Check whether a cached version of the master file exists or not * @return bool */ - public function hasCachedVersion(){ - $modifTime = filemtime($this->masterFile); - if(file_exists($this->cacheId) && filemtime($this->cacheId) >= $modifTime){ - return true; - } - return false; - } + public function hasCachedVersion() + { + $modifTime = filemtime($this->masterFile); + if (file_exists($this->cacheId) && filemtime($this->cacheId) >= $modifTime) { + return true; + } + return false; + } /** * Refresh the cached version modif date to the master modif date * @return void */ - public function touch(){ - @touch($this->cacheId, filemtime($this->masterFile)); - } - - /** + public function touch() + { + @touch($this->cacheId, filemtime($this->masterFile)); + } + + /** * Generate an ID for the cached file, either using the idComputerCallback, or a simple hash function. * @param $pluginId * @param $filePath * @return string */ - protected function buildCacheId($pluginId, $filePath){ - if(!is_dir($this->cacheDir."/".$pluginId)){ + protected function buildCacheId($pluginId, $filePath) + { + if (!is_dir($this->cacheDir."/".$pluginId)) { mkdir($this->cacheDir."/".$pluginId, 0755); } - $root = $this->cacheDir ."/".$pluginId."/"; - if(isSet($this->idComputerCallback)){ - $hash = call_user_func($this->idComputerCallback, $filePath); - }else{ - $info = pathinfo($filePath); - $hash = md5($filePath).(!empty($info["extension"])?".".$info["extension"]:""); - } - return $root.$hash; - } - - -} + $root = $this->cacheDir ."/".$pluginId."/"; + if (isSet($this->idComputerCallback)) { + $hash = call_user_func($this->idComputerCallback, $filePath); + } else { + $info = pathinfo($filePath); + $hash = md5($filePath).(!empty($info["extension"])?".".$info["extension"]:""); + } + return $root.$hash; + } + -?> \ No newline at end of file +} diff --git a/core/src/core/classes/class.AJXP_Controller.php b/core/src/core/classes/class.AJXP_Controller.php index 5e64487b78..b16bdefddd 100644 --- a/core/src/core/classes/class.AJXP_Controller.php +++ b/core/src/core/classes/class.AJXP_Controller.php @@ -1,558 +1,572 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); -/** - * Core controller for dispatching the actions. - * It uses the XML Registry (simple version, not extended) to search all the tags and find the action. - * @package AjaXplorer - * @subpackage Core - */ -class AJXP_Controller{ - - /** - * @var DOMXPath - */ - private static $xPath; - /** - * @var bool - */ - public static $lastActionNeedsAuth = false; - /** - * @var array - */ - private static $includeHooks = array(); - - /** - * Initialize the queryable xPath object - * @static - * @return DOMXPath - */ - private static function initXPath(){ - if(!isSet(self::$xPath)){ - - $registry = AJXP_PluginsService::getXmlRegistry( false ); - $changes = self::filterRegistryFromRole($registry); - if($changes) AJXP_PluginsService::updateXmlRegistry($registry); - self::$xPath = new DOMXPath($registry); - } - return self::$xPath; - } - - /** - * Check the current user "specificActionsRights" and filter the full registry actions with these. - * @static - * @param DOMDocument $registry - * @return bool - */ - public static function filterRegistryFromRole(&$registry){ - if(!AuthService::usersEnabled()) return false ; - $loggedUser = AuthService::getLoggedUser(); - if($loggedUser == null) return false; - $crtRepo = ConfService::getRepository(); - $crtRepoId = AJXP_REPO_SCOPE_ALL; // "ajxp.all"; - if($crtRepo != null && is_a($crtRepo, "Repository")){ - $crtRepoId = $crtRepo->getId(); - } - $actionRights = $loggedUser->mergedRole->listActionsStatesFor($crtRepo); - $changes = false; - $xPath = new DOMXPath($registry); - foreach($actionRights as $pluginName => $actions){ - foreach ($actions as $actionName => $enabled){ - if($enabled !== false) continue; - $actions = $xPath->query("actions/action[@name='$actionName']"); - if(!$actions->length){ - continue; - } - $action = $actions->item(0); - $action->parentNode->removeChild($action); - $changes = true; - } - } - $parameters = $loggedUser->mergedRole->listParameters(); - foreach($parameters as $scope => $paramsPlugs){ - if($scope == AJXP_REPO_SCOPE_ALL || $scope == $crtRepoId || ($crtRepo->hasParent() && $scope == AJXP_REPO_SCOPE_SHARED)){ - foreach($paramsPlugs as $plugId => $params){ - foreach($params as $name => $value){ - // Search exposed plugin_configs, replace if necessary. - $searchparams = $xPath->query("plugins/*[@id='$plugId']/plugin_configs/property[@name='$name']"); - if(!$searchparams->length) continue; - $param = $searchparams->item(0); - $newCdata = $registry->createCDATASection(json_encode($value)); - $param->removeChild($param->firstChild); - $param->appendChild($newCdata); - } - } - } - } - return $changes; - } - - - /** - * @param $actionName - * @param $path - * @return bool - */ - public static function findRestActionAndApply($actionName, $path){ - $xPath = self::initXPath(); - $actions = $xPath->query("actions/action[@name='$actionName']"); - if(!$actions->length){ - self::$lastActionNeedsAuth = true; - return false; - } - $action = $actions->item(0); - $restPathList = $xPath->query("processing/serverCallback/@restParams", $action); - if(!$restPathList->length){ - self::$lastActionNeedsAuth = true; - return false; - } - $restPath = $restPathList->item(0)->nodeValue; - $paramNames = explode("/", trim($restPath, "/")); - $path = array_shift(explode("?", $path)); - $paramValues = array_map("urldecode", explode("/", trim($path, "/"), count($paramNames))); - foreach($paramNames as $i => $pName){ - if(strpos($pName, "+") !== false){ - $paramNames[$i] = str_replace("+", "", $pName); - $paramValues[$i] = "/" . $paramValues[$i]; - } - } - if(count($paramValues) < count($paramNames)){ - $paramNames = array_slice($paramNames, 0, count($paramValues)); - } - $httpVars = array_merge($_GET, $_POST, array_combine($paramNames, $paramValues)); - return self::findActionAndApply($actionName, $httpVars, $_FILES, $action); - - } - - /** - * @static - * @param Array $parameters - * @param DOMNode $callbackNode - * @param DOMXPath $xPath - * @throws Exception - */ - public static function checkParams(&$parameters, $callbackNode, $xPath){ - if(!$callbackNode->attributes->getNamedItem('checkParams') || $callbackNode->attributes->getNamedItem('checkParams')->nodeValue != "true"){ - return; - } - $inputParams = $xPath->query("input_param", $callbackNode); - $declaredParams = array(); - foreach($inputParams as $param){ - $name = $param->attributes->getNamedItem("name")->nodeValue; - $type = $param->attributes->getNamedItem("type")->nodeValue; - $defaultNode = $param->attributes->getNamedItem("default"); - $mandatory = ($param->attributes->getNamedItem("mandatory")->nodeValue == "true"); - if($mandatory && !isSet($parameters[$name])){ - throw new Exception("Missing parameter '".$name."' of type '$type'"); - } - if($defaultNode != null && !isSet($parameters[$name])){ - $parameters[$name] = $defaultNode->nodeValue; - } - $declaredParams[] = $name; - } - foreach($parameters as $k => $n){ - if(!in_array($k, $declaredParams)) unset($parameters[$k]); - } - } - - /** - * Main method for querying the XML registry, find an action and all its associated processors, - * and apply all the callbacks. - * @static - * @param String $actionName - * @param array $httpVars - * @param array $fileVars - * @param DOMNode $action - * @return bool - */ - public static function findActionAndApply($actionName, $httpVars, $fileVars, &$action = null){ - $actionName = AJXP_Utils::sanitize($actionName, AJXP_SANITIZE_EMAILCHARS); - if($actionName == "cross_copy"){ - $pService = AJXP_PluginsService::getInstance(); - $actives = $pService->getActivePlugins(); - $accessPlug = $pService->getPluginsByType("access"); - if(count($accessPlug)){ - foreach($accessPlug as $key=>$objbect){ - if($actives[$objbect->getId()] === true){ - call_user_func(array($pService->getPluginById($objbect->getId()), "crossRepositoryCopy"), $httpVars); - break; - } - } - } - self::$lastActionNeedsAuth = true; - return ; - } - $xPath = self::initXPath(); - if($action == null){ - $actions = $xPath->query("actions/action[@name='$actionName']"); - if(!$actions->length){ - self::$lastActionNeedsAuth = true; - return false; - } - $action = $actions->item(0); - } - //Check Rights - if(AuthService::usersEnabled()){ - $loggedUser = AuthService::getLoggedUser(); - if( AJXP_Controller::actionNeedsRight($action, $xPath, "adminOnly") && - ($loggedUser == null || !$loggedUser->isAdmin())){ - $mess = ConfService::getMessages(); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, $mess[207]); - AJXP_XMLWriter::requireAuth(); - AJXP_XMLWriter::close(); - exit(1); - } - if( AJXP_Controller::actionNeedsRight($action, $xPath, "read") && - ($loggedUser == null || !$loggedUser->canRead(ConfService::getCurrentRepositoryId().""))){ - AJXP_XMLWriter::header(); - if($actionName == "ls" & $loggedUser!=null - && $loggedUser->canWrite(ConfService::getCurrentRepositoryId()."")){ - // Special case of "write only" right : return empty listing, no auth error. - AJXP_XMLWriter::close(); - exit(1); - } - $mess = ConfService::getMessages(); - AJXP_XMLWriter::sendMessage(null, $mess[208]); - AJXP_XMLWriter::requireAuth(); - AJXP_XMLWriter::close(); - exit(1); - } - if( AJXP_Controller::actionNeedsRight($action, $xPath, "write") && - ($loggedUser == null || !$loggedUser->canWrite(ConfService::getCurrentRepositoryId().""))){ - $mess = ConfService::getMessages(); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, $mess[207]); - AJXP_XMLWriter::requireAuth(); - AJXP_XMLWriter::close(); - exit(1); - } - } - - $preCalls = self::getCallbackNode($xPath, $action, 'pre_processing/serverCallback', $actionName, $httpVars, $fileVars, true); - $postCalls = self::getCallbackNode($xPath, $action, 'post_processing/serverCallback[not(@capture="true")]', $actionName, $httpVars, $fileVars, true); - $captureCalls = self::getCallbackNode($xPath, $action, 'post_processing/serverCallback[@capture="true"]', $actionName, $httpVars, $fileVars, true); - $mainCall = self::getCallbackNode($xPath, $action, "processing/serverCallback",$actionName, $httpVars, $fileVars, false); - if($mainCall != null){ - self::checkParams($httpVars, $mainCall, $xPath); - } - - if($captureCalls !== false){ - // Make sure the ShutdownScheduler has its own OB started BEFORE, as it will presumabily be - // executed AFTER the end of this one. - AJXP_ShutdownScheduler::getInstance(); - ob_start(); - $params = array("pre_processor_results" => array(), "post_processor_results" => array()); - } - if($preCalls !== false){ - foreach ($preCalls as $preCall){ - // A Preprocessing callback can modify its input arguments (passed by ref) - $preResult = self::applyCallback($xPath, $preCall, $actionName, $httpVars, $fileVars); - if(isSet($params)){ - $params["pre_processor_results"][$preCall->getAttribute("pluginId")] = $preResult; - } - } - } - if($mainCall){ - $result = self::applyCallback($xPath, $mainCall, $actionName, $httpVars, $fileVars); - if(isSet($params)){ - $params["processor_result"] = $result; - } - } - if($postCalls !== false){ - foreach ($postCalls as $postCall){ - // A Preprocessing callback can modify its input arguments (passed by ref) - $postResult = self::applyCallback($xPath, $postCall, $actionName, $httpVars, $fileVars); - if(isSet($params)){ - $params["post_processor_results"][$postCall->getAttribute("pluginId")] = $postResult; - } - } - } - if($captureCalls !== false){ - $params["ob_output"] = ob_get_contents(); - ob_end_clean(); - foreach ($captureCalls as $captureCall){ - self::applyCallback($xPath, $captureCall, $actionName, $httpVars, $params); - } - }else{ - if(isSet($result)) return $result; - } - } - - /** - * Launch a command-line version of the framework by passing the actionName & parameters as arguments. - * @static - * @param String $currentRepositoryId - * @param String $actionName - * @param Array $parameters - * @param string $user - * @param string $statusFile - * @return null|UnixProcess - */ - public static function applyActionInBackground($currentRepositoryId, $actionName, $parameters, $user ="", $statusFile = ""){ - $token = md5(time()); - $logDir = AJXP_CACHE_DIR."/cmd_outputs"; - if(!is_dir($logDir)) mkdir($logDir, 0755); - $logFile = $logDir."/".$token.".out"; - $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); - if(empty($user)){ - if(AuthService::usersEnabled() && AuthService::getLoggedUser() !== null) $user = AuthService::getLoggedUser()->getId(); - else $user = "shared"; - } - if(AuthService::usersEnabled()){ - $user = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($token."\1CDAFx¨op#"), $user, MCRYPT_MODE_ECB, $iv)); - } - $robustInstallPath = str_replace("/", DIRECTORY_SEPARATOR, AJXP_INSTALL_PATH); - $cmd = ConfService::getCoreConf("CLI_PHP")." ".$robustInstallPath.DIRECTORY_SEPARATOR."cmd.php -u=$user -t=$token -a=$actionName -r=$currentRepositoryId"; - /* Inserted next 3 lines to quote the command if in windows - rmeske*/ - if (PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows"){ - $cmd = ConfService::getCoreConf("CLI_PHP")." ".chr(34).$robustInstallPath.DIRECTORY_SEPARATOR."cmd.php".chr(34)." -u=$user -t=$token -a=$actionName -r=$currentRepositoryId"; - } - if($statusFile != ""){ - $cmd .= " -s=".$statusFile; - } - foreach($parameters as $key=>$value){ - if($key == "action" || $key == "get_action") continue; - $cmd .= " --$key=".escapeshellarg($value); - } - - return self::runCommandInBackground($cmd, $logFile); - /* - if (PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows"){ - if(AJXP_SERVER_DEBUG) $cmd .= " > ".$logFile; - if(class_exists("COM") && ConfService::getCoreConf("CLI_USE_COM")){ - $WshShell = new COM("WScript.Shell"); - $oExec = $WshShell->Run("cmd /C $cmd", 0, false); - }else{ - $tmpBat = implode(DIRECTORY_SEPARATOR, array( $robustInstallPath, "data","tmp", md5(time()).".bat")); - $cmd .= "\n DEL ".chr(34).$tmpBat.chr(34); - AJXP_Logger::debug("Writing file $cmd to $tmpBat"); - file_put_contents($tmpBat, $cmd); - pclose(popen('start /b "CLI" "'.$tmpBat.'"', 'r')); - } - }else{ - $process = new UnixProcess($cmd, (AJXP_SERVER_DEBUG?$logFile:null)); - AJXP_Logger::debug("Starting process and sending output dev null"); - return $process; - } - */ - } - - /** - * @param $cmd - * @param $logFile - * @return UnixProcess|null - */ - public static function runCommandInBackground($cmd, $logFile){ - if (PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows"){ - if(AJXP_SERVER_DEBUG) $cmd .= " > ".$logFile; - if(class_exists("COM") && ConfService::getCoreConf("CLI_USE_COM")){ - $WshShell = new COM("WScript.Shell"); - $oExec = $WshShell->Run("cmd /C $cmd", 0, false); - }else{ - $basePath = str_replace("/", DIRECTORY_SEPARATOR, AJXP_INSTALL_PATH); - $tmpBat = implode(DIRECTORY_SEPARATOR, array( $basePath, "data","tmp", md5(time()).".bat")); - $cmd .= "\n DEL ".chr(34).$tmpBat.chr(34); - AJXP_Logger::debug("Writing file $cmd to $tmpBat"); - file_put_contents($tmpBat, $cmd); - pclose(popen('start /b "CLI" "'.$tmpBat.'"', 'r')); - } - }else{ - $process = new UnixProcess($cmd, (AJXP_SERVER_DEBUG?$logFile:null)); - AJXP_Logger::debug("Starting process and sending output dev null"); - return $process; - } - } - - /** - * Find a callback node by its xpath query, filtering with the applyCondition if the xml attribute exists. - * @static - * @param DOMXPath $xPath - * @param DOMNode $actionNode - * @param string $query - * @param string $actionName - * @param array $httpVars - * @param array $fileVars - * @param bool $multiple - * @return DOMNode|bool - */ - private static function getCallbackNode($xPath, $actionNode, $query ,$actionName, $httpVars, $fileVars, $multiple = true){ - $callbacks = $xPath->query($query, $actionNode); - if(!$callbacks->length) return false; - if($multiple){ - $cbArray = array(); - foreach ($callbacks as $callback) { - if(self::appliesCondition($callback, $actionName, $httpVars, $fileVars)){ - $cbArray[] = $callback; - } - } - if(!count($cbArray)) return false; - return $cbArray; - }else{ - $callback=$callbacks->item(0); - if(!self::appliesCondition($callback, $actionName, $httpVars, $fileVars)) return false; - return $callback; - } - } - - /** - * Check in the callback node if an applyCondition XML attribute exists, and eval its content. - * The content must set an $apply boolean as result - * @static - * @param DOMNode $callback - * @param string $actionName - * @param array $httpVars - * @param array $fileVars - * @return bool - */ - private static function appliesCondition($callback, $actionName, $httpVars, $fileVars){ - if($callback->getAttribute("applyCondition")!=""){ - $apply = false; - eval($callback->getAttribute("applyCondition")); - if(!$apply) return false; - } - return true; - } - - /** - * Applies a callback node - * @static - * @param DOMXPath $xPath - * @param DOMNode $callback - * @param String $actionName - * @param Array $httpVars - * @param Array $fileVars - * @param null $variableArgs - * @throw AJXP_Exception - * @return void - */ - private static function applyCallback($xPath, $callback, &$actionName, &$httpVars, &$fileVars, &$variableArgs = null, $defer = false){ - //Processing - $plugId = $xPath->query("@pluginId", $callback)->item(0)->value; - $methodName = $xPath->query("@methodName", $callback)->item(0)->value; - $plugInstance = AJXP_PluginsService::findPluginById($plugId); - //return call_user_func(array($plugInstance, $methodName), $actionName, $httpVars, $fileVars); - // Do not use call_user_func, it cannot pass parameters by reference. - if(method_exists($plugInstance, $methodName)){ - if($variableArgs == null){ - return $plugInstance->$methodName($actionName, $httpVars, $fileVars); - }else{ - if($defer == true){ - AJXP_ShutdownScheduler::getInstance()->registerShutdownEventArray(array($plugInstance, $methodName), $variableArgs); - }else{ - call_user_func_array(array($plugInstance, $methodName), $variableArgs); - } - } - }else{ - throw new AJXP_Exception("Cannot find method $methodName for plugin $plugId!"); - } - } - - /** - * Find all callbacks registered for a given hook and apply them - * @static - * @param string $hookName - * @param array $args - * @return - */ - public static function applyHook($hookName, $args, $forceNonDefer = false){ - $xPath = self::initXPath(); - $callbacks = $xPath->query("hooks/serverCallback[@hookName='$hookName']"); - if(!$callbacks->length) return ; - $callback = new DOMNode(); - foreach ($callbacks as $callback){ - if($callback->getAttribute("applyCondition")!=""){ - $apply = false; - eval($callback->getAttribute("applyCondition")); - if(!$apply) continue; - } - //$fake1; $fake2; $fake3; - $defer = ($callback->attributes->getNamedItem("defer") != null && $callback->attributes->getNamedItem("defer")->nodeValue == "true"); - if($defer && $forceNonDefer) $defer = false; - self::applyCallback($xPath, $callback, $fake1, $fake2, $fake3, $args, $defer); - } - } - - /** - * Find the statically defined callbacks for a given hook and apply them - * @static - * @param $hookName - * @param $args - * @return - */ - public static function applyIncludeHook($hookName, &$args){ - if(!isSet(self::$includeHooks[$hookName])) return; - foreach(self::$includeHooks[$hookName] as $callback){ - call_user_func_array($callback, $args); - } - } - - /** - * Register a hook statically when it must be defined before the XML registry construction. - * @static - * @param $hookName - * @param $callback - * @return void - */ - public static function registerIncludeHook($hookName, $callback){ - if(!isSet(self::$includeHooks[$hookName])){ - self::$includeHooks[$hookName] = array(); - } - self::$includeHooks[$hookName][] = $callback; - } - - /** - * Check the rightsContext node of an action. - * @static - * @param DOMNode $actionNode - * @param DOMXPath $xPath - * @param string $right - * @return bool - */ - public static function actionNeedsRight($actionNode, $xPath, $right){ - $rights = $xPath->query("rightsContext", $actionNode); - if(!$rights->length) return false; - $rightNode = $rights->item(0); - $rightAttr = $xPath->query("@".$right, $rightNode); - if($rightAttr->length && $rightAttr->item(0)->value == "true"){ - self::$lastActionNeedsAuth = true; - return true; - } - return false; - } - - /** - * Utilitary used by the postprocesors to forward previously computed data - * @static - * @param array $postProcessData - * @return void - */ - public static function passProcessDataThrough($postProcessData){ - if(isSet($postProcessData["pre_processor_results"]) && is_array($postProcessData["pre_processor_results"])){ - print(implode("", $postProcessData["pre_processor_results"])); - } - if(isSet($postProcessData["processor_result"])){ - print($postProcessData["processor_result"]); - } - if(isSet($postProcessData["ob_output"])) print($postProcessData["ob_output"]); - } -} -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); +/** + * Core controller for dispatching the actions. + * It uses the XML Registry (simple version, not extended) to search all the tags and find the action. + * @package AjaXplorer + * @subpackage Core + */ +class AJXP_Controller +{ + /** + * @var DOMXPath + */ + private static $xPath; + /** + * @var bool + */ + public static $lastActionNeedsAuth = false; + /** + * @var array + */ + private static $includeHooks = array(); + + /** + * Initialize the queryable xPath object + * @static + * @return DOMXPath + */ + private static function initXPath() + { + if (!isSet(self::$xPath)) { + + $registry = AJXP_PluginsService::getXmlRegistry( false ); + $changes = self::filterRegistryFromRole($registry); + if($changes) AJXP_PluginsService::updateXmlRegistry($registry); + self::$xPath = new DOMXPath($registry); + } + return self::$xPath; + } + + /** + * Check the current user "specificActionsRights" and filter the full registry actions with these. + * @static + * @param DOMDocument $registry + * @return bool + */ + public static function filterRegistryFromRole(&$registry) + { + if(!AuthService::usersEnabled()) return false ; + $loggedUser = AuthService::getLoggedUser(); + if($loggedUser == null) return false; + $crtRepo = ConfService::getRepository(); + $crtRepoId = AJXP_REPO_SCOPE_ALL; // "ajxp.all"; + if ($crtRepo != null && is_a($crtRepo, "Repository")) { + $crtRepoId = $crtRepo->getId(); + } + $actionRights = $loggedUser->mergedRole->listActionsStatesFor($crtRepo); + $changes = false; + $xPath = new DOMXPath($registry); + foreach ($actionRights as $pluginName => $actions) { + foreach ($actions as $actionName => $enabled) { + if($enabled !== false) continue; + $actions = $xPath->query("actions/action[@name='$actionName']"); + if (!$actions->length) { + continue; + } + $action = $actions->item(0); + $action->parentNode->removeChild($action); + $changes = true; + } + } + $parameters = $loggedUser->mergedRole->listParameters(); + foreach ($parameters as $scope => $paramsPlugs) { + if ($scope == AJXP_REPO_SCOPE_ALL || $scope == $crtRepoId || ($crtRepo->hasParent() && $scope == AJXP_REPO_SCOPE_SHARED)) { + foreach ($paramsPlugs as $plugId => $params) { + foreach ($params as $name => $value) { + // Search exposed plugin_configs, replace if necessary. + $searchparams = $xPath->query("plugins/*[@id='$plugId']/plugin_configs/property[@name='$name']"); + if(!$searchparams->length) continue; + $param = $searchparams->item(0); + $newCdata = $registry->createCDATASection(json_encode($value)); + $param->removeChild($param->firstChild); + $param->appendChild($newCdata); + } + } + } + } + return $changes; + } + + + /** + * @param $actionName + * @param $path + * @return bool + */ + public static function findRestActionAndApply($actionName, $path) + { + $xPath = self::initXPath(); + $actions = $xPath->query("actions/action[@name='$actionName']"); + if (!$actions->length) { + self::$lastActionNeedsAuth = true; + return false; + } + $action = $actions->item(0); + $restPathList = $xPath->query("processing/serverCallback/@restParams", $action); + if (!$restPathList->length) { + self::$lastActionNeedsAuth = true; + return false; + } + $restPath = $restPathList->item(0)->nodeValue; + $paramNames = explode("/", trim($restPath, "/")); + $path = array_shift(explode("?", $path)); + $paramValues = array_map("urldecode", explode("/", trim($path, "/"), count($paramNames))); + foreach ($paramNames as $i => $pName) { + if (strpos($pName, "+") !== false) { + $paramNames[$i] = str_replace("+", "", $pName); + $paramValues[$i] = "/" . $paramValues[$i]; + } + } + if (count($paramValues) < count($paramNames)) { + $paramNames = array_slice($paramNames, 0, count($paramValues)); + } + $httpVars = array_merge($_GET, $_POST, array_combine($paramNames, $paramValues)); + return self::findActionAndApply($actionName, $httpVars, $_FILES, $action); + + } + + /** + * @static + * @param Array $parameters + * @param DOMNode $callbackNode + * @param DOMXPath $xPath + * @throws Exception + */ + public static function checkParams(&$parameters, $callbackNode, $xPath) + { + if (!$callbackNode->attributes->getNamedItem('checkParams') || $callbackNode->attributes->getNamedItem('checkParams')->nodeValue != "true") { + return; + } + $inputParams = $xPath->query("input_param", $callbackNode); + $declaredParams = array(); + foreach ($inputParams as $param) { + $name = $param->attributes->getNamedItem("name")->nodeValue; + $type = $param->attributes->getNamedItem("type")->nodeValue; + $defaultNode = $param->attributes->getNamedItem("default"); + $mandatory = ($param->attributes->getNamedItem("mandatory")->nodeValue == "true"); + if ($mandatory && !isSet($parameters[$name])) { + throw new Exception("Missing parameter '".$name."' of type '$type'"); + } + if ($defaultNode != null && !isSet($parameters[$name])) { + $parameters[$name] = $defaultNode->nodeValue; + } + $declaredParams[] = $name; + } + foreach ($parameters as $k => $n) { + if(!in_array($k, $declaredParams)) unset($parameters[$k]); + } + } + + /** + * Main method for querying the XML registry, find an action and all its associated processors, + * and apply all the callbacks. + * @static + * @param String $actionName + * @param array $httpVars + * @param array $fileVars + * @param DOMNode $action + * @return bool + */ + public static function findActionAndApply($actionName, $httpVars, $fileVars, &$action = null) + { + $actionName = AJXP_Utils::sanitize($actionName, AJXP_SANITIZE_EMAILCHARS); + if ($actionName == "cross_copy") { + $pService = AJXP_PluginsService::getInstance(); + $actives = $pService->getActivePlugins(); + $accessPlug = $pService->getPluginsByType("access"); + if (count($accessPlug)) { + foreach ($accessPlug as $key=>$objbect) { + if ($actives[$objbect->getId()] === true) { + call_user_func(array($pService->getPluginById($objbect->getId()), "crossRepositoryCopy"), $httpVars); + break; + } + } + } + self::$lastActionNeedsAuth = true; + return ; + } + $xPath = self::initXPath(); + if ($action == null) { + $actions = $xPath->query("actions/action[@name='$actionName']"); + if (!$actions->length) { + self::$lastActionNeedsAuth = true; + return false; + } + $action = $actions->item(0); + } + //Check Rights + if (AuthService::usersEnabled()) { + $loggedUser = AuthService::getLoggedUser(); + if( AJXP_Controller::actionNeedsRight($action, $xPath, "adminOnly") && + ($loggedUser == null || !$loggedUser->isAdmin())){ + $mess = ConfService::getMessages(); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, $mess[207]); + AJXP_XMLWriter::requireAuth(); + AJXP_XMLWriter::close(); + exit(1); + } + if( AJXP_Controller::actionNeedsRight($action, $xPath, "read") && + ($loggedUser == null || !$loggedUser->canRead(ConfService::getCurrentRepositoryId().""))){ + AJXP_XMLWriter::header(); + if($actionName == "ls" & $loggedUser!=null + && $loggedUser->canWrite(ConfService::getCurrentRepositoryId()."")){ + // Special case of "write only" right : return empty listing, no auth error. + AJXP_XMLWriter::close(); + exit(1); + } + $mess = ConfService::getMessages(); + AJXP_XMLWriter::sendMessage(null, $mess[208]); + AJXP_XMLWriter::requireAuth(); + AJXP_XMLWriter::close(); + exit(1); + } + if( AJXP_Controller::actionNeedsRight($action, $xPath, "write") && + ($loggedUser == null || !$loggedUser->canWrite(ConfService::getCurrentRepositoryId().""))){ + $mess = ConfService::getMessages(); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, $mess[207]); + AJXP_XMLWriter::requireAuth(); + AJXP_XMLWriter::close(); + exit(1); + } + } + + $preCalls = self::getCallbackNode($xPath, $action, 'pre_processing/serverCallback', $actionName, $httpVars, $fileVars, true); + $postCalls = self::getCallbackNode($xPath, $action, 'post_processing/serverCallback[not(@capture="true")]', $actionName, $httpVars, $fileVars, true); + $captureCalls = self::getCallbackNode($xPath, $action, 'post_processing/serverCallback[@capture="true"]', $actionName, $httpVars, $fileVars, true); + $mainCall = self::getCallbackNode($xPath, $action, "processing/serverCallback",$actionName, $httpVars, $fileVars, false); + if ($mainCall != null) { + self::checkParams($httpVars, $mainCall, $xPath); + } + + if ($captureCalls !== false) { + // Make sure the ShutdownScheduler has its own OB started BEFORE, as it will presumabily be + // executed AFTER the end of this one. + AJXP_ShutdownScheduler::getInstance(); + ob_start(); + $params = array("pre_processor_results" => array(), "post_processor_results" => array()); + } + if ($preCalls !== false) { + foreach ($preCalls as $preCall) { + // A Preprocessing callback can modify its input arguments (passed by ref) + $preResult = self::applyCallback($xPath, $preCall, $actionName, $httpVars, $fileVars); + if (isSet($params)) { + $params["pre_processor_results"][$preCall->getAttribute("pluginId")] = $preResult; + } + } + } + if ($mainCall) { + $result = self::applyCallback($xPath, $mainCall, $actionName, $httpVars, $fileVars); + if (isSet($params)) { + $params["processor_result"] = $result; + } + } + if ($postCalls !== false) { + foreach ($postCalls as $postCall) { + // A Preprocessing callback can modify its input arguments (passed by ref) + $postResult = self::applyCallback($xPath, $postCall, $actionName, $httpVars, $fileVars); + if (isSet($params)) { + $params["post_processor_results"][$postCall->getAttribute("pluginId")] = $postResult; + } + } + } + if ($captureCalls !== false) { + $params["ob_output"] = ob_get_contents(); + ob_end_clean(); + foreach ($captureCalls as $captureCall) { + self::applyCallback($xPath, $captureCall, $actionName, $httpVars, $params); + } + } else { + if(isSet($result)) return $result; + } + } + + /** + * Launch a command-line version of the framework by passing the actionName & parameters as arguments. + * @static + * @param String $currentRepositoryId + * @param String $actionName + * @param Array $parameters + * @param string $user + * @param string $statusFile + * @return null|UnixProcess + */ + public static function applyActionInBackground($currentRepositoryId, $actionName, $parameters, $user ="", $statusFile = "") + { + $token = md5(time()); + $logDir = AJXP_CACHE_DIR."/cmd_outputs"; + if(!is_dir($logDir)) mkdir($logDir, 0755); + $logFile = $logDir."/".$token.".out"; + $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); + if (empty($user)) { + if(AuthService::usersEnabled() && AuthService::getLoggedUser() !== null) $user = AuthService::getLoggedUser()->getId(); + else $user = "shared"; + } + if (AuthService::usersEnabled()) { + $user = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($token."\1CDAFx¨op#"), $user, MCRYPT_MODE_ECB, $iv)); + } + $robustInstallPath = str_replace("/", DIRECTORY_SEPARATOR, AJXP_INSTALL_PATH); + $cmd = ConfService::getCoreConf("CLI_PHP")." ".$robustInstallPath.DIRECTORY_SEPARATOR."cmd.php -u=$user -t=$token -a=$actionName -r=$currentRepositoryId"; + /* Inserted next 3 lines to quote the command if in windows - rmeske*/ + if (PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows") { + $cmd = ConfService::getCoreConf("CLI_PHP")." ".chr(34).$robustInstallPath.DIRECTORY_SEPARATOR."cmd.php".chr(34)." -u=$user -t=$token -a=$actionName -r=$currentRepositoryId"; + } + if ($statusFile != "") { + $cmd .= " -s=".$statusFile; + } + foreach ($parameters as $key=>$value) { + if($key == "action" || $key == "get_action") continue; + $cmd .= " --$key=".escapeshellarg($value); + } + + return self::runCommandInBackground($cmd, $logFile); + /* + if (PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows") { + if(AJXP_SERVER_DEBUG) $cmd .= " > ".$logFile; + if (class_exists("COM") && ConfService::getCoreConf("CLI_USE_COM")) { + $WshShell = new COM("WScript.Shell"); + $oExec = $WshShell->Run("cmd /C $cmd", 0, false); + } else { + $tmpBat = implode(DIRECTORY_SEPARATOR, array( $robustInstallPath, "data","tmp", md5(time()).".bat")); + $cmd .= "\n DEL ".chr(34).$tmpBat.chr(34); + AJXP_Logger::debug("Writing file $cmd to $tmpBat"); + file_put_contents($tmpBat, $cmd); + pclose(popen('start /b "CLI" "'.$tmpBat.'"', 'r')); + } + } else { + $process = new UnixProcess($cmd, (AJXP_SERVER_DEBUG?$logFile:null)); + AJXP_Logger::debug("Starting process and sending output dev null"); + return $process; + } + */ + } + + /** + * @param $cmd + * @param $logFile + * @return UnixProcess|null + */ + public static function runCommandInBackground($cmd, $logFile) + { + if (PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows") { + if(AJXP_SERVER_DEBUG) $cmd .= " > ".$logFile; + if (class_exists("COM") && ConfService::getCoreConf("CLI_USE_COM")) { + $WshShell = new COM("WScript.Shell"); + $oExec = $WshShell->Run("cmd /C $cmd", 0, false); + } else { + $basePath = str_replace("/", DIRECTORY_SEPARATOR, AJXP_INSTALL_PATH); + $tmpBat = implode(DIRECTORY_SEPARATOR, array( $basePath, "data","tmp", md5(time()).".bat")); + $cmd .= "\n DEL ".chr(34).$tmpBat.chr(34); + AJXP_Logger::debug("Writing file $cmd to $tmpBat"); + file_put_contents($tmpBat, $cmd); + pclose(popen('start /b "CLI" "'.$tmpBat.'"', 'r')); + } + } else { + $process = new UnixProcess($cmd, (AJXP_SERVER_DEBUG?$logFile:null)); + AJXP_Logger::debug("Starting process and sending output dev null"); + return $process; + } + } + + /** + * Find a callback node by its xpath query, filtering with the applyCondition if the xml attribute exists. + * @static + * @param DOMXPath $xPath + * @param DOMNode $actionNode + * @param string $query + * @param string $actionName + * @param array $httpVars + * @param array $fileVars + * @param bool $multiple + * @return DOMNode|bool + */ + private static function getCallbackNode($xPath, $actionNode, $query ,$actionName, $httpVars, $fileVars, $multiple = true) + { + $callbacks = $xPath->query($query, $actionNode); + if(!$callbacks->length) return false; + if ($multiple) { + $cbArray = array(); + foreach ($callbacks as $callback) { + if (self::appliesCondition($callback, $actionName, $httpVars, $fileVars)) { + $cbArray[] = $callback; + } + } + if(!count($cbArray)) return false; + return $cbArray; + } else { + $callback=$callbacks->item(0); + if(!self::appliesCondition($callback, $actionName, $httpVars, $fileVars)) return false; + return $callback; + } + } + + /** + * Check in the callback node if an applyCondition XML attribute exists, and eval its content. + * The content must set an $apply boolean as result + * @static + * @param DOMNode $callback + * @param string $actionName + * @param array $httpVars + * @param array $fileVars + * @return bool + */ + private static function appliesCondition($callback, $actionName, $httpVars, $fileVars) + { + if ($callback->getAttribute("applyCondition")!="") { + $apply = false; + eval($callback->getAttribute("applyCondition")); + if(!$apply) return false; + } + return true; + } + + /** + * Applies a callback node + * @static + * @param DOMXPath $xPath + * @param DOMNode $callback + * @param String $actionName + * @param Array $httpVars + * @param Array $fileVars + * @param null $variableArgs + * @throw AJXP_Exception + * @return void + */ + private static function applyCallback($xPath, $callback, &$actionName, &$httpVars, &$fileVars, &$variableArgs = null, $defer = false) + { + //Processing + $plugId = $xPath->query("@pluginId", $callback)->item(0)->value; + $methodName = $xPath->query("@methodName", $callback)->item(0)->value; + $plugInstance = AJXP_PluginsService::findPluginById($plugId); + //return call_user_func(array($plugInstance, $methodName), $actionName, $httpVars, $fileVars); + // Do not use call_user_func, it cannot pass parameters by reference. + if (method_exists($plugInstance, $methodName)) { + if ($variableArgs == null) { + return $plugInstance->$methodName($actionName, $httpVars, $fileVars); + } else { + if ($defer == true) { + AJXP_ShutdownScheduler::getInstance()->registerShutdownEventArray(array($plugInstance, $methodName), $variableArgs); + } else { + call_user_func_array(array($plugInstance, $methodName), $variableArgs); + } + } + } else { + throw new AJXP_Exception("Cannot find method $methodName for plugin $plugId!"); + } + } + + /** + * Find all callbacks registered for a given hook and apply them + * @static + * @param string $hookName + * @param array $args + * @return + */ + public static function applyHook($hookName, $args, $forceNonDefer = false) + { + $xPath = self::initXPath(); + $callbacks = $xPath->query("hooks/serverCallback[@hookName='$hookName']"); + if(!$callbacks->length) return ; + $callback = new DOMNode(); + foreach ($callbacks as $callback) { + if ($callback->getAttribute("applyCondition")!="") { + $apply = false; + eval($callback->getAttribute("applyCondition")); + if(!$apply) continue; + } + //$fake1; $fake2; $fake3; + $defer = ($callback->attributes->getNamedItem("defer") != null && $callback->attributes->getNamedItem("defer")->nodeValue == "true"); + if($defer && $forceNonDefer) $defer = false; + self::applyCallback($xPath, $callback, $fake1, $fake2, $fake3, $args, $defer); + } + } + + /** + * Find the statically defined callbacks for a given hook and apply them + * @static + * @param $hookName + * @param $args + * @return + */ + public static function applyIncludeHook($hookName, &$args) + { + if(!isSet(self::$includeHooks[$hookName])) return; + foreach (self::$includeHooks[$hookName] as $callback) { + call_user_func_array($callback, $args); + } + } + + /** + * Register a hook statically when it must be defined before the XML registry construction. + * @static + * @param $hookName + * @param $callback + * @return void + */ + public static function registerIncludeHook($hookName, $callback) + { + if (!isSet(self::$includeHooks[$hookName])) { + self::$includeHooks[$hookName] = array(); + } + self::$includeHooks[$hookName][] = $callback; + } + + /** + * Check the rightsContext node of an action. + * @static + * @param DOMNode $actionNode + * @param DOMXPath $xPath + * @param string $right + * @return bool + */ + public static function actionNeedsRight($actionNode, $xPath, $right) + { + $rights = $xPath->query("rightsContext", $actionNode); + if(!$rights->length) return false; + $rightNode = $rights->item(0); + $rightAttr = $xPath->query("@".$right, $rightNode); + if ($rightAttr->length && $rightAttr->item(0)->value == "true") { + self::$lastActionNeedsAuth = true; + return true; + } + return false; + } + + /** + * Utilitary used by the postprocesors to forward previously computed data + * @static + * @param array $postProcessData + * @return void + */ + public static function passProcessDataThrough($postProcessData) + { + if (isSet($postProcessData["pre_processor_results"]) && is_array($postProcessData["pre_processor_results"])) { + print(implode("", $postProcessData["pre_processor_results"])); + } + if (isSet($postProcessData["processor_result"])) { + print($postProcessData["processor_result"]); + } + if(isSet($postProcessData["ob_output"])) print($postProcessData["ob_output"]); + } +} diff --git a/core/src/core/classes/class.AJXP_Exception.php b/core/src/core/classes/class.AJXP_Exception.php index ccb7ff9546..50e4e39d91 100644 --- a/core/src/core/classes/class.AJXP_Exception.php +++ b/core/src/core/classes/class.AJXP_Exception.php @@ -1,51 +1,50 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); -/** - * Custom exception (legacy from php4 when there were no exceptions) - * @package AjaXplorer - * @subpackage Core - */ -class AJXP_Exception extends Exception { - - function AJXP_Exception($messageString, $messageId = false){ - if($messageId !== false && class_exists("ConfService")){ - $messages = ConfService::getMessages(); - if(array_key_exists($messageId, $messages)){ - $messageString = $messages[$messageId]; - }else{ - $messageString = $messageId; - } - } - parent::__construct($messageString); - } - - function errorToXml($mixed) - { - if(is_a($mixed, "Exception")){ - throw $this; - }else{ - throw new AJXP_Exception($mixed); - } - } -} - -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); +/** + * Custom exception (legacy from php4 when there were no exceptions) + * @package AjaXplorer + * @subpackage Core + */ +class AJXP_Exception extends Exception +{ + public function AJXP_Exception($messageString, $messageId = false) + { + if ($messageId !== false && class_exists("ConfService")) { + $messages = ConfService::getMessages(); + if (array_key_exists($messageId, $messages)) { + $messageString = $messages[$messageId]; + } else { + $messageString = $messageId; + } + } + parent::__construct($messageString); + } + + public function errorToXml($mixed) + { + if (is_a($mixed, "Exception")) { + throw $this; + } else { + throw new AJXP_Exception($mixed); + } + } +} diff --git a/core/src/core/classes/class.AJXP_JSPacker.php b/core/src/core/classes/class.AJXP_JSPacker.php index 7d23a010f9..8a074a35c7 100644 --- a/core/src/core/classes/class.AJXP_JSPacker.php +++ b/core/src/core/classes/class.AJXP_JSPacker.php @@ -25,32 +25,32 @@ * @package AjaXplorer * @subpackage Core */ -class AJXP_JSPacker{ - - /** - * Static function for packing all js and css into big files +class AJXP_JSPacker +{ + /** + * Static function for packing all js and css into big files * Auto detect /js/*_list.txt files and /css/*_list.txt files and pack them. - */ - function pack(){ - + */ + public function pack() + { // Make sure that the gui.* plugin is loaded $plug = AJXP_PluginsService::getInstance()->getPluginsByType("gui"); $sList = glob(CLIENT_RESOURCES_FOLDER."/js/*_list.txt"); - foreach ($sList as $list){ + foreach ($sList as $list) { $scriptName = str_replace("_list.txt", ".js", $list); AJXP_JSPacker::concatListAndPack($list, $scriptName, "Normal"); } $sList = glob(AJXP_THEME_FOLDER."/css/*_list.txt"); - foreach ($sList as $list){ + foreach ($sList as $list) { $scriptName = str_replace("_list.txt", ".css", $list); AJXP_JSPacker::concatListAndPack($list, $scriptName, "None"); } - } + } /** * Perform actual compression @@ -59,38 +59,36 @@ function pack(){ * @param $mode * @return bool */ - function concatListAndPack($src, $out, $mode){ - - if(!is_file($src) || !is_readable($src)){ - return false; - } - - // Concat List into one big string - $jscode = '' ; - $handle = @fopen($src, 'r'); - if ($handle) { - while (!feof($handle)) { - $jsline = fgets($handle, 4096) ; - if(rtrim($jsline,"\n") != ""){ - $code = file_get_contents(AJXP_INSTALL_PATH."/".CLIENT_RESOURCES_FOLDER."/".rtrim($jsline,"\n\r")) ; - if ($code) $jscode .= $code ; - } - } - fclose($handle); - } - - // Pack and write to file - require_once("packer/class.JavaScriptPacker.php"); - $packer = new JavaScriptPacker($jscode, $mode , true, false); - $packed = $packer->pack(); - if($mode == "None"){ // css case, hack for I.E. - $packed = str_replace("solid#", "solid #", $packed); - } - @file_put_contents($out, $packed); - - return true; - } - -} + public function concatListAndPack($src, $out, $mode) + { + if (!is_file($src) || !is_readable($src)) { + return false; + } -?> \ No newline at end of file + // Concat List into one big string + $jscode = '' ; + $handle = @fopen($src, 'r'); + if ($handle) { + while (!feof($handle)) { + $jsline = fgets($handle, 4096) ; + if (rtrim($jsline,"\n") != "") { + $code = file_get_contents(AJXP_INSTALL_PATH."/".CLIENT_RESOURCES_FOLDER."/".rtrim($jsline,"\n\r")) ; + if ($code) $jscode .= $code ; + } + } + fclose($handle); + } + + // Pack and write to file + require_once("packer/class.JavaScriptPacker.php"); + $packer = new JavaScriptPacker($jscode, $mode , true, false); + $packed = $packer->pack(); + if ($mode == "None") { // css case, hack for I.E. + $packed = str_replace("solid#", "solid #", $packed); + } + @file_put_contents($out, $packed); + + return true; + } + +} diff --git a/core/src/core/classes/class.AJXP_Node.php b/core/src/core/classes/class.AJXP_Node.php index 46f7450e5a..741f8645eb 100644 --- a/core/src/core/classes/class.AJXP_Node.php +++ b/core/src/core/classes/class.AJXP_Node.php @@ -26,27 +26,28 @@ * @package AjaXplorer * @subpackage Core */ -class AJXP_Node{ +class AJXP_Node +{ /** * @var string URL of the node in the form ajxp.protocol://repository_id/path/to/node */ - protected $_url; + protected $_url; /** * @var array The node metadata */ - protected $_metadata = array(); + protected $_metadata = array(); /** * @var string Associated wrapper */ - protected $_wrapperClassName; + protected $_wrapperClassName; /** * @var array Parsed url fragments */ - protected $urlParts = array(); + protected $urlParts = array(); /** * @var string A local representation of a real file, if possible */ - protected $realFilePointer; + protected $realFilePointer; /** * @var bool Whether the core information of the node is already loaded or not */ @@ -73,12 +74,14 @@ class AJXP_Node{ * @param string $url URL of the node in the form ajxp.protocol://repository_id/path/to/node * @param array $metadata Node metadata */ - public function __construct($url, $metadata = array()){ + public function __construct($url, $metadata = array()) + { $this->setUrl($url); - $this->_metadata = $metadata; - } + $this->_metadata = $metadata; + } - public function __sleep(){ + public function __sleep() + { $t = array_diff(array_keys(get_class_vars("AJXP_Node")), array("_accessDriver", "_repository", "_metaStore")); return $t; } @@ -87,19 +90,21 @@ public function __sleep(){ * @param String $url of the node in the form ajxp.protocol://repository_id/path/to/node * @return void */ - public function setUrl($url){ + public function setUrl($url) + { $this->_url = $url; // Clean url $testExp = explode("//", $url); - if(count($testExp) > 1){ + if (count($testExp) > 1) { $this->_url = array_shift($testExp)."//"; $this->_url .= implode("/", $testExp); } $this->parseUrl(); } - public function getRepository(){ - if(!isSet($this->_repository)){ + public function getRepository() + { + if (!isSet($this->_repository)) { $this->_repository = ConfService::getRepositoryById($this->urlParts["host"]); } return $this->_repository; @@ -108,10 +113,11 @@ public function getRepository(){ /** * @return AbstractAccessDriver */ - public function getDriver(){ - if(!isSet($this->_accessDriver)){ + public function getDriver() + { + if (!isSet($this->_accessDriver)) { $repo = $this->getRepository(); - if($repo != null){ + if ($repo != null) { $this->_accessDriver = ConfService::loadDriverForRepository($repo); } } @@ -121,22 +127,25 @@ public function getDriver(){ /** * @param AbstractAccessDriver */ - public function setDriver($accessDriver){ + public function setDriver($accessDriver) + { $this->_accessDriver = $accessDriver; } /** * @return MetaStoreProvider */ - protected function getMetaStore(){ - if(!isSet($this->_metaStore)){ + protected function getMetaStore() + { + if (!isSet($this->_metaStore)) { $this->getDriver(); $this->_metaStore = AJXP_PluginsService::getInstance()->getUniqueActivePluginForType("metastore"); } return $this->_metaStore; } - public function hasMetaStore(){ + public function hasMetaStore() + { return ($this->getMetaStore() != false); } @@ -147,12 +156,13 @@ public function hasMetaStore(){ * @param int $scope * @param bool $indexable */ - public function setMetadata($nameSpace, $metaData, $private = false, $scope=AJXP_METADATA_SCOPE_REPOSITORY, $indexable = false){ + public function setMetadata($nameSpace, $metaData, $private = false, $scope=AJXP_METADATA_SCOPE_REPOSITORY, $indexable = false) + { $metaStore = $this->getMetaStore(); - if($metaStore !== false){ + if ($metaStore !== false) { $metaStore->setMetadata($this, $nameSpace, $metaData, $private, $scope); //$this->mergeMetadata($metaData); - if($indexable){ + if ($indexable) { if(!isSet($this->_indexableMetaKeys[$private ? "user":"shared"]))$this->_indexableMetaKeys[$private ? "user":"shared"] = array(); $this->_indexableMetaKeys[$private ? "user":"shared"][$nameSpace] = $nameSpace; } @@ -167,11 +177,12 @@ public function setMetadata($nameSpace, $metaData, $private = false, $scope=AJXP * @param int $scope * @param bool $indexable */ - public function removeMetadata($nameSpace, $private = false, $scope=AJXP_METADATA_SCOPE_REPOSITORY, $indexable = false){ + public function removeMetadata($nameSpace, $private = false, $scope=AJXP_METADATA_SCOPE_REPOSITORY, $indexable = false) + { $metaStore = $this->getMetaStore(); - if($metaStore !== false){ + if ($metaStore !== false) { $metaStore->removeMetadata($this, $nameSpace, $private, $scope); - if($indexable && isSet($this->_indexableMetaKeys[$private ? "user":"shared"]) && isset($this->_indexableMetaKeys[$private ? "user":"shared"][$nameSpace])){ + if ($indexable && isSet($this->_indexableMetaKeys[$private ? "user":"shared"]) && isset($this->_indexableMetaKeys[$private ? "user":"shared"][$nameSpace])) { unset($this->_indexableMetaKeys[$private ? "user":"shared"][$nameSpace]); } AJXP_Controller::applyHook("node.meta_change", array(&$this)); @@ -184,11 +195,12 @@ public function removeMetadata($nameSpace, $private = false, $scope=AJXP_METADAT * @param bool $private * @param int $scope */ - public function retrieveMetadata($nameSpace, $private = false, $scope=AJXP_METADATA_SCOPE_REPOSITORY, $indexable = false){ + public function retrieveMetadata($nameSpace, $private = false, $scope=AJXP_METADATA_SCOPE_REPOSITORY, $indexable = false) + { $metaStore = $this->getMetaStore(); - if($metaStore !== false){ + if ($metaStore !== false) { $data = $metaStore->retrieveMetadata($this, $nameSpace, $private, $scope); - if(!empty($data) && $indexable){ + if (!empty($data) && $indexable) { if(!isSet($this->_indexableMetaKeys[$private ? "user":"shared"]))$this->_indexableMetaKeys[$private ? "user":"shared"] = array(); $this->_indexableMetaKeys[$private ? "user":"shared"][$nameSpace] = $nameSpace; } @@ -201,14 +213,16 @@ public function retrieveMetadata($nameSpace, $private = false, $scope=AJXP_METAD * @param bool $boolean Leaf or Collection? * @return void */ - public function setLeaf($boolean){ + public function setLeaf($boolean) + { $this->_metadata["is_file"] = $boolean; } /** * @return bool */ - public function isLeaf(){ + public function isLeaf() + { return isSet($this->_metadata["is_file"])?$this->_metadata["is_file"]:true; } @@ -216,14 +230,16 @@ public function isLeaf(){ * @param $label String Main label, will set the metadata "text" key. * @return void */ - public function setLabel($label){ + public function setLabel($label) + { $this->_metadata["text"] = $label; } /** * @return string Try to get the metadata "text" key, or the basename of the node path. */ - public function getLabel(){ + public function getLabel() + { return isSet($this->_metadata["text"])? $this->_metadata["text"] : basename($this->urlParts["path"]); } @@ -231,7 +247,8 @@ public function getLabel(){ * List all set metadata keys * @return array */ - public function listMetaKeys(){ + public function listMetaKeys() + { return array_keys($this->_metadata); } @@ -243,11 +260,12 @@ public function listMetaKeys(){ * @param mixed $details A specification of expected metadata fields, or minimal * @return void */ - public function loadNodeInfo($forceRefresh = false, $contextNode = false, $details = false){ + public function loadNodeInfo($forceRefresh = false, $contextNode = false, $details = false) + { if($this->nodeInfoLoaded && !$forceRefresh) return; - if(!empty($this->_wrapperClassName)){ + if (!empty($this->_wrapperClassName)) { $registered = AJXP_PluginsService::getInstance()->getRegisteredWrappers(); - if(!isSet($registered[$this->getScheme()])){ + if (!isSet($registered[$this->getScheme()])) { $this->getDriver()->detectStreamWrapper(true); } } @@ -260,42 +278,47 @@ public function loadNodeInfo($forceRefresh = false, $contextNode = false, $detai * This will last the time of the script and will be removed afterward. * @return string */ - public function getRealFile(){ - if(!isset($this->realFilePointer)){ - $this->realFilePointer = call_user_func(array($this->_wrapperClassName, "getRealFSReference"), $this->_url, true); - $isRemote = call_user_func(array($this->_wrapperClassName, "isRemote")); - if($isRemote){ - register_shutdown_function(array("AJXP_Utils", "silentUnlink"), $this->realFilePointer); - } - } - return $this->realFilePointer; - } + public function getRealFile() + { + if (!isset($this->realFilePointer)) { + $this->realFilePointer = call_user_func(array($this->_wrapperClassName, "getRealFSReference"), $this->_url, true); + $isRemote = call_user_func(array($this->_wrapperClassName, "isRemote")); + if ($isRemote) { + register_shutdown_function(array("AJXP_Utils", "silentUnlink"), $this->realFilePointer); + } + } + return $this->realFilePointer; + } /** * @return string URL of the node in the form ajxp.protocol://repository_id/path/to/node */ - public function getUrl(){ - return $this->_url; - } + public function getUrl() + { + return $this->_url; + } /** * @return string The path from the root of the repository */ - public function getPath(){ - return $this->urlParts["path"]; - } + public function getPath() + { + return $this->urlParts["path"]; + } /** * @return string The scheme part of the url */ - public function getScheme(){ - return $this->urlParts["scheme"]; - } + public function getScheme() + { + return $this->urlParts["scheme"]; + } /** * @return string The repository identifer */ - public function getRepositoryId(){ + public function getRepositoryId() + { return $this->urlParts["host"]; } @@ -305,42 +328,43 @@ public function getRepositoryId(){ * @param bool $mergeValues * @return void */ - public function mergeMetadata($metadata, $mergeValues = false){ - if($mergeValues){ - foreach($metadata as $key => $value){ - if(isSet($this->_metadata[$key])){ + public function mergeMetadata($metadata, $mergeValues = false) + { + if ($mergeValues) { + foreach ($metadata as $key => $value) { + if (isSet($this->_metadata[$key])) { $existingValue = explode(",", $this->_metadata[$key]); - if(!in_array($value, $existingValue)){ + if (!in_array($value, $existingValue)) { array_push($existingValue, $value); $this->_metadata[$key] = implode(",", $existingValue); } - }else{ + } else { $this->_metadata[$key] = $value; } } - }else{ + } else { $this->_metadata = array_merge($this->_metadata, $metadata); } - } + } /** * Magic getter for metadata * @param $varName * @return array|null|string */ - public function __get($varName){ - - if(strtolower($varName) == "wrapperclassname") return $this->_wrapperClassName; - if(strtolower($varName) == "url") return $this->_url; - if(strtolower($varName) == "metadata") return $this->_metadata; - if(strtolower($varName) == "indexablemetakeys") return $this->_indexableMetaKeys; + public function __get($varName) + { + if(strtolower($varName) == "wrapperclassname") return $this->_wrapperClassName; + if(strtolower($varName) == "url") return $this->_url; + if(strtolower($varName) == "metadata") return $this->_metadata; + if(strtolower($varName) == "indexablemetakeys") return $this->_indexableMetaKeys; - if(isSet($this->_metadata[$varName])){ - return $this->_metadata[$varName]; - }else{ - return null; - } - } + if (isSet($this->_metadata[$varName])) { + return $this->_metadata[$varName]; + } else { + return null; + } + } /** * Magic setter for metadata @@ -348,34 +372,36 @@ public function __get($varName){ * @param $metaValue * @return */ - public function __set($metaName, $metaValue){ - if(strtolower($metaName) == "metadata"){ - $this->_metadata = $metaValue; - return; - } + public function __set($metaName, $metaValue) + { + if (strtolower($metaName) == "metadata") { + $this->_metadata = $metaValue; + return; + } if($metaValue == null) unset($this->_metadata[$metaName]); else $this->_metadata[$metaName] = $metaValue; - } + } /** - * Safe parseUrl implementation + * Safe parseUrl implementation * @return void */ - protected function parseUrl(){ - if(strstr($this->_url, "#") !== false){ + protected function parseUrl() + { + if (strstr($this->_url, "#") !== false) { $url = str_replace("#", "__HASH__", $this->_url); $this->urlParts = parse_url($url); - foreach($this->urlParts as $partKey => $partValue){ + foreach ($this->urlParts as $partKey => $partValue) { $this->urlParts[$partKey] = str_replace("__HASH__", "#", $partValue); } - }else{ + } else { $this->urlParts = parse_url($this->_url); } - if(strstr($this->urlParts["scheme"], "ajxp.")!==false){ - $pServ = AJXP_PluginsService::getInstance(); - $this->_wrapperClassName = $pServ->getWrapperClassName($this->urlParts["scheme"]); - } - } - -} \ No newline at end of file + if (strstr($this->urlParts["scheme"], "ajxp.")!==false) { + $pServ = AJXP_PluginsService::getInstance(); + $this->_wrapperClassName = $pServ->getWrapperClassName($this->urlParts["scheme"]); + } + } + +} diff --git a/core/src/core/classes/class.AJXP_Plugin.php b/core/src/core/classes/class.AJXP_Plugin.php index 538057f302..4eeac03f1c 100644 --- a/core/src/core/classes/class.AJXP_Plugin.php +++ b/core/src/core/classes/class.AJXP_Plugin.php @@ -25,89 +25,93 @@ * @package AjaXplorer * @subpackage Core */ -class AJXP_Plugin implements Serializable{ - protected $baseDir; - protected $id; - protected $name; - protected $type; - /** - * XPath query - * - * @var DOMXPath - */ - protected $xPath; - protected $manifestLoaded = false; +class AJXP_Plugin implements Serializable +{ + protected $baseDir; + protected $id; + protected $name; + protected $type; + /** + * XPath query + * + * @var DOMXPath + */ + protected $xPath; + protected $manifestLoaded = false; protected $externalFilesAppended = false; protected $enabled; - protected $actions; - protected $registryContributions = array(); + protected $actions; + protected $registryContributions = array(); protected $contributionsLoaded = false; - protected $options; // can be passed at init time - protected $pluginConf; // can be passed at load time - protected $pluginConfDefinition; - protected $dependencies; + protected $options; // can be passed at init time + protected $pluginConf; // can be passed at load time + protected $pluginConfDefinition; + protected $dependencies; protected $streamData; - protected $mixins = array(); - public $loadingState = ""; - /** - * The manifest.xml loaded - * - * @var DOMDocument - */ - protected $manifestDoc; - - /** - * Internally store XML during serialization state. - * - * @var string - */ - private $manifestXML; - - private $serializableAttributes = array( - "baseDir", - "id", - "name", - "type", - "manifestLoaded", + protected $mixins = array(); + public $loadingState = ""; + /** + * The manifest.xml loaded + * + * @var DOMDocument + */ + protected $manifestDoc; + + /** + * Internally store XML during serialization state. + * + * @var string + */ + private $manifestXML; + + private $serializableAttributes = array( + "baseDir", + "id", + "name", + "type", + "manifestLoaded", "externalFilesAppended", "enabled", - "actions", - "registryContributions", + "actions", + "registryContributions", "contributionsLoaded", - "mixins", + "mixins", "streamData", - "options", "pluginConf", "pluginConfDefinition", "dependencies", "loadingState", "manifestXML"); - - /** - * Construction method - * - * @param string $id - * @param string $baseDir - */ - public function __construct($id, $baseDir){ - $this->baseDir = $baseDir; - $this->id = $id; - $split = explode(".", $id); - $this->type = $split[0]; - $this->name = $split[1]; - $this->actions = array(); - $this->dependencies = array(); - } + "options", "pluginConf", "pluginConfDefinition", "dependencies", "loadingState", "manifestXML"); - protected function getPluginWorkDir($check = false){ + /** + * Construction method + * + * @param string $id + * @param string $baseDir + */ + public function __construct($id, $baseDir) + { + $this->baseDir = $baseDir; + $this->id = $id; + $split = explode(".", $id); + $this->type = $split[0]; + $this->name = $split[1]; + $this->actions = array(); + $this->dependencies = array(); + } + + protected function getPluginWorkDir($check = false) + { $d = AJXP_DATA_PATH.DIRECTORY_SEPARATOR."plugins".DIRECTORY_SEPARATOR.$this->getId(); if(!$check) return $d; - if(!is_dir($d)){ + if (!is_dir($d)) { $res = @mkdir($d, 0755, true); if(!$res) throw new Exception("Error while creating plugin directory for ".$this->getId()); } return $d; } - protected function getPluginCacheDir($shared = false, $check = false){ + protected function getPluginCacheDir($shared = false, $check = false) + { $d = ($shared ? AJXP_SHARED_CACHE_DIR : AJXP_CACHE_DIR).DIRECTORY_SEPARATOR."plugins".DIRECTORY_SEPARATOR.$this->getId(); if(!$check) return $d; - if(!is_dir($d)){ + if (!is_dir($d)) { $res = @mkdir($d, 0755, true); if(!$res) throw new Exception("Error while creating plugin cache directory for ".$this->getId()); } @@ -118,16 +122,18 @@ protected function getPluginCacheDir($shared = false, $check = false){ * @param $options * @return void */ - public function init($options){ + public function init($options) + { $this->options = array_merge($this->loadOptionsDefaults(), $options); - } + } - protected function getFilteredOption($optionName, $repositoryScope = AJXP_REPO_SCOPE_ALL){ + protected function getFilteredOption($optionName, $repositoryScope = AJXP_REPO_SCOPE_ALL) + { $merged = $this->options; if(is_array($this->pluginConf)) $merged = array_merge($merged, $this->pluginConf); $loggedUser = AuthService::getLoggedUser(); - if($loggedUser != null){ - if($repositoryScope == AJXP_REPO_SCOPE_ALL){ + if ($loggedUser != null) { + if ($repositoryScope == AJXP_REPO_SCOPE_ALL) { $repo = ConfService::getRepository(); if($repo != null) $repositoryScope = $repo->getId(); } @@ -137,26 +143,27 @@ protected function getFilteredOption($optionName, $repositoryScope = AJXP_REPO_S $repositoryScope, isSet($merged[$optionName]) ? $merged[$optionName] : null ); - }else{ + } else { return isSet($merged[$optionName]) ? $merged[$optionName] : null; } } /** - * Perform initialization checks, and throw exception if problems found. - * @throws Exception - */ - public function performChecks(){ - - } + * Perform initialization checks, and throw exception if problems found. + * @throws Exception + */ + public function performChecks() + { + } /** * @return bool */ - public function isEnabled(){ + public function isEnabled() + { if(isSet($this->enabled)) return $this->enabled; $this->enabled = true; - if($this->manifestLoaded){ + if ($this->manifestLoaded) { $l = $this->xPath->query("@enabled", $this->manifestDoc->documentElement); - if($l->length && $l->item(0)->nodeValue === "false"){ + if ($l->length && $l->item(0)->nodeValue === "false") { $this->enabled = false; } } @@ -167,248 +174,255 @@ public function isEnabled(){ * Main function for loading all the nodes under registry_contributions. * @return void */ - protected function loadRegistryContributions($dry = false){ - $regNodes = $this->xPath->query("registry_contributions/*"); - for($i=0;$i<$regNodes->length;$i++){ - $regNode = $regNodes->item($i); - if($regNode->nodeType != XML_ELEMENT_NODE) continue; - if($regNode->nodeName == "external_file" && !$this->externalFilesAppended){ - $data = $this->nodeAttrToHash($regNode); - $filename = $data["filename"] OR ""; - $include = $data["include"] OR "*"; - $exclude = $data["exclude"] OR ""; - if(!is_file(AJXP_INSTALL_PATH."/".$filename)) continue; - if($include != "*") { - $include = explode(",", $include); - }else{ - $include = array("*"); - } - if($exclude != "") { - $exclude = explode(",", $exclude); - }else{ - $exclude = array(); - } - $this->initXmlContributionFile($filename, $include, $exclude, $dry); - }else{ - if(!$dry) { + protected function loadRegistryContributions($dry = false) + { + $regNodes = $this->xPath->query("registry_contributions/*"); + for ($i=0;$i<$regNodes->length;$i++) { + $regNode = $regNodes->item($i); + if($regNode->nodeType != XML_ELEMENT_NODE) continue; + if ($regNode->nodeName == "external_file" && !$this->externalFilesAppended) { + $data = $this->nodeAttrToHash($regNode); + $filename = $data["filename"] OR ""; + $include = $data["include"] OR "*"; + $exclude = $data["exclude"] OR ""; + if(!is_file(AJXP_INSTALL_PATH."/".$filename)) continue; + if ($include != "*") { + $include = explode(",", $include); + } else { + $include = array("*"); + } + if ($exclude != "") { + $exclude = explode(",", $exclude); + } else { + $exclude = array(); + } + $this->initXmlContributionFile($filename, $include, $exclude, $dry); + } else { + if (!$dry) { $this->registryContributions[]=$regNode; $this->parseSpecificContributions($regNode); } - } - } - // add manifest as a "plugins" (remove parsed contrib) - $pluginContrib = new DOMDocument(); - $pluginContrib->loadXML(""); - $manifestNode = $pluginContrib->importNode($this->manifestDoc->documentElement, true); - $pluginContrib->documentElement->appendChild($manifestNode); - $xP=new DOMXPath($pluginContrib); - $regNodeParent = $xP->query("registry_contributions", $manifestNode); - if($regNodeParent->length){ - $manifestNode->removeChild($regNodeParent->item(0)); - } - if(!$dry) { + } + } + // add manifest as a "plugins" (remove parsed contrib) + $pluginContrib = new DOMDocument(); + $pluginContrib->loadXML(""); + $manifestNode = $pluginContrib->importNode($this->manifestDoc->documentElement, true); + $pluginContrib->documentElement->appendChild($manifestNode); + $xP=new DOMXPath($pluginContrib); + $regNodeParent = $xP->query("registry_contributions", $manifestNode); + if ($regNodeParent->length) { + $manifestNode->removeChild($regNodeParent->item(0)); + } + if (!$dry) { $this->registryContributions[]=$pluginContrib->documentElement; $this->parseSpecificContributions($pluginContrib->documentElement); $this->contributionsLoaded = true; } - } + } - /** + /** * Load an external XML file and include/exclude its nodes as contributions. * @param string $xmlFile Path to the file from the base install path * @param array $include XPath query for XML Nodes to include * @param array $exclude XPath query for XML Nodes to exclude from the included ones. * @return */ - protected function initXmlContributionFile($xmlFile, $include=array("*"), $exclude=array(), $dry = false){ - $contribDoc = new DOMDocument(); - $contribDoc->load(AJXP_INSTALL_PATH."/".$xmlFile); - if(!is_array($include) && !is_array($exclude)){ - if(!$dry) { + protected function initXmlContributionFile($xmlFile, $include=array("*"), $exclude=array(), $dry = false) + { + $contribDoc = new DOMDocument(); + $contribDoc->load(AJXP_INSTALL_PATH."/".$xmlFile); + if (!is_array($include) && !is_array($exclude)) { + if (!$dry) { $this->registryContributions[] = $contribDoc->documentElement; $this->parseSpecificContributions($contribDoc->documentElement); } - return; - } - $xPath = new DOMXPath($contribDoc); - $excluded = array(); - foreach($exclude as $excludePath){ - $children = $xPath->query($excludePath); - foreach($children as $child){ - $excluded[] = $child; - } - } - $selected = array(); - foreach($include as $includePath){ - $incChildren = $xPath->query($includePath); - if(!$incChildren->length) continue; - $parentNode = $incChildren->item(0)->parentNode; - if(!isSet($selected[$parentNode->nodeName])){ - $selected[$parentNode->nodeName]=array("parent"=>$parentNode, "nodes"=>array()); - } - foreach($incChildren as $incChild){ - $foundEx = false; - foreach($excluded as $exChild){ - if($this->nodesEqual($exChild, $incChild)) { - $foundEx = true;break; - } - } - if($foundEx) continue; - $selected[$parentNode->nodeName]["nodes"][] = $incChild; - } - if(!count($selected[$parentNode->nodeName]["nodes"])){ - unset($selected[$parentNode->nodeName]); - } - } - if(!count($selected)) return; + return; + } + $xPath = new DOMXPath($contribDoc); + $excluded = array(); + foreach ($exclude as $excludePath) { + $children = $xPath->query($excludePath); + foreach ($children as $child) { + $excluded[] = $child; + } + } + $selected = array(); + foreach ($include as $includePath) { + $incChildren = $xPath->query($includePath); + if(!$incChildren->length) continue; + $parentNode = $incChildren->item(0)->parentNode; + if (!isSet($selected[$parentNode->nodeName])) { + $selected[$parentNode->nodeName]=array("parent"=>$parentNode, "nodes"=>array()); + } + foreach ($incChildren as $incChild) { + $foundEx = false; + foreach ($excluded as $exChild) { + if ($this->nodesEqual($exChild, $incChild)) { + $foundEx = true;break; + } + } + if($foundEx) continue; + $selected[$parentNode->nodeName]["nodes"][] = $incChild; + } + if (!count($selected[$parentNode->nodeName]["nodes"])) { + unset($selected[$parentNode->nodeName]); + } + } + if(!count($selected)) return; $originalRegContrib = $this->xPath->query("registry_contributions")->item(0); - foreach($selected as $parentNodeName => $data){ - $node = $data["parent"]->cloneNode(false); + foreach ($selected as $parentNodeName => $data) { + $node = $data["parent"]->cloneNode(false); //$newNode = $originalRegContrib->ownerDocument->importNode($node, false); - if($dry){ + if ($dry) { $localRegParent = $this->xPath->query("registry_contributions/".$parentNodeName); - if($localRegParent->length) { + if ($localRegParent->length) { $localRegParent = $localRegParent->item(0); - } - else{ + } else { $localRegParent = $originalRegContrib->ownerDocument->createElement($parentNodeName); $originalRegContrib->appendChild($localRegParent); } } - foreach($data["nodes"] as $childNode){ - $node->appendChild($childNode); + foreach ($data["nodes"] as $childNode) { + $node->appendChild($childNode); if($dry) $localRegParent->appendChild($localRegParent->ownerDocument->importNode($childNode, true)); - } - if(!$dry) { + } + if (!$dry) { $this->registryContributions[] = $node; $this->parseSpecificContributions($node); - }else{ + } else { $this->reloadXPath(); } - } - } + } + } /** * Dynamically modify some registry contributions nodes. Can be easily derivated to enable/disable * some features dynamically during plugin initialization. * @param DOMNode $contribNode * @return void */ - protected function parseSpecificContributions(&$contribNode){ - //Append plugin id to callback tags - $callbacks = $contribNode->getElementsByTagName("serverCallback"); - foreach($callbacks as $callback){ - $attr = $callback->ownerDocument->createAttribute("pluginId"); - $attr->value = $this->id; - $callback->appendChild($attr); - } - if($contribNode->nodeName == "actions"){ - $actionXpath=new DOMXPath($contribNode->ownerDocument); - foreach($contribNode->childNodes as $actionNode){ - if($actionNode->nodeType!=XML_ELEMENT_NODE) continue; + protected function parseSpecificContributions(&$contribNode) + { + //Append plugin id to callback tags + $callbacks = $contribNode->getElementsByTagName("serverCallback"); + foreach ($callbacks as $callback) { + $attr = $callback->ownerDocument->createAttribute("pluginId"); + $attr->value = $this->id; + $callback->appendChild($attr); + } + if ($contribNode->nodeName == "actions") { + $actionXpath=new DOMXPath($contribNode->ownerDocument); + foreach ($contribNode->childNodes as $actionNode) { + if($actionNode->nodeType!=XML_ELEMENT_NODE) continue; $names = $actionXpath->query("@name", $actionNode); - $name = $names->item(0)->value; + $name = $names->item(0)->value; $this->actions[$name] = $name; continue; /* - $actionData=array(); - $actionData["XML"] = $contribNode->ownerDocument->saveXML($actionNode); - $names = $actionXpath->query("@name", $actionNode); - $callbacks = $actionXpath->query("processing/serverCallback/@methodName", $actionNode); - if($callbacks->length){ - $actionData["callback"] = $callbacks->item(0)->value; - } - $rightContextNodes = $actionXpath->query("rightsContext",$actionNode); - if($rightContextNodes->length){ - $rightContext = $rightContextNodes->item(0); - $actionData["rights"] = $this->nodeAttrToHash($rightContext); - } - $actionData["node"] = $actionNode; - $this->actions[$name] = $actionData; + $actionData=array(); + $actionData["XML"] = $contribNode->ownerDocument->saveXML($actionNode); + $names = $actionXpath->query("@name", $actionNode); + $callbacks = $actionXpath->query("processing/serverCallback/@methodName", $actionNode); + if ($callbacks->length) { + $actionData["callback"] = $callbacks->item(0)->value; + } + $rightContextNodes = $actionXpath->query("rightsContext",$actionNode); + if ($rightContextNodes->length) { + $rightContext = $rightContextNodes->item(0); + $actionData["rights"] = $this->nodeAttrToHash($rightContext); + } + $actionData["node"] = $actionNode; + $this->actions[$name] = $actionData; */ - } - } - } + } + } + } /** * Load the main manifest.xml file of the plugni * @throws Exception * @return */ - public function loadManifest(){ - $file = $this->baseDir."/manifest.xml"; - if(!is_file($file)) { - return; - } - $this->manifestDoc = new DOMDocument(); - try{ - $this->manifestDoc->load($file); - }catch (Exception $e){ - throw $e; - } + public function loadManifest() + { + $file = $this->baseDir."/manifest.xml"; + if (!is_file($file)) { + return; + } + $this->manifestDoc = new DOMDocument(); + try { + $this->manifestDoc->load($file); + } catch (Exception $e) { + throw $e; + } $id = $this->manifestDoc->documentElement->getAttribute("id"); - if(empty($id) || $id != $this->getId()){ + if (empty($id) || $id != $this->getId()) { $this->manifestDoc->documentElement->setAttribute("id", $this->getId()); } - $this->xPath = new DOMXPath($this->manifestDoc); - $this->loadMixins(); + $this->xPath = new DOMXPath($this->manifestDoc); + $this->loadMixins(); $this->detectStreamWrapper(); - $this->manifestLoaded = true; - $this->loadDependencies(); - } + $this->manifestLoaded = true; + $this->loadDependencies(); + } /** * Get the plugin label as defined in the manifest file (label attribute) * @return mixed|string */ - public function getManifestLabel(){ - $l = $this->xPath->query("@label", $this->manifestDoc->documentElement); - if($l->length) return AJXP_XMLWriter::replaceAjxpXmlKeywords($l->item(0)->nodeValue); - else return $this->id; - } + public function getManifestLabel() + { + $l = $this->xPath->query("@label", $this->manifestDoc->documentElement); + if($l->length) return AJXP_XMLWriter::replaceAjxpXmlKeywords($l->item(0)->nodeValue); + else return $this->id; + } /** * Get the plugin description as defined in the manifest file (description attribute) * @return mixed|string */ - public function getManifestDescription(){ - $l = $this->xPath->query("@description", $this->manifestDoc->documentElement); - if($l->length) return AJXP_XMLWriter::replaceAjxpXmlKeywords($l->item(0)->nodeValue); - else return ""; - } + public function getManifestDescription() + { + $l = $this->xPath->query("@description", $this->manifestDoc->documentElement); + if($l->length) return AJXP_XMLWriter::replaceAjxpXmlKeywords($l->item(0)->nodeValue); + else return ""; + } /** * Serialized all declared attributes and return a serialized representation of this plugin. * The XML Manifest is base64 encoded before serialization. * @return string */ - public function serialize(){ - if($this->manifestDoc != null){ - $this->manifestXML = base64_encode($this->manifestDoc->saveXML()); - } - $serialArray = array(); - foreach ($this->serializableAttributes as $attr){ - $serialArray[$attr] = serialize($this->$attr); - } - return serialize($serialArray); - } + public function serialize() + { + if ($this->manifestDoc != null) { + $this->manifestXML = base64_encode($this->manifestDoc->saveXML()); + } + $serialArray = array(); + foreach ($this->serializableAttributes as $attr) { + $serialArray[$attr] = serialize($this->$attr); + } + return serialize($serialArray); + } /** * Load this plugin from its serialized reprensation. The manifest XML is base64 decoded. * @param $string * @return void */ - public function unserialize($string){ - $serialArray = unserialize($string); - foreach ($serialArray as $key => $value){ - $this->$key = unserialize($value); - } - if($this->manifestXML != NULL){ - //$this->manifestDoc = DOMDocument::loadXML(base64_decode($this->manifestXML)); + public function unserialize($string) + { + $serialArray = unserialize($string); + foreach ($serialArray as $key => $value) { + $this->$key = unserialize($value); + } + if ($this->manifestXML != NULL) { + //$this->manifestDoc = DOMDocument::loadXML(base64_decode($this->manifestXML)); $this->manifestDoc = new DOMDocument(1.0, "UTF-8"); $this->manifestDoc->loadXML(base64_decode($this->manifestXML)); - $this->reloadXPath(); - unset($this->manifestXML); - } - //var_dump($this); - } + $this->reloadXPath(); + unset($this->manifestXML); + } + //var_dump($this); + } /** * Legacy function, should better be used to return XML Nodes than string. Perform a query @@ -417,148 +431,157 @@ public function unserialize($string){ * @param string $format * @return DOMElement|DOMNodeList|string */ - public function getManifestRawContent($xmlNodeName = "", $format = "string", $externalFiles = false){ - if($externalFiles && !$this->externalFilesAppended) { + public function getManifestRawContent($xmlNodeName = "", $format = "string", $externalFiles = false) + { + if ($externalFiles && !$this->externalFilesAppended) { $this->loadRegistryContributions(true); $this->externalFilesAppended = true; } - if($xmlNodeName == ""){ - if($format == "string"){ - return $this->manifestDoc->saveXML($this->manifestDoc->documentElement); - }else{ - return $this->manifestDoc->documentElement; - } - }else{ - $nodes = $this->xPath->query($xmlNodeName); - if($format == "string"){ - $buffer = ""; - foreach ($nodes as $node){ - $buffer .= $this->manifestDoc->saveXML($node); - } - return $buffer; - }else{ - return $nodes; - } - } - } + if ($xmlNodeName == "") { + if ($format == "string") { + return $this->manifestDoc->saveXML($this->manifestDoc->documentElement); + } else { + return $this->manifestDoc->documentElement; + } + } else { + $nodes = $this->xPath->query($xmlNodeName); + if ($format == "string") { + $buffer = ""; + foreach ($nodes as $node) { + $buffer .= $this->manifestDoc->saveXML($node); + } + return $buffer; + } else { + return $nodes; + } + } + } /** * Return the registry contributions. The parameter can be used by subclasses to optimize the size of the XML returned : * the extended version is called when sending to the client, whereas the "small" version is loaded to find and apply actions. * @param bool $extendedVersion Can be used by subclasses to optimize the size of the XML returned. * @return array */ - public function getRegistryContributions($extendedVersion = true){ - if(!$this->contributionsLoaded) { + public function getRegistryContributions($extendedVersion = true) + { + if (!$this->contributionsLoaded) { $this->loadRegistryContributions(); } - return $this->registryContributions; - } + return $this->registryContributions; + } /** * Load the declared dependant plugins * @return void */ - protected function loadDependencies(){ - $depPaths = "dependencies/*/@pluginName"; - $nodes = $this->xPath->query($depPaths); - foreach ($nodes as $attr){ - $value = $attr->value; - $this->dependencies = array_merge($this->dependencies, explode("|", $value)); - } - } + protected function loadDependencies() + { + $depPaths = "dependencies/*/@pluginName"; + $nodes = $this->xPath->query($depPaths); + foreach ($nodes as $attr) { + $value = $attr->value; + $this->dependencies = array_merge($this->dependencies, explode("|", $value)); + } + } /** * Update dependencies dynamically * @param AJXP_PluginsService $pluginService * @return void */ - public function updateDependencies($pluginService){ - $append = false; - foreach ($this->dependencies as $index => $dependency){ - if($dependency == "access.AJXP_STREAM_PROVIDER"){ - unset($this->dependencies[$index]); - $append = true; - } - } - if($append){ - $this->dependencies = array_merge($this->dependencies, $pluginService->getStreamWrapperPlugins()); - } - } - /** + public function updateDependencies($pluginService) + { + $append = false; + foreach ($this->dependencies as $index => $dependency) { + if ($dependency == "access.AJXP_STREAM_PROVIDER") { + unset($this->dependencies[$index]); + $append = true; + } + } + if ($append) { + $this->dependencies = array_merge($this->dependencies, $pluginService->getStreamWrapperPlugins()); + } + } + /** * Check if this plugin depends on another one. * @param string $pluginName * @return bool */ - public function dependsOn($pluginName){ - return (in_array($pluginName, $this->dependencies) + public function dependsOn($pluginName) + { + return (in_array($pluginName, $this->dependencies) || in_array(substr($pluginName, 0, strpos($pluginName, "."))."+", $this->dependencies)); - } - /** - * Get dependencies - * - * @param AJXP_PluginsService $pluginService - * @return array - */ - public function getActiveDependencies($pluginService){ - if(!$this->manifestLoaded) return array(); - $deps = array(); - $nodes = $this->xPath->query("dependencies/activePlugin/@pluginName"); - foreach ($nodes as $attr) { - $value = $attr->value; - if($value == "access.AJXP_STREAM_PROVIDER"){ - $deps = array_merge($deps, $pluginService->getStreamWrapperPlugins()); - }else if(strpos($value, "+") !== false){ + } + /** + * Get dependencies + * + * @param AJXP_PluginsService $pluginService + * @return array + */ + public function getActiveDependencies($pluginService) + { + if(!$this->manifestLoaded) return array(); + $deps = array(); + $nodes = $this->xPath->query("dependencies/activePlugin/@pluginName"); + foreach ($nodes as $attr) { + $value = $attr->value; + if ($value == "access.AJXP_STREAM_PROVIDER") { + $deps = array_merge($deps, $pluginService->getStreamWrapperPlugins()); + } else if (strpos($value, "+") !== false) { $typed = $pluginService->getPluginsByType(substr($value, 0, strlen($value)-1)); foreach($typed as $typPlug) $deps[] = $typPlug->getId(); - }else{ - $deps = array_merge($deps, explode("|", $value)); - } - } - return $deps; - } - /** + } else { + $deps = array_merge($deps, explode("|", $value)); + } + } + return $deps; + } + /** * Load the global parameters for this plugin * @return void */ - protected function loadConfigsDefinitions(){ - $params = $this->xPath->query("//server_settings/global_param"); - $this->pluginConf = array(); - foreach ($params as $xmlNode){ - $paramNode = $this->nodeAttrToHash($xmlNode); - $this->pluginConfDefinition[$paramNode["name"]] = $paramNode; - if(isset($paramNode["default"])){ - if($paramNode["type"] == "boolean"){ + protected function loadConfigsDefinitions() + { + $params = $this->xPath->query("//server_settings/global_param"); + $this->pluginConf = array(); + foreach ($params as $xmlNode) { + $paramNode = $this->nodeAttrToHash($xmlNode); + $this->pluginConfDefinition[$paramNode["name"]] = $paramNode; + if (isset($paramNode["default"])) { + if ($paramNode["type"] == "boolean") { $paramNode["default"] = ($paramNode["default"] === "true" ? true: false); - }else if($paramNode["type"] == "integer"){ + } else if ($paramNode["type"] == "integer") { $paramNode["default"] = intval($paramNode["default"]); } - $this->pluginConf[$paramNode["name"]] = $paramNode["default"]; - } - } - } - /** + $this->pluginConf[$paramNode["name"]] = $paramNode["default"]; + } + } + } + /** * Load the default values for this plugin options * @return array */ - protected function loadOptionsDefaults(){ + protected function loadOptionsDefaults() + { $optionsDefaults = array(); $params = $this->xPath->query("//server_settings/param[@default]"); - foreach ($params as $xmlNode){ + foreach ($params as $xmlNode) { $default = $xmlNode->getAttribute("default"); - if($xmlNode->getAttribute("type") == "boolean"){ + if ($xmlNode->getAttribute("type") == "boolean") { $default = ($default === "true" ? true: false); - }else if($xmlNode->getAttribute("type") == "integer"){ + } else if ($xmlNode->getAttribute("type") == "integer") { $default = intval($default); } $optionsDefaults[$xmlNode->getAttribute("name")] = $default; - } + } return $optionsDefaults; - } - /** + } + /** * @return array */ - public function getConfigsDefinitions(){ - return $this->pluginConfDefinition; - } - /** + public function getConfigsDefinitions() + { + return $this->pluginConfDefinition; + } + /** * Load the configs passed as parameter. This method will * + Parse the config definitions and load the default values * + Merge these values with the $configData parameter @@ -566,148 +589,160 @@ public function getConfigsDefinitions(){ * @param array $configData * @return void */ - public function loadConfigs($configData){ - // PARSE DEFINITIONS AND LOAD DEFAULT VALUES - if(!isSet($this->pluginConf)) { - $this->loadConfigsDefinitions(); - } - // MERGE WITH PASSED CONFIGS - $this->pluginConf = array_merge($this->pluginConf, $configData); - - // PUBLISH IF NECESSARY - foreach ($this->pluginConf as $key => $value){ - if(isSet($this->pluginConfDefinition[$key]) && isSet($this->pluginConfDefinition[$key]["expose"]) && $this->pluginConfDefinition[$key]["expose"] == "true"){ - $this->exposeConfigInManifest($key, $value); - } - } + public function loadConfigs($configData) + { + // PARSE DEFINITIONS AND LOAD DEFAULT VALUES + if (!isSet($this->pluginConf)) { + $this->loadConfigsDefinitions(); + } + // MERGE WITH PASSED CONFIGS + $this->pluginConf = array_merge($this->pluginConf, $configData); + + // PUBLISH IF NECESSARY + foreach ($this->pluginConf as $key => $value) { + if (isSet($this->pluginConfDefinition[$key]) && isSet($this->pluginConfDefinition[$key]["expose"]) && $this->pluginConfDefinition[$key]["expose"] == "true") { + $this->exposeConfigInManifest($key, $value); + } + } // ASSIGN SPECIFIC OPTIONS TO PLUGIN KEY - if(isSet($this->pluginConf["AJXP_PLUGIN_ENABLED"])){ + if (isSet($this->pluginConf["AJXP_PLUGIN_ENABLED"])) { $this->enabled = $this->pluginConf["AJXP_PLUGIN_ENABLED"]; } - } + } /** * Return this plugin configs, merged with its associated "core" configs. * @return array */ - public function getConfigs(){ - $core = AJXP_PluginsService::getInstance()->findPlugin("core", $this->type); - if(!empty($core)){ - $coreConfs = $core->getConfigs(); - return array_merge($coreConfs, $this->pluginConf); - }else{ - return $this->pluginConf; - } - } - /** + public function getConfigs() + { + $core = AJXP_PluginsService::getInstance()->findPlugin("core", $this->type); + if (!empty($core)) { + $coreConfs = $core->getConfigs(); + return array_merge($coreConfs, $this->pluginConf); + } else { + return $this->pluginConf; + } + } + /** * Return the file path of the specific class to load * @return array|bool */ - public function getClassFile(){ - $files = $this->xPath->query("class_definition"); - if(!$files->length) return false; - return $this->nodeAttrToHash($files->item(0)); - } + public function getClassFile() + { + $files = $this->xPath->query("class_definition"); + if(!$files->length) return false; + return $this->nodeAttrToHash($files->item(0)); + } /** * @return bool */ - public function manifestLoaded(){ - return $this->manifestLoaded; - } + public function manifestLoaded() + { + return $this->manifestLoaded; + } /** * @return string */ - public function getId(){ - return $this->id; - } + public function getId() + { + return $this->id; + } /** * @return string */ - public function getName(){ - return $this->name; - } + public function getName() + { + return $this->name; + } /** * @return string */ - public function getType(){ - return $this->type; - } + public function getType() + { + return $this->type; + } /** * @return string */ - public function getBaseDir(){ - return $this->baseDir; - } + public function getBaseDir() + { + return $this->baseDir; + } /** * @return array */ - public function getDependencies(){ - return $this->dependencies; - } - /** + public function getDependencies() + { + return $this->dependencies; + } + /** * Detect if this plugin declares a StreamWrapper, and if yes loads it and register the stream. * @param bool $register * @return array|bool */ - public function detectStreamWrapper($register = false){ - if(isSet($this->streamData)){ + public function detectStreamWrapper($register = false) + { + if (isSet($this->streamData)) { if($this->streamData === false) return false; $streamData = $this->streamData; // include wrapper, no other checks needed. include_once(AJXP_INSTALL_PATH."/".$streamData["filename"]); - }else{ + } else { $files = $this->xPath->query("class_stream_wrapper"); - if(!$files->length) { + if (!$files->length) { $this->streamData = false; return false; } $streamData = $this->nodeAttrToHash($files->item(0)); - if(!is_file(AJXP_INSTALL_PATH."/".$streamData["filename"])){ + if (!is_file(AJXP_INSTALL_PATH."/".$streamData["filename"])) { $this->streamData = false; return false; } include_once(AJXP_INSTALL_PATH."/".$streamData["filename"]); - if(!class_exists($streamData["classname"])){ + if (!class_exists($streamData["classname"])) { $this->streamData = false; return false; } $this->streamData = $streamData; } - if($register){ - $pServ = AJXP_PluginsService::getInstance(); - if(!in_array($streamData["protocol"], stream_get_wrappers())){ - stream_wrapper_register($streamData["protocol"], $streamData["classname"]); - $pServ->registerWrapperClass($streamData["protocol"], $streamData["classname"]); - } - } - return $streamData; - } - /** + if ($register) { + $pServ = AJXP_PluginsService::getInstance(); + if (!in_array($streamData["protocol"], stream_get_wrappers())) { + stream_wrapper_register($streamData["protocol"], $streamData["classname"]); + $pServ->registerWrapperClass($streamData["protocol"], $streamData["classname"]); + } + } + return $streamData; + } + /** * Add a name/value pair in the manifest to be published to the world. * @param $configName * @param $configValue * @return void */ - protected function exposeConfigInManifest($configName, $configValue){ - $confBranch = $this->xPath->query("plugin_configs"); - if(!$confBranch->length){ - $configNode = $this->manifestDoc->importNode(new DOMElement("plugin_configs", "")); - $this->manifestDoc->documentElement->appendChild($configNode); - }else{ - $configNode = $confBranch->item(0); - } - $prop = $this->manifestDoc->createElement("property"); - $propValue = $this->manifestDoc->createCDATASection(json_encode($configValue)); - $prop->appendChild($propValue); - $attName = $this->manifestDoc->createAttribute("name"); - $attValue = $this->manifestDoc->createTextNode($configName); - $attName->appendChild($attValue); - $prop->appendChild($attName); - $configNode->appendChild($prop); - $this->reloadXPath(); - } + protected function exposeConfigInManifest($configName, $configValue) + { + $confBranch = $this->xPath->query("plugin_configs"); + if (!$confBranch->length) { + $configNode = $this->manifestDoc->importNode(new DOMElement("plugin_configs", "")); + $this->manifestDoc->documentElement->appendChild($configNode); + } else { + $configNode = $confBranch->item(0); + } + $prop = $this->manifestDoc->createElement("property"); + $propValue = $this->manifestDoc->createCDATASection(json_encode($configValue)); + $prop->appendChild($propValue); + $attName = $this->manifestDoc->createAttribute("name"); + $attValue = $this->manifestDoc->createTextNode($configName); + $attName->appendChild($attValue); + $prop->appendChild($attName); + $configNode->appendChild($prop); + $this->reloadXPath(); + } - public function getPluginInformation(){ + public function getPluginInformation() + { $info = array( "plugin_author" => "", "plugin_uri" => "", @@ -716,12 +751,12 @@ public function getPluginInformation(){ "core_version" => AJXP_VERSION, ); $infoBranch = $this->xPath->query("plugin_info"); - if($infoBranch->length){ - foreach($infoBranch->item(0)->childNodes as $child){ + if ($infoBranch->length) { + foreach ($infoBranch->item(0)->childNodes as $child) { if($child->nodeType != 1) continue; - if($child->nodeName != "core_relation") { + if ($child->nodeName != "core_relation") { $info[$child->nodeName] = $child->nodeValue; - }else{ + } else { if($child->getAttribute("packaged") == "false") $info["core_packaged"] = false; $coreV = $child->getAttribute("tested_version"); if($coreV == "follow") $coreV = AJXP_VERSION; @@ -732,17 +767,18 @@ public function getPluginInformation(){ return $info; } - public function getPluginInformationHTML($defaultAuthor, $defaultUriBase){ + public function getPluginInformationHTML($defaultAuthor, $defaultUriBase) + { $pInfo = $this->getPluginInformation(); $pInfoString = ""; - if(empty($pInfo["plugin_uri"])){ + if (empty($pInfo["plugin_uri"])) { if($pInfo["core_packaged"]) $pInfo["plugin_uri"] = $defaultUriBase.$this->getType()."/".$this->getName()."/"; else $pInfo["plugin_uri"] = "N/A"; } - if($pInfo["plugin_uri"] != "N/A"){ + if ($pInfo["plugin_uri"] != "N/A") { $pInfo["plugin_uri"] = "".$pInfo["plugin_uri"].""; } - if($pInfo["core_packaged"]){ + if ($pInfo["core_packaged"]) { unset($pInfo["plugin_version"]); unset($pInfo["core_version"]); } @@ -755,7 +791,7 @@ public function getPluginInformationHTML($defaultAuthor, $defaultUriBase){ "core_version" => "Core version" ); if(empty($pInfo["plugin_author"])) $pInfo["plugin_author"] = $defaultAuthor; - foreach($pInfo as $k => $v){ + foreach ($pInfo as $k => $v) { $pInfoString .= "
  • ".$humanKeys[$k]."$v
  • "; } return "
      $pInfoString
    "; @@ -764,62 +800,66 @@ public function getPluginInformationHTML($defaultAuthor, $defaultUriBase){ /** * @return void */ - public function reloadXPath(){ - // Relaunch xpath - $this->xPath = new DOMXPath($this->manifestDoc); - } - /** + public function reloadXPath() + { + // Relaunch xpath + $this->xPath = new DOMXPath($this->manifestDoc); + } + /** * @param $mixinName * @return bool */ - public function hasMixin($mixinName){ - return (in_array($mixinName, $this->mixins)); - } - /** + public function hasMixin($mixinName) + { + return (in_array($mixinName, $this->mixins)); + } + /** * Check if the plugin declares mixins, and load them using AJXP_PluginsService::patchPluginWithMixin method * @return void */ - protected function loadMixins(){ - - $attr = $this->manifestDoc->documentElement->getAttribute("mixins"); - if($attr != ""){ - $this->mixins = explode(",", $attr); - foreach ($this->mixins as $mixin){ - AJXP_PluginsService::getInstance()->patchPluginWithMixin($this, $this->manifestDoc, $mixin); - } - } - } - - /** - * Transform a simple node and its attributes to a HashTable - * - * @param DOMNode $node + protected function loadMixins() + { + $attr = $this->manifestDoc->documentElement->getAttribute("mixins"); + if ($attr != "") { + $this->mixins = explode(",", $attr); + foreach ($this->mixins as $mixin) { + AJXP_PluginsService::getInstance()->patchPluginWithMixin($this, $this->manifestDoc, $mixin); + } + } + } + + /** + * Transform a simple node and its attributes to a HashTable + * + * @param DOMNode $node * @return array - */ - protected function nodeAttrToHash($node){ - $hash = array(); - $attributes = $node->attributes; - if($attributes!=null){ - foreach ($attributes as $domAttr){ - $hash[$domAttr->name] = $domAttr->value; - } - } - return $hash; - } - /** - * Compare two nodes at first level (nodename and attributes) - * - * @param DOMNode $node1 - * @param DOMNode $node2 + */ + protected function nodeAttrToHash($node) + { + $hash = array(); + $attributes = $node->attributes; + if ($attributes!=null) { + foreach ($attributes as $domAttr) { + $hash[$domAttr->name] = $domAttr->value; + } + } + return $hash; + } + /** + * Compare two nodes at first level (nodename and attributes) + * + * @param DOMNode $node1 + * @param DOMNode $node2 * @return bool - */ - protected function nodesEqual($node1, $node2){ - if($node1->nodeName != $node2->nodeName) return false; - $hash1 = $this->nodeAttrToHash($node1); - $hash2 = $this->nodeAttrToHash($node2); - foreach($hash1 as $name=>$value){ - if(!isSet($hash2[$name]) || $hash2[$name] != $value) return false; - } - return true; - } -} \ No newline at end of file + */ + protected function nodesEqual($node1, $node2) + { + if($node1->nodeName != $node2->nodeName) return false; + $hash1 = $this->nodeAttrToHash($node1); + $hash2 = $this->nodeAttrToHash($node2); + foreach ($hash1 as $name=>$value) { + if(!isSet($hash2[$name]) || $hash2[$name] != $value) return false; + } + return true; + } +} diff --git a/core/src/core/classes/class.AJXP_PluginsService.php b/core/src/core/classes/class.AJXP_PluginsService.php index 77c78146a1..042be95651 100644 --- a/core/src/core/classes/class.AJXP_PluginsService.php +++ b/core/src/core/classes/class.AJXP_PluginsService.php @@ -25,7 +25,8 @@ * @package AjaXplorer * @subpackage Core */ -class AJXP_PluginsService{ +class AJXP_PluginsService +{ private static $instance; private $registry = array(); private $required_files = array(); @@ -49,12 +50,13 @@ class AJXP_PluginsService{ * @param AbstractConfDriver $confStorage * @param bool $rewriteCache Force a cache rewriting */ - public function loadPluginsRegistry($pluginFolder, $confStorage, $rewriteCache = false){ - if(!$rewriteCache && (!defined("AJXP_SKIP_CACHE") || AJXP_SKIP_CACHE === false)){ + public function loadPluginsRegistry($pluginFolder, $confStorage, $rewriteCache = false) + { + if (!$rewriteCache && (!defined("AJXP_SKIP_CACHE") || AJXP_SKIP_CACHE === false)) { $reqs = AJXP_Utils::loadSerialFile(AJXP_PLUGINS_REQUIRES_FILE); - if(count($reqs)){ - foreach ($reqs as $filename){ - if(!is_file($filename)){ + if (count($reqs)) { + foreach ($reqs as $filename) { + if (!is_file($filename)) { // CACHE IS OUT OF SYNC WITH REQUIRES $this->loadPluginsRegistry($pluginFolder, $confStorage, true); return; @@ -64,9 +66,9 @@ public function loadPluginsRegistry($pluginFolder, $confStorage, $rewriteCache = $res = AJXP_Utils::loadSerialFile(AJXP_PLUGINS_CACHE_FILE); $this->registry = $res; // Refresh streamWrapperPlugins - foreach ($this->registry as $pType => $plugs){ - foreach ($plugs as $plugin){ - if(method_exists($plugin, "detectStreamWrapper") && $plugin->detectStreamWrapper(false) !== false){ + foreach ($this->registry as $pType => $plugs) { + foreach ($plugs as $plugin) { + if (method_exists($plugin, "detectStreamWrapper") && $plugin->detectStreamWrapper(false) !== false) { $this->streamWrapperPlugins[] = $plugin->getId(); } } @@ -74,22 +76,22 @@ public function loadPluginsRegistry($pluginFolder, $confStorage, $rewriteCache = return ; } } - if(is_string($pluginFolder)){ + if (is_string($pluginFolder)) { $pluginFolder = array($pluginFolder); } $this->confStorage = $confStorage; $pluginsPool = array(); - foreach($pluginFolder as $sourceFolder){ + foreach ($pluginFolder as $sourceFolder) { $handler = @opendir($sourceFolder); - if($handler){ + if ($handler) { while ( ($item = readdir($handler)) !==false) { if($item == "." || $item == ".." || !@is_dir($sourceFolder."/".$item) || strstr($item,".")===false) continue ; $plugin = new AJXP_Plugin($item, $sourceFolder."/".$item); $plugin->loadManifest(); - if($plugin->manifestLoaded()){ + if ($plugin->manifestLoaded()) { $pluginsPool[$plugin->getId()] = $plugin; - if(method_exists($plugin, "detectStreamWrapper") && $plugin->detectStreamWrapper(false) !== false){ + if (method_exists($plugin, "detectStreamWrapper") && $plugin->detectStreamWrapper(false) !== false) { $this->streamWrapperPlugins[] = $plugin->getId(); } } @@ -97,16 +99,16 @@ public function loadPluginsRegistry($pluginFolder, $confStorage, $rewriteCache = closedir($handler); } } - if(count($pluginsPool)){ + if (count($pluginsPool)) { $this->checkDependencies($pluginsPool); - foreach ($pluginsPool as $plugin){ + foreach ($pluginsPool as $plugin) { $this->recursiveLoadPlugin($plugin, $pluginsPool); } } - if(!defined("AJXP_SKIP_CACHE") || AJXP_SKIP_CACHE === false){ + if (!defined("AJXP_SKIP_CACHE") || AJXP_SKIP_CACHE === false) { AJXP_Utils::saveSerialFile(AJXP_PLUGINS_REQUIRES_FILE, $this->required_files, false, false); AJXP_Utils::saveSerialFile(AJXP_PLUGINS_CACHE_FILE, $this->registry, false, false); - if(is_file(AJXP_PLUGINS_QUERIES_CACHE)){ + if (is_file(AJXP_PLUGINS_QUERIES_CACHE)) { @unlink(AJXP_PLUGINS_QUERIES_CACHE); } } @@ -118,25 +120,26 @@ public function loadPluginsRegistry($pluginFolder, $confStorage, $rewriteCache = * @param AJXP_Plugin $plugin * @param array $pluginsPool */ - private function recursiveLoadPlugin($plugin, $pluginsPool){ - if($plugin->loadingState!=""){ + private function recursiveLoadPlugin($plugin, $pluginsPool) + { + if ($plugin->loadingState!="") { return ; } $dependencies = $plugin->getDependencies(); $plugin->loadingState = "lock"; - foreach ($dependencies as $dependencyId){ - if(isSet($pluginsPool[$dependencyId])){ + foreach ($dependencies as $dependencyId) { + if (isSet($pluginsPool[$dependencyId])) { $this->recursiveLoadPlugin($pluginsPool[$dependencyId], $pluginsPool); - }else if(strpos($dependencyId, "+") !== false){ - foreach(array_keys($pluginsPool) as $pId){ - if(strpos($pId, str_replace("+", "", $dependencyId)) === 0){ + } else if (strpos($dependencyId, "+") !== false) { + foreach (array_keys($pluginsPool) as $pId) { + if (strpos($pId, str_replace("+", "", $dependencyId)) === 0) { $this->recursiveLoadPlugin($pluginsPool[$pId], $pluginsPool); } } } } $plugType = $plugin->getType(); - if(!isSet($this->registry[$plugType])){ + if (!isSet($this->registry[$plugType])) { $this->registry[$plugType] = array(); } $plugin = $this->instanciatePluginClass($plugin); @@ -152,11 +155,12 @@ private function recursiveLoadPlugin($plugin, $pluginsPool){ * @param array $sortedPlugins * @return bool|void */ - private function cachePlugSort($sortedPlugins){ + private function cachePlugSort($sortedPlugins) + { if(!AJXP_PLUGINS_CACHE_FILE) return false; $indexes = array(); $i = 0; - foreach ($sortedPlugins as $plugin){ + foreach ($sortedPlugins as $plugin) { $indexes[$i] = $plugin->getId(); $i++; } @@ -170,34 +174,37 @@ private function cachePlugSort($sortedPlugins){ * @param array $sortedPlugins * @return mixed */ - private function loadPlugCache($sortedPlugins){ + private function loadPlugCache($sortedPlugins) + { if(!AJXP_PLUGINS_CACHE_FILE) return false; $cache = AJXP_Utils::loadSerialFile(AJXP_PLUGINS_CACHE_FILE); if(!count($cache)) return false; // Break if one plugin is not present in cache - foreach ($sortedPlugins as $index => $plugin){ - if(!in_array($plugin->getId(), $cache)){return false;} + foreach ($sortedPlugins as $index => $plugin) { + if (!in_array($plugin->getId(), $cache)) {return false;} } $sorted = array(); - foreach ($cache as $id => $plugId){ + foreach ($cache as $id => $plugId) { // Walk the cache and add the plugins in right order. - if(isSet($sortedPlugins[$plugId])){ + if (isSet($sortedPlugins[$plugId])) { $sorted[] = $sortedPlugins[$plugId]; } } return $sorted; } - public function loadFromPluginQueriesCache($key){ + public function loadFromPluginQueriesCache($key) + { if(AJXP_SKIP_CACHE) return null; $test = AJXP_Utils::loadSerialFile(AJXP_PLUGINS_QUERIES_CACHE); - if(!empty($test) && is_array($test) && isset($test[$key])){ + if (!empty($test) && is_array($test) && isset($test[$key])) { return $test[$key]; } return null; } - public function storeToPluginQueriesCache($key, $value){ + public function storeToPluginQueriesCache($key, $value) + { if(AJXP_SKIP_CACHE) return; $test = AJXP_Utils::loadSerialFile(AJXP_PLUGINS_QUERIES_CACHE); if(!is_array($test)) $test = array(); @@ -211,7 +218,8 @@ public function storeToPluginQueriesCache($key, $value){ * @param array $pluginOptions * @return AJXP_Plugin */ - public function softLoad($pluginId, $pluginOptions){ + public function softLoad($pluginId, $pluginOptions) + { $plugin = new AJXP_Plugin($pluginId, AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/".$pluginId); $plugin->loadManifest(); $plugin = $this->instanciatePluginClass($plugin); @@ -226,18 +234,19 @@ public function softLoad($pluginId, $pluginOptions){ * @param AJXP_Plugin $plugin * @return AJXP_Plugin */ - private function instanciatePluginClass($plugin){ + private function instanciatePluginClass($plugin) + { $definition = $plugin->getClassFile(); if(!$definition) return $plugin; $filename = AJXP_INSTALL_PATH."/".$definition["filename"]; $className = $definition["classname"]; - if(is_file($filename)){ + if (is_file($filename)) { require_once($filename); $newPlugin = new $className($plugin->getId(), $plugin->getBaseDir()); $newPlugin->loadManifest(); $this->required_files[] = $filename; return $newPlugin; - }else{ + } else { return $plugin; } } @@ -246,19 +255,20 @@ private function instanciatePluginClass($plugin){ * @param $arrayToSort * @return */ - private function checkDependencies(&$arrayToSort){ + private function checkDependencies(&$arrayToSort) + { // First make sure that the given dependencies are present - foreach ($arrayToSort as $plugId => $plugObject){ + foreach ($arrayToSort as $plugId => $plugObject) { $plugObject->updateDependencies($this); $dependencies = $plugObject->getDependencies(); if(!count($dependencies)) continue;// return ; $found = false; - foreach ($dependencies as $requiredPlugId){ - if( strpos($requiredPlugId, "+") !== false || isSet($arrayToSort[$requiredPlugId])){ + foreach ($dependencies as $requiredPlugId) { + if ( strpos($requiredPlugId, "+") !== false || isSet($arrayToSort[$requiredPlugId])) { $found = true; break; } } - if(!$found){ + if (!$found) { unset($arrayToSort[$plugId]); } } @@ -273,54 +283,56 @@ private function checkDependencies(&$arrayToSort){ * @internal param String $pluginB * @return integer */ - public static function sortByDependencyIds($pluginIdA, $pluginIdB){ + public static function sortByDependencyIds($pluginIdA, $pluginIdB) + { if($pluginIdA == $pluginIdB) return 0; $pluginA = self::findPluginById($pluginIdA); $pluginB = self::findPluginById($pluginIdB); if($pluginA == null || $pluginB == null) return 0; - if($pluginA->dependsOn($pluginIdB)) { + if ($pluginA->dependsOn($pluginIdB)) { return 1; } - if($pluginB->dependsOn($pluginIdA)) { + if ($pluginB->dependsOn($pluginIdA)) { return -1; } return 0; } - public function getOrderByDependency($plugins, $withStatus = true){ + public function getOrderByDependency($plugins, $withStatus = true) + { $orders = array(); $keys = array(); $unkowns = array(); - if($withStatus){ - foreach($plugins as $pid => $status){ + if ($withStatus) { + foreach ($plugins as $pid => $status) { if($status) $keys[] = $pid; } - }else{ + } else { $keys = array_keys($plugins); } $result = array(); - while(count($keys) > 0){ + while (count($keys) > 0) { $test = array_shift($keys); $testObject = $this->getPluginById($test); $deps = $testObject->getActiveDependencies(self::getInstance()); - if(!count($deps)){ + if (!count($deps)) { $result[] = $test; continue; } $found = false; $inOriginalPlugins = false; - foreach($deps as $depId){ - if(in_array($depId, $result)) { + foreach ($deps as $depId) { + if (in_array($depId, $result)) { $found = true; break; } - if(!$inOriginalPlugins && array_key_exists($depId, $plugins) && (!$withStatus || $plugins[$depId] == true)){ + if (!$inOriginalPlugins && array_key_exists($depId, $plugins) && (!$withStatus || $plugins[$depId] == true)) { $inOriginalPlugins = true; } } - if($found){ + if ($found) { $result[] = $test; - }else{ + } else { if($inOriginalPlugins) $keys[] = $test; else { unset($plugins[$test]); @@ -339,7 +351,8 @@ public function getOrderByDependency($plugins, $withStatus = true){ * @param string $type * @return array */ - public function getPluginsByType($type){ + public function getPluginsByType($type) + { if(isSet($this->registry[$type])) return $this->registry[$type]; else return array(); } @@ -350,7 +363,8 @@ public function getPluginsByType($type){ * @param string $pluginId * @return AJXP_Plugin */ - public function getPluginById($pluginId){ + public function getPluginById($pluginId) + { $split = explode(".", $pluginId); return $this->getPluginByTypeName($split[0], $split[1]); } @@ -360,9 +374,10 @@ public function getPluginById($pluginId){ * @param string $pluginId * @return void */ - public function removePluginById($pluginId){ + public function removePluginById($pluginId) + { $split = explode(".", $pluginId); - if(isSet($this->registry[$split[0]]) && isSet($this->registry[$split[0]][$split[1]])){ + if (isSet($this->registry[$split[0]]) && isSet($this->registry[$split[0]][$split[1]])) { unset($this->registry[$split[0]][$split[1]]); } } @@ -374,13 +389,14 @@ public function removePluginById($pluginId){ * or it's the task of the core class to load the necessary plugin(s) of this type. * @return void */ - public function initActivePlugins(){ + public function initActivePlugins() + { $detected = $this->getDetectedPlugins(); $toActivate = array(); - foreach ($detected as $pType => $pObjects){ + foreach ($detected as $pType => $pObjects) { $coreP = $this->findPlugin("core", $pType); if($coreP !== false && !isSet($coreP->AUTO_LOAD_TYPE)) continue; - foreach ($pObjects as $pName => $pObject){ + foreach ($pObjects as $pName => $pObject) { $toActivate[$pObject->getId()] = $pObject ; } } @@ -388,11 +404,11 @@ public function initActivePlugins(){ foreach ($o as $id) { $pObject = $toActivate[$id]; $pObject->init(array()); - try{ + try { $pObject->performChecks(); if(!$pObject->isEnabled()) continue; $this->setPluginActiveInst($pObject->getType(), $pObject->getName(), true); - }catch (Exception $e){ + } catch (Exception $e) { //$this->errors[$pName] = "[$pName] ".$e->getMessage(); } @@ -408,7 +424,8 @@ public function initActivePlugins(){ * @param AJXP_Plugin $updateInstance * @return void */ - public static function setPluginActive($type, $name, $active=true, $updateInstance = null){ + public static function setPluginActive($type, $name, $active=true, $updateInstance = null) + { self::getInstance()->setPluginActiveInst($type, $name, $active, $updateInstance); } /** @@ -419,30 +436,31 @@ public static function setPluginActive($type, $name, $active=true, $updateInstan * @param AJXP_Plugin $updateInstance * @return void */ - public function setPluginActiveInst($type, $name, $active=true, $updateInstance = null){ - if($active){ + public function setPluginActiveInst($type, $name, $active=true, $updateInstance = null) + { + if ($active) { // Check active plugin dependencies $plug = $this->getPluginById($type.".".$name); if(!$plug || !$plug->isEnabled()) return; $deps = $plug->getActiveDependencies($this); - if(count($deps)){ + if (count($deps)) { $found = false; - foreach ($deps as $dep){ - if(isSet($this->activePlugins[$dep]) && $this->activePlugins[$dep] !== false){ + foreach ($deps as $dep) { + if (isSet($this->activePlugins[$dep]) && $this->activePlugins[$dep] !== false) { $found = true; break; } } - if(!$found){ + if (!$found) { $this->activePlugins[$type.".".$name] = false; return ; } } } $this->activePlugins[$type.".".$name] = $active; - if(isSet($updateInstance) && isSet($this->registry[$type][$name])){ + if (isSet($updateInstance) && isSet($this->registry[$type][$name])) { $this->registry[$type][$name] = $updateInstance; } - if(isSet($this->xmlRegistry) && !$this->tmpDeferRegistryBuild){ + if (isSet($this->xmlRegistry) && !$this->tmpDeferRegistryBuild) { $this->buildXmlRegistry(($this->registryVersion == "extended")); } } @@ -453,10 +471,11 @@ public function setPluginActiveInst($type, $name, $active=true, $updateInstance * @param AJXP_Plugin $updateInstance * @return void */ - public function setPluginUniqueActiveForType($type, $name, $updateInstance = null){ + public function setPluginUniqueActiveForType($type, $name, $updateInstance = null) + { $typePlugs = $this->getPluginsByType($type); $this->tmpDeferRegistryBuild = true; - foreach($typePlugs as $plugName => $plugObject){ + foreach ($typePlugs as $plugName => $plugObject) { $this->setPluginActiveInst($type, $plugName, false); } $this->tmpDeferRegistryBuild = false; @@ -466,7 +485,8 @@ public function setPluginUniqueActiveForType($type, $name, $updateInstance = nul * Retrieve the whole active plugins list * @return array */ - public function getActivePlugins(){ + public function getActivePlugins() + { return $this->activePlugins; } /** @@ -475,13 +495,14 @@ public function getActivePlugins(){ * @param bool $unique * @return array|bool */ - public function getActivePluginsForType($type, $unique = false){ + public function getActivePluginsForType($type, $unique = false) + { $acts = array(); - foreach($this->activePlugins as $plugId => $active){ + foreach ($this->activePlugins as $plugId => $active) { if(!$active) continue; list($pT,$pN) = explode(".", $plugId); - if($pT == $type && isset($this->registry[$pT][$pN])){ - if($unique) { + if ($pT == $type && isset($this->registry[$pT][$pN])) { + if ($unique) { return $this->registry[$pT][$pN]; break; } @@ -497,21 +518,24 @@ public function getActivePluginsForType($type, $unique = false){ * @param $type * @return array|bool */ - public function getUniqueActivePluginForType($type){ + public function getUniqueActivePluginForType($type) + { return $this->getActivePluginsForType($type, true); } /** * All the plugins registry, active or not * @return array */ - public function getDetectedPlugins(){ + public function getDetectedPlugins() + { return $this->registry; } /** * All the plugins that declare a stream wrapper * @return array */ - public function getStreamWrapperPlugins(){ + public function getStreamWrapperPlugins() + { return $this->streamWrapperPlugins; } /** @@ -520,7 +544,8 @@ public function getStreamWrapperPlugins(){ * @param string $wrapperClassName * @return void */ - public function registerWrapperClass($protocol, $wrapperClassName){ + public function registerWrapperClass($protocol, $wrapperClassName) + { $this->registeredWrappers[$protocol] = $wrapperClassName; } @@ -529,14 +554,16 @@ public function registerWrapperClass($protocol, $wrapperClassName){ * @param $protocol * @return */ - public function getWrapperClassName($protocol){ + public function getWrapperClassName($protocol) + { return $this->registeredWrappers[$protocol]; } /** * The protocol/classnames table * @return array */ - public function getRegisteredWrappers(){ + public function getRegisteredWrappers() + { return $this->registeredWrappers; } /** @@ -545,15 +572,16 @@ public function getRegisteredWrappers(){ * @param bool $extendedVersion Will be passed to the plugin, for optimization purpose. * @return void */ - public function buildXmlRegistry($extendedVersion = true){ + public function buildXmlRegistry($extendedVersion = true) + { $actives = $this->getActivePlugins(); $reg = new DOMDocument(); $reg->loadXML(""); - foreach($actives as $activeName=>$status){ + foreach ($actives as $activeName=>$status) { if($status === false) continue; $plug = $this->getPluginById($activeName); $contribs = $plug->getRegistryContributions($extendedVersion); - foreach($contribs as $contrib){ + foreach ($contribs as $contrib) { $parent = $contrib->nodeName; $nodes = $contrib->childNodes; if(!$nodes->length) continue; @@ -571,9 +599,10 @@ public function buildXmlRegistry($extendedVersion = true){ * @param bool $extendedVersion * @return DOMDocument The registry */ - public static function getXmlRegistry($extendedVersion = true){ + public static function getXmlRegistry($extendedVersion = true) + { $self = self::getInstance(); - if(!isSet($self->xmlRegistry) || ($self->registryVersion == "light" && $extendedVersion)){ + if (!isSet($self->xmlRegistry) || ($self->registryVersion == "light" && $extendedVersion)) { $self->buildXmlRegistry( $extendedVersion ); $self->registryVersion = ($extendedVersion ? "extended":"light"); } @@ -585,7 +614,8 @@ public static function getXmlRegistry($extendedVersion = true){ * @param $registry * @return void */ - public static function updateXmlRegistry($registry){ + public static function updateXmlRegistry($registry) + { $self = self::getInstance(); $self->xmlRegistry = $registry; } @@ -596,10 +626,10 @@ public static function updateXmlRegistry($registry){ * @param DOMDocument $manifestDoc * @param String $mixinName */ - public function patchPluginWithMixin(&$plugin, &$manifestDoc, $mixinName){ - + public function patchPluginWithMixin(&$plugin, &$manifestDoc, $mixinName) + { // Load behaviours if not already - if(!isSet($this->mixinsDoc)){ + if (!isSet($this->mixinsDoc)) { $this->mixinsDoc = new DOMDocument(); $this->mixinsDoc->load(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/core.ajaxplorer/ajxp_mixins.xml"); $this->mixinsXPath = new DOMXPath($this->mixinsDoc); @@ -608,7 +638,7 @@ public function patchPluginWithMixin(&$plugin, &$manifestDoc, $mixinName){ $nodeList = $this->mixinsXPath->query($mixinName); if(!$nodeList->length) return; $mixinNode = $nodeList->item(0); - foreach($mixinNode->childNodes as $child){ + foreach ($mixinNode->childNodes as $child) { if($child->nodeType != XML_ELEMENT_NODE) continue; $uuidAttr = $child->getAttribute("uuidAttr") OR "name"; $this->mergeNodes($manifestDoc, $child->nodeName, $uuidAttr, $child->childNodes, true); @@ -625,26 +655,27 @@ public function patchPluginWithMixin(&$plugin, &$manifestDoc, $mixinName){ * @param boolean $limitToActivePlugins Whether to search only in active plugins or in all plugins * @return DOMNode[] */ - public static function searchAllManifests($query, $stringOrNodeFormat = "string", $limitToActivePlugins = false, $limitToEnabledPlugins = false, $loadExternalFiles = false){ + public static function searchAllManifests($query, $stringOrNodeFormat = "string", $limitToActivePlugins = false, $limitToEnabledPlugins = false, $loadExternalFiles = false) + { $buffer = ""; $nodes = array(); $self = self::getInstance(); - foreach ($self->registry as $plugType){ - foreach ($plugType as $plugName => $plugObject){ - if($limitToActivePlugins){ + foreach ($self->registry as $plugType) { + foreach ($plugType as $plugName => $plugObject) { + if ($limitToActivePlugins) { $plugId = $plugObject->getId(); - if($limitToActivePlugins && (!isSet($self->activePlugins[$plugId]) || $self->activePlugins[$plugId] === false)){ + if ($limitToActivePlugins && (!isSet($self->activePlugins[$plugId]) || $self->activePlugins[$plugId] === false)) { continue; } } - if($limitToEnabledPlugins){ + if ($limitToEnabledPlugins) { if(!$plugObject->isEnabled()) continue; } $res = $plugObject->getManifestRawContent($query, $stringOrNodeFormat, $loadExternalFiles); - if($stringOrNodeFormat == "string"){ + if ($stringOrNodeFormat == "string") { $buffer .= $res; - }else{ - foreach ($res as $node){ + } else { + foreach ($res as $node) { $nodes[] = $node; } } @@ -663,38 +694,39 @@ public static function searchAllManifests($query, $stringOrNodeFormat = "string" * @param bool $doNotOverrideChildren * @return void */ - protected function mergeNodes(&$original, $parentName, $uuidAttr, $childrenNodes, $doNotOverrideChildren = false){ + protected function mergeNodes(&$original, $parentName, $uuidAttr, $childrenNodes, $doNotOverrideChildren = false) + { // find or create parent $parentSelection = $original->getElementsByTagName($parentName); - if($parentSelection->length){ + if ($parentSelection->length) { $parentNode = $parentSelection->item(0); $xPath = new DOMXPath($original); - foreach($childrenNodes as $child){ + foreach ($childrenNodes as $child) { if($child->nodeType != XML_ELEMENT_NODE) continue; - if($child->getAttribute($uuidAttr) == "*"){ + if ($child->getAttribute($uuidAttr) == "*") { $query = $parentName.'/'.$child->nodeName; - }else{ + } else { $query = $parentName.'/'.$child->nodeName.'[@'.$uuidAttr.' = "'.$child->getAttribute($uuidAttr).'"]'; } $childrenSel = $xPath->query($query); - if($childrenSel->length){ + if ($childrenSel->length) { if($doNotOverrideChildren) continue; - foreach ($childrenSel as $existingNode){ + foreach ($childrenSel as $existingNode) { // Clone as many as needed $clone = $original->importNode($child, true); $this->mergeChildByTagName($clone, $existingNode); } - }else{ + } else { $clone = $original->importNode($child, true); $parentNode->appendChild($clone); } } - }else{ + } else { //create parentNode and append children - if($childrenNodes->length){ + if ($childrenNodes->length) { $parentNode = $original->importNode($childrenNodes->item(0)->parentNode, true); $original->documentElement->appendChild($parentNode); - }else{ + } else { $parentNode = $original->createElement($parentName); $original->documentElement->appendChild($parentNode); } @@ -706,28 +738,29 @@ protected function mergeNodes(&$original, $parentName, $uuidAttr, $childrenNodes * @param $old * @return */ - protected function mergeChildByTagName($new, &$old){ - if(!$this->hasElementChild($new) || !$this->hasElementChild($old)){ + protected function mergeChildByTagName($new, &$old) + { + if (!$this->hasElementChild($new) || !$this->hasElementChild($old)) { $old->parentNode->replaceChild($new, $old); return; } - foreach($new->childNodes as $newChild){ + foreach ($new->childNodes as $newChild) { if($newChild->nodeType != XML_ELEMENT_NODE) continue; $found = null; - foreach($old->childNodes as $oldChild){ + foreach ($old->childNodes as $oldChild) { if($oldChild->nodeType != XML_ELEMENT_NODE) continue; - if($oldChild->nodeName == $newChild->nodeName){ + if ($oldChild->nodeName == $newChild->nodeName) { $found = $oldChild; } } - if($found != null){ - if($newChild->nodeName == "post_processing" || $newChild->nodeName == "pre_processing"){ + if ($found != null) { + if ($newChild->nodeName == "post_processing" || $newChild->nodeName == "pre_processing") { $old->appendChild($newChild->cloneNode(true)); - }else{ + } else { $this->mergeChildByTagName($newChild, $found); } - }else{ + } else { // CloneNode or it's messing with the current foreach loop. $old->appendChild($newChild->cloneNode(true)); } @@ -739,9 +772,10 @@ protected function mergeChildByTagName($new, &$old){ * @param $node * @return bool */ - private function hasElementChild($node){ + private function hasElementChild($node) + { if(!$node->hasChildNodes()) return false; - foreach($node->childNodes as $child){ + foreach ($node->childNodes as $child) { if($child->nodeType == XML_ELEMENT_NODE) return true; } return false; @@ -752,10 +786,11 @@ private function hasElementChild($node){ * @param string $plugName * @return AJXP_Plugin */ - public function getPluginByTypeName($plugType, $plugName){ - if(isSet($this->registry[$plugType]) && isSet($this->registry[$plugType][$plugName])){ + public function getPluginByTypeName($plugType, $plugName) + { + if (isSet($this->registry[$plugType]) && isSet($this->registry[$plugType][$plugName])) { return $this->registry[$plugType][$plugName]; - }else{ + } else { return false; } } @@ -766,7 +801,8 @@ public function getPluginByTypeName($plugType, $plugName){ * @param string $name * @return AJXP_Plugin */ - public static function findPlugin($type, $name){ + public static function findPlugin($type, $name) + { $instance = self::getInstance(); return $instance->getPluginByTypeName($type, $name); } @@ -777,11 +813,13 @@ public static function findPlugin($type, $name){ * @param $id * @return AJXP_Plugin */ - public static function findPluginById($id){ + public static function findPluginById($id) + { return self::getInstance()->getPluginById($id); } - private function __construct(){ + private function __construct() + { } /** * Singleton method @@ -790,7 +828,7 @@ private function __construct(){ */ public static function getInstance() { - if(!isSet(self::$instance)){ + if (!isSet(self::$instance)) { $c = __CLASS__; self::$instance = new $c; } @@ -801,4 +839,3 @@ public function __clone() trigger_error("Cannot clone me, i'm a singleton!", E_USER_ERROR); } } -?> \ No newline at end of file diff --git a/core/src/core/classes/class.AJXP_Role.php b/core/src/core/classes/class.AJXP_Role.php index 40b0dac171..b73a710fb6 100644 --- a/core/src/core/classes/class.AJXP_Role.php +++ b/core/src/core/classes/class.AJXP_Role.php @@ -1,417 +1,440 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die('Access not allowed'); - -define('AJXP_VALUE_CLEAR', "AJXP_VALUE_CLEAR"); -define('AJXP_REPO_SCOPE_ALL',"AJXP_REPO_SCOPE_ALL"); -define('AJXP_REPO_SCOPE_SHARED',"AJXP_REPO_SCOPE_SHARED"); -define('AJXP_PLUGINS_SCOPE_ALL',"plugin_all"); - -/** - * @package AjaXplorer - * @subpackage Core - */ -class AJXP_Role implements AjxpGroupPathProvider -{ - - protected $groupPath; - protected $roleId; - protected $roleLabel; - - protected $acls = array(); - protected $parameters = array(); - protected $actions = array(); - protected $autoApplies = array(); - - public function __construct($id){ - $this->roleId = $id; - } - - public function migrateDeprectated($repositoriesList, AjxpRole $oldRole){ - $repositoriesList["ajxp.all"] = ""; - foreach($repositoriesList as $repoId => $repoObject){ - $right = $oldRole->getRight($repoId); - if(!empty($right)) $this->setAcl($repoId, $right); - $actions = $oldRole->getSpecificActionsRights($repoId); - if(count($actions)){ - foreach($actions as $act => $status){ - if($repoId == "ajxp.all"){ - $this->setActionState(AJXP_PLUGINS_SCOPE_ALL, $act, AJXP_REPO_SCOPE_ALL, $status); - }else{ - $this->setActionState(AJXP_PLUGINS_SCOPE_ALL, $act, $repoId, $status); - } - } - } - } - $this->setGroupPath($oldRole->getGroupPath()); - if($oldRole->isDefault()){ - $this->setAutoApplies(array("all")); - } - } - - public function isGroupRole(){ - return strpos($this->roleId, "AJXP_GRP_") === 0; - } - public function isUserRole(){ - return strpos($this->roleId, "AJXP_USER_") === 0; - } - - - /** - * Whether this role can read the given repo - * @param string $repositoryId Repository ID - * @return bool - */ - function canRead($repositoryId){ - $right = $this->getAcl($repositoryId); - if($right == "rw" || $right == "r") return true; - return false; - } - - /** - * Whether this role can write the given repo - * @param string $repositoryId Repository ID - * @return bool - */ - function canWrite($repositoryId){ - $right = $this->getAcl($repositoryId); - if($right == "rw" || $right == "w") return true; - return false; - } - - - /** - * @param string $repositoryId - * @param string $rightString - * @return void - */ - public function setAcl($repositoryId, $rightString){ - if(empty($rightString)){ - if(isSet($this->acls[$repositoryId])) unset($this->acls[$repositoryId]); - }else{ - $this->acls[$repositoryId] = $rightString; - } - return; - } - /** - * @param string $repositoryId - * @return string - */ - public function getAcl($repositoryId){ - if(isSet($this->acls[$repositoryId])) { - return $this->acls[$repositoryId]; - } - return ""; - } - /** - * @return array Associative array[REPO_ID] => RIGHT_STRING (r / w / rw / AJXP_VALUE_CLEAR) - */ - public function listAcls(){ - return $this->acls; - } - - public function clearAcls(){ - $this->acls = array(); - } - - /** - * Send all role informations as an associative array - * @return array - */ - public function getDataArray(){ - $roleData = array(); - $roleData["ACL"] = $this->listAcls(); - $roleData["ACTIONS"] = $this->listActionsStates(); - $roleData["PARAMETERS"] = $this->listParameters(); - $roleData["APPLIES"] = $this->listAutoApplies(); - return $roleData; - } - - /** - * Update the role information from an associative array - * @see getDataArray() - * @param array $roleData - */ - public function bunchUpdate($roleData){ - - $this->acls = $roleData["ACL"]; - $this->actions = $roleData["ACTIONS"]; - $this->parameters = $roleData["PARAMETERS"]; - $this->autoApplies = $roleData["APPLIES"]; - - } - - - /** - * @param string $pluginId - * @param string $parameterName - * @param mixed $parameterValue can be AJXP_VALUE_CLEAR (force clear previous), or empty string for clearing value (apply previous). - * @param string|null $repositoryId - */ - public function setParameterValue($pluginId, $parameterName, $parameterValue, $repositoryId = null){ - if($repositoryId === null) $repositoryId = AJXP_REPO_SCOPE_ALL; - if(empty($parameterValue) && $parameterValue !== false){ - if(isSet($this->parameters[$repositoryId][$pluginId][$parameterName])){ - unset($this->parameters[$repositoryId][$pluginId][$parameterName]); - if(!count($this->parameters[$repositoryId][$pluginId])) unset($this->parameters[$repositoryId][$pluginId]); - if(!count($this->parameters[$repositoryId])) unset($this->parameters[$repositoryId]); - } - }else{ - $this->parameters = $this->setArrayValue($this->parameters, $repositoryId, $pluginId, $parameterName, $parameterValue); - } - return; - } - - /** - * @param string $pluginId - * @param string $parameterName - * @param string $repositoryId - * @param mixed $parameterValue - * @return mixed - */ - public function filterParameterValue($pluginId, $parameterName, $repositoryId, $parameterValue){ - if(isSet($this->parameters[AJXP_REPO_SCOPE_ALL][$pluginId][$parameterName])){ - $v = $this->parameters[AJXP_REPO_SCOPE_ALL][$pluginId][$parameterName]; - if($v === AJXP_VALUE_CLEAR) return ""; - else return $v; - } - if(isSet($this->parameters[$repositoryId][$pluginId][$parameterName])){ - $v = $this->parameters[$repositoryId][$pluginId][$parameterName]; - if($v === AJXP_VALUE_CLEAR) return ""; - else return $v; - } - return $parameterValue; - } - /** - * @return array Associative array of parameters : array[REPO_ID][PLUGIN_ID][PARAMETER_NAME] = PARAMETER_VALUE - */ - public function listParameters(){ - return $this->parameters; - } - - public function listAutoApplies(){ - return $this->autoApplies; - } - - /** - * @param string $pluginId - * @param string $actionName - * @param string|null $repositoryId - * @param string $state - */ - public function setActionState($pluginId, $actionName, $repositoryId = null, $state = "disabled"){ - $this->actions = $this->setArrayValue($this->actions, $repositoryId, $pluginId, $actionName, $state); - return; - } - - public function listActionsStates(){ - return $this->actions; - } - - /** - * @param Repository $repository - * @return array - */ - public function listActionsStatesFor($repository){ - $actions = array(); - if(isSet($this->actions[AJXP_REPO_SCOPE_ALL])){ - $actions = $this->actions[AJXP_REPO_SCOPE_ALL]; - } - if($repository != null && isSet($this->actions[AJXP_REPO_SCOPE_SHARED]) && $repository->hasParent()){ - $actions = array_merge($actions, $this->actions[AJXP_REPO_SCOPE_SHARED]); - } - if($repository != null && isSet($this->actions[$repository->getId()])){ - $actions = array_merge($actions, $this->actions[$repository->getId()]); - } - return $actions; - } - - /** - * @param string $pluginId - * @param string $actionName - * @param string $repositoryId - * @param boolean $inputState - * @return boolean - */ - public function actionEnabled($pluginId, $actionName, $repositoryId, $inputState){ - if(isSet($this->actions[AJXP_REPO_SCOPE_ALL][$pluginId][$actionName])){ - return $this->actions[AJXP_REPO_SCOPE_ALL][$pluginId][$actionName] == "enabled" ? true : false ; - } - if(isSet($this->actions[$repositoryId][$pluginId][$actionName])){ - return $this->actions[$repositoryId][$pluginId][$actionName] == "enabled" ? true : false ; - } - return $inputState; - } - - /** - * @return array - */ - public function listAllActionsStates(){ - return $this->actions; - } - - /** - * @param AJXP_Role $role - * @return AJXP_Role - */ - public function override(AJXP_Role $role){ - $newRole = new AJXP_Role($role->getId()); - - $newAcls = $this->array_merge_recursive2($role->listAcls(), $this->listAcls()); - foreach($newAcls as $repoId => $rightString){ - if($rightString == AJXP_VALUE_CLEAR) continue; - $newRole->setAcl($repoId, $rightString); - } - - $newParams = $this->array_merge_recursive2($role->listParameters(), $this->listParameters()); - foreach($newParams as $repoId => $data){ - foreach ($data as $pluginId => $param) { - foreach($param as $parameterName => $parameterValue){ - if($parameterValue === true || $parameterValue === false){ - $newRole->setParameterValue($pluginId, $parameterName, $parameterValue, $repoId); - continue; - } - if($parameterValue == AJXP_VALUE_CLEAR) continue; - $newRole->setParameterValue($pluginId, $parameterName, $parameterValue, $repoId); - } - } - } - - $newActions = $this->array_merge_recursive2($role->listActionsStates(), $this->listActionsStates()); - foreach($newActions as $repoId => $data){ - foreach ($data as $pluginId => $action) { - foreach($action as $actionName => $actionState){ - $newRole->setActionState($pluginId, $actionName, $repoId, $actionState); - } - } - } - - return $newRole; - } - - /** - * @param array - * @param key1 - * @param key2 - * @param key3... - * @param value - */ - function setArrayValue(){ - $args = func_get_args(); - $arr = $args[0]; //array_shift($args); - $argMaxIndex = count($args)-1; - $value = $args[$argMaxIndex]; //array_pop($args); - $current = &$arr; - foreach ($args as $index => $key){ - if($index == 0) continue; - if($index < $argMaxIndex -1) { - if(!isset($current[$key])) $current[$key] = array(); - $current = &$current[$key]; - }else{ - $current[$key] = $value; - break; - } - } - return $arr; - } - - function array_merge_recursive2($array1, $array2) - { - $arrays = func_get_args(); - $narrays = count($arrays); - - // check arguments - // comment out if more performance is necessary (in this case the foreach loop will trigger a warning if the argument is not an array) - for ($i = 0; $i < $narrays; $i ++) { - if (!is_array($arrays[$i])) { - // also array_merge_recursive returns nothing in this case - trigger_error('Argument #' . ($i+1) . ' is not an array - trying to merge array with scalar! Returning null!', E_USER_WARNING); - return; - } - } - - // the first array is in the output set in every case - $ret = $arrays[0]; - - // merege $ret with the remaining arrays - for ($i = 1; $i < $narrays; $i ++) { - foreach ($arrays[$i] as $key => $value) { - //if (((string) $key) === ((string) intval($key))) { // integer or string as integer key - append - // $ret[] = $value; - //} - //{ // string key - megre - if (is_array($value) && isset($ret[$key])) { - // if $ret[$key] is not an array you try to merge an scalar value with an array - the result is not defined (incompatible arrays) - // in this case the call will trigger an E_USER_WARNING and the $ret[$key] will be null. - $ret[$key] = $this->array_merge_recursive2($ret[$key], $value); - } - else { - $ret[$key] = $value; - } - // } - } - } - - return $ret; - } - - public function setGroupPath($groupPath) - { - $this->groupPath = $groupPath; - } - - public function getGroupPath() - { - return $this->groupPath; - } - - public function getId() - { - return $this->roleId; - } - - public function setLabel($roleLabel) - { - $this->roleLabel = $roleLabel; - } - - public function getLabel() - { - return $this->roleLabel; - } - - /** - * @param array $specificRights - */ - public function setAutoApplies($specificRights){ - $this->autoApplies = $specificRights; - } - - /** - * @param string $specificRight - * @return boolean - */ - public function autoAppliesTo($specificRight){ - return in_array($specificRight, $this->autoApplies); - } - -} \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die('Access not allowed'); + +define('AJXP_VALUE_CLEAR', "AJXP_VALUE_CLEAR"); +define('AJXP_REPO_SCOPE_ALL',"AJXP_REPO_SCOPE_ALL"); +define('AJXP_REPO_SCOPE_SHARED',"AJXP_REPO_SCOPE_SHARED"); +define('AJXP_PLUGINS_SCOPE_ALL',"plugin_all"); + +/** + * @package AjaXplorer + * @subpackage Core + */ +class AJXP_Role implements AjxpGroupPathProvider +{ + + protected $groupPath; + protected $roleId; + protected $roleLabel; + + protected $acls = array(); + protected $parameters = array(); + protected $actions = array(); + protected $autoApplies = array(); + + public function __construct($id) + { + $this->roleId = $id; + } + + public function migrateDeprectated($repositoriesList, AjxpRole $oldRole) + { + $repositoriesList["ajxp.all"] = ""; + foreach ($repositoriesList as $repoId => $repoObject) { + $right = $oldRole->getRight($repoId); + if(!empty($right)) $this->setAcl($repoId, $right); + $actions = $oldRole->getSpecificActionsRights($repoId); + if (count($actions)) { + foreach ($actions as $act => $status) { + if ($repoId == "ajxp.all") { + $this->setActionState(AJXP_PLUGINS_SCOPE_ALL, $act, AJXP_REPO_SCOPE_ALL, $status); + } else { + $this->setActionState(AJXP_PLUGINS_SCOPE_ALL, $act, $repoId, $status); + } + } + } + } + $this->setGroupPath($oldRole->getGroupPath()); + if ($oldRole->isDefault()) { + $this->setAutoApplies(array("all")); + } + } + + public function isGroupRole() + { + return strpos($this->roleId, "AJXP_GRP_") === 0; + } + public function isUserRole() + { + return strpos($this->roleId, "AJXP_USER_") === 0; + } + + + /** + * Whether this role can read the given repo + * @param string $repositoryId Repository ID + * @return bool + */ + public function canRead($repositoryId) + { + $right = $this->getAcl($repositoryId); + if($right == "rw" || $right == "r") return true; + return false; + } + + /** + * Whether this role can write the given repo + * @param string $repositoryId Repository ID + * @return bool + */ + public function canWrite($repositoryId) + { + $right = $this->getAcl($repositoryId); + if($right == "rw" || $right == "w") return true; + return false; + } + + + /** + * @param string $repositoryId + * @param string $rightString + * @return void + */ + public function setAcl($repositoryId, $rightString) + { + if (empty($rightString)) { + if(isSet($this->acls[$repositoryId])) unset($this->acls[$repositoryId]); + } else { + $this->acls[$repositoryId] = $rightString; + } + return; + } + /** + * @param string $repositoryId + * @return string + */ + public function getAcl($repositoryId) + { + if (isSet($this->acls[$repositoryId])) { + return $this->acls[$repositoryId]; + } + return ""; + } + /** + * @return array Associative array[REPO_ID] => RIGHT_STRING (r / w / rw / AJXP_VALUE_CLEAR) + */ + public function listAcls() + { + return $this->acls; + } + + public function clearAcls() + { + $this->acls = array(); + } + + /** + * Send all role informations as an associative array + * @return array + */ + public function getDataArray() + { + $roleData = array(); + $roleData["ACL"] = $this->listAcls(); + $roleData["ACTIONS"] = $this->listActionsStates(); + $roleData["PARAMETERS"] = $this->listParameters(); + $roleData["APPLIES"] = $this->listAutoApplies(); + return $roleData; + } + + /** + * Update the role information from an associative array + * @see getDataArray() + * @param array $roleData + */ + public function bunchUpdate($roleData) + { + $this->acls = $roleData["ACL"]; + $this->actions = $roleData["ACTIONS"]; + $this->parameters = $roleData["PARAMETERS"]; + $this->autoApplies = $roleData["APPLIES"]; + + } + + + /** + * @param string $pluginId + * @param string $parameterName + * @param mixed $parameterValue can be AJXP_VALUE_CLEAR (force clear previous), or empty string for clearing value (apply previous). + * @param string|null $repositoryId + */ + public function setParameterValue($pluginId, $parameterName, $parameterValue, $repositoryId = null) + { + if($repositoryId === null) $repositoryId = AJXP_REPO_SCOPE_ALL; + if (empty($parameterValue) && $parameterValue !== false) { + if (isSet($this->parameters[$repositoryId][$pluginId][$parameterName])) { + unset($this->parameters[$repositoryId][$pluginId][$parameterName]); + if(!count($this->parameters[$repositoryId][$pluginId])) unset($this->parameters[$repositoryId][$pluginId]); + if(!count($this->parameters[$repositoryId])) unset($this->parameters[$repositoryId]); + } + } else { + $this->parameters = $this->setArrayValue($this->parameters, $repositoryId, $pluginId, $parameterName, $parameterValue); + } + return; + } + + /** + * @param string $pluginId + * @param string $parameterName + * @param string $repositoryId + * @param mixed $parameterValue + * @return mixed + */ + public function filterParameterValue($pluginId, $parameterName, $repositoryId, $parameterValue) + { + if (isSet($this->parameters[AJXP_REPO_SCOPE_ALL][$pluginId][$parameterName])) { + $v = $this->parameters[AJXP_REPO_SCOPE_ALL][$pluginId][$parameterName]; + if($v === AJXP_VALUE_CLEAR) return ""; + else return $v; + } + if (isSet($this->parameters[$repositoryId][$pluginId][$parameterName])) { + $v = $this->parameters[$repositoryId][$pluginId][$parameterName]; + if($v === AJXP_VALUE_CLEAR) return ""; + else return $v; + } + return $parameterValue; + } + /** + * @return array Associative array of parameters : array[REPO_ID][PLUGIN_ID][PARAMETER_NAME] = PARAMETER_VALUE + */ + public function listParameters() + { + return $this->parameters; + } + + public function listAutoApplies() + { + return $this->autoApplies; + } + + /** + * @param string $pluginId + * @param string $actionName + * @param string|null $repositoryId + * @param string $state + */ + public function setActionState($pluginId, $actionName, $repositoryId = null, $state = "disabled") + { + $this->actions = $this->setArrayValue($this->actions, $repositoryId, $pluginId, $actionName, $state); + return; + } + + public function listActionsStates() + { + return $this->actions; + } + + /** + * @param Repository $repository + * @return array + */ + public function listActionsStatesFor($repository) + { + $actions = array(); + if (isSet($this->actions[AJXP_REPO_SCOPE_ALL])) { + $actions = $this->actions[AJXP_REPO_SCOPE_ALL]; + } + if ($repository != null && isSet($this->actions[AJXP_REPO_SCOPE_SHARED]) && $repository->hasParent()) { + $actions = array_merge($actions, $this->actions[AJXP_REPO_SCOPE_SHARED]); + } + if ($repository != null && isSet($this->actions[$repository->getId()])) { + $actions = array_merge($actions, $this->actions[$repository->getId()]); + } + return $actions; + } + + /** + * @param string $pluginId + * @param string $actionName + * @param string $repositoryId + * @param boolean $inputState + * @return boolean + */ + public function actionEnabled($pluginId, $actionName, $repositoryId, $inputState) + { + if (isSet($this->actions[AJXP_REPO_SCOPE_ALL][$pluginId][$actionName])) { + return $this->actions[AJXP_REPO_SCOPE_ALL][$pluginId][$actionName] == "enabled" ? true : false ; + } + if (isSet($this->actions[$repositoryId][$pluginId][$actionName])) { + return $this->actions[$repositoryId][$pluginId][$actionName] == "enabled" ? true : false ; + } + return $inputState; + } + + /** + * @return array + */ + public function listAllActionsStates() + { + return $this->actions; + } + + /** + * @param AJXP_Role $role + * @return AJXP_Role + */ + public function override(AJXP_Role $role) + { + $newRole = new AJXP_Role($role->getId()); + + $newAcls = $this->array_merge_recursive2($role->listAcls(), $this->listAcls()); + foreach ($newAcls as $repoId => $rightString) { + if($rightString == AJXP_VALUE_CLEAR) continue; + $newRole->setAcl($repoId, $rightString); + } + + $newParams = $this->array_merge_recursive2($role->listParameters(), $this->listParameters()); + foreach ($newParams as $repoId => $data) { + foreach ($data as $pluginId => $param) { + foreach ($param as $parameterName => $parameterValue) { + if ($parameterValue === true || $parameterValue === false) { + $newRole->setParameterValue($pluginId, $parameterName, $parameterValue, $repoId); + continue; + } + if($parameterValue == AJXP_VALUE_CLEAR) continue; + $newRole->setParameterValue($pluginId, $parameterName, $parameterValue, $repoId); + } + } + } + + $newActions = $this->array_merge_recursive2($role->listActionsStates(), $this->listActionsStates()); + foreach ($newActions as $repoId => $data) { + foreach ($data as $pluginId => $action) { + foreach ($action as $actionName => $actionState) { + $newRole->setActionState($pluginId, $actionName, $repoId, $actionState); + } + } + } + + return $newRole; + } + + /** + * @param array + * @param key1 + * @param key2 + * @param key3... + * @param value + */ + public function setArrayValue() + { + $args = func_get_args(); + $arr = $args[0]; //array_shift($args); + $argMaxIndex = count($args)-1; + $value = $args[$argMaxIndex]; //array_pop($args); + $current = &$arr; + foreach ($args as $index => $key) { + if($index == 0) continue; + if ($index < $argMaxIndex -1) { + if(!isset($current[$key])) $current[$key] = array(); + $current = &$current[$key]; + } else { + $current[$key] = $value; + break; + } + } + return $arr; + } + + public function array_merge_recursive2($array1, $array2) + { + $arrays = func_get_args(); + $narrays = count($arrays); + + // check arguments + // comment out if more performance is necessary (in this case the foreach loop will trigger a warning if the argument is not an array) + for ($i = 0; $i < $narrays; $i ++) { + if (!is_array($arrays[$i])) { + // also array_merge_recursive returns nothing in this case + trigger_error('Argument #' . ($i+1) . ' is not an array - trying to merge array with scalar! Returning null!', E_USER_WARNING); + return; + } + } + + // the first array is in the output set in every case + $ret = $arrays[0]; + + // merege $ret with the remaining arrays + for ($i = 1; $i < $narrays; $i ++) { + foreach ($arrays[$i] as $key => $value) { + //if (((string) $key) === ((string) intval($key))) { // integer or string as integer key - append + // $ret[] = $value; + //} + //{ // string key - megre + if (is_array($value) && isset($ret[$key])) { + // if $ret[$key] is not an array you try to merge an scalar value with an array - the result is not defined (incompatible arrays) + // in this case the call will trigger an E_USER_WARNING and the $ret[$key] will be null. + $ret[$key] = $this->array_merge_recursive2($ret[$key], $value); + } else { + $ret[$key] = $value; + } + // } + } + } + + return $ret; + } + + public function setGroupPath($groupPath) + { + $this->groupPath = $groupPath; + } + + public function getGroupPath() + { + return $this->groupPath; + } + + public function getId() + { + return $this->roleId; + } + + public function setLabel($roleLabel) + { + $this->roleLabel = $roleLabel; + } + + public function getLabel() + { + return $this->roleLabel; + } + + /** + * @param array $specificRights + */ + public function setAutoApplies($specificRights) + { + $this->autoApplies = $specificRights; + } + + /** + * @param string $specificRight + * @return boolean + */ + public function autoAppliesTo($specificRight) + { + return in_array($specificRight, $this->autoApplies); + } + +} diff --git a/core/src/core/classes/class.AJXP_Safe.php b/core/src/core/classes/class.AJXP_Safe.php index 17c74e67be..db6ba0f74f 100644 --- a/core/src/core/classes/class.AJXP_Safe.php +++ b/core/src/core/classes/class.AJXP_Safe.php @@ -1,267 +1,279 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * Credential keeper that can be stored in the session, the credentials are kept crypted. - * @package AjaXplorer - * @subpackage Core - */ -class AJXP_Safe{ - - private static $instance; - - private $user; - private $encodedPassword; - private $secretKey; - private $separator = "__SAFE_SEPARATOR__"; - private $forceSessionCredentials = false; - /** - * Instance constructor - */ - public function __construct(){ - if(defined('AJXP_SAFE_SECRET_KEY')){ - $this->secretKey = AJXP_SAFE_SECRET_KEY; - }else{ - $this->secretKey = "\1CDAFx¨op#"; - } - } - /** - * Store the user/password pair. Password will be encoded - * @param string $user - * @param string $password - * @return void - */ - public function setCredentials($user, $password){ - $this->user = $user; - $this->encodedPassword = $this->_encodePassword($password, $user); - } - /** - * Return the user/password pair, or false if cannot find it. - * @return array|bool - */ - public function getCredentials(){ - if(isSet($this->user) && isSet($this->encodedPassword)){ - $decoded = $this->_decodePassword($this->encodedPassword, $this->user); - return array( - "user" => $this->user, - "password" => $decoded, - 0 => $this->user, - 1 => $decoded - ); - }else{ - return false; - } - } - /** - * Use mcrypt function to encode the password - * @param $password - * @param $user - * @return string - */ - private function _encodePassword($password, $user){ - if (function_exists('mcrypt_encrypt')) - { - // The initialisation vector is only required to avoid a warning, as ECB ignore IV - $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); - // We encode as base64 so if we need to store the result in a database, it can be stored in text column - $password = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($user.$this->secretKey), $password, MCRYPT_MODE_ECB, $iv)); - } - return $password; - } - /** - * Use mcrypt functions to decode the password - * @param $encoded - * @param $user - * @return string - */ - private function _decodePassword($encoded, $user){ - if (function_exists('mcrypt_decrypt')) - { - // The initialisation vector is only required to avoid a warning, as ECB ignore IV - $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); - // We have encoded as base64 so if we need to store the result in a database, it can be stored in text column - $encoded = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($user.$this->secretKey), base64_decode($encoded), MCRYPT_MODE_ECB, $iv), "\0"); - } - return $encoded; - } - /** - * Store the password credentials in the session - * @return void - */ - public function store(){ - $_SESSION["AJXP_SAFE_CREDENTIALS"] = base64_encode($this->user.$this->separator.$this->encodedPassword); - } - /** - * Load the credentials from session - * @return - */ - public function load($encodedString = ""){ - if($encodedString == "" && !empty($_SESSION["AJXP_SAFE_CREDENTIALS"])){ - $encodedString = $_SESSION["AJXP_SAFE_CREDENTIALS"]; - } - if(empty($encodedString)) return; - $sessData = base64_decode($encodedString); - $parts = explode($this->separator, $sessData); - $this->user = $parts[0]; - $this->encodedPassword = $parts[1]; - } - /** - * Remove the credentials from session - * @return void - */ - public function clear(){ - unset($_SESSION["AJXP_SAFE_CREDENTIALS"]); - $this->user = null; - $this->encodedPassword = null; - } - /** - * For the session credentials to override other credentials set via config - * @return void - */ - public function forceSessionCredentialsUsage(){ - $this->forceSessionCredentials = true; - } - - - - /** - * Creates the singleton instance - * @return AJXP_Safe - */ - public static function getInstance(){ - if(empty(self::$instance)){ - self::$instance = new AJXP_Safe(); - } - return self::$instance; - } - /** - * Store the user/pass key pair - * @static - * @param string $user - * @param string $password - * @return void - */ - public static function storeCredentials($user, $password){ - $inst = AJXP_Safe::getInstance(); - $inst->setCredentials($user, $password); - $inst->store(); - } - /** - * Remove the user/pass encoded from the session - * @static - * @return void - */ - public static function clearCredentials(){ - $inst = AJXP_Safe::getInstance(); - $inst->clear(); - } - /** - * Retrieve the user/pass from the session - * @static - * @return array|bool - */ - public static function loadCredentials(){ - $inst = AJXP_Safe::getInstance(); - $inst->load(); - return $inst->getCredentials(); - } - - public static function getEncodedCredentialString(){ - return $_SESSION["AJXP_SAFE_CREDENTIALS"]; - } - - public static function getCredentialsFromEncodedString($encoded){ - $tmpInstance = new AJXP_Safe(); - $tmpInstance->load($encoded); - return $tmpInstance->getCredentials(); - } - - /** - * Will try to get the credentials for a given repository as follow : - * + Try to get the credentials from the url parsing - * + Try to get them from the user "Wallet" (personal data) - * + Try to get them from the repository configuration - * + Try to get them from the AJXP_Safe. - * - * @param array $parsedUrl - * @param Repository $repository - * @return array - */ - public static function tryLoadingCredentialsFromSources($parsedUrl, $repository){ - $user = $password = ""; - $optionsPrefix = ""; - if($repository->getAccessType() == "ftp"){ - $optionsPrefix = "FTP_"; - } - // Get USER/PASS - // 1. Try from URL - if(isSet($parsedUrl["user"]) && isset($parsedUrl["pass"])){ - $user = rawurldecode($parsedUrl["user"]); - $password = rawurldecode($parsedUrl["pass"]); - } - // 2. Try from user wallet - if($user==""){ - $loggedUser = AuthService::getLoggedUser(); - if($loggedUser != null){ - $wallet = $loggedUser->getPref("AJXP_WALLET"); - if(is_array($wallet) && isSet($wallet[$repository->getId()][$optionsPrefix."USER"])){ - $user = $wallet[$repository->getId()][$optionsPrefix."USER"]; - $password = $loggedUser->decodeUserPassword($wallet[$repository->getId()][$optionsPrefix."PASS"]); - } - } - } - // 2bis. Wallet is now a custom parameter - if($user ==""){ - $loggedUser = AuthService::getLoggedUser(); - if($loggedUser != null){ - $u = $loggedUser->mergedRole->filterParameterValue("access.".$repository->getAccessType(), $optionsPrefix."USER", $repository->getId(), ""); - $p = $loggedUser->mergedRole->filterParameterValue("access.".$repository->getAccessType(), $optionsPrefix."PASS", $repository->getId(), ""); - if(!empty($u) && !empty($p)){ - $user = $u; - $password = $loggedUser->decodeUserPassword($p); - } - } - } - // 3. Try from repository config - if($user==""){ - $user = $repository->getOption($optionsPrefix."USER"); - $password = $repository->getOption($optionsPrefix."PASS"); - } - // 4. Test if there are encoded credentials available - if($user == "" && $repository->getOption("ENCODED_CREDENTIALS") != ""){ - list($user, $password) = AJXP_Safe::getCredentialsFromEncodedString($repository->getOption("ENCODED_CREDENTIALS")); - } - // 5. Try from session - if($user=="" && ( $repository->getOption("USE_SESSION_CREDENTIALS") || self::getInstance()->forceSessionCredentials )){ - $safeCred = AJXP_Safe::loadCredentials(); - if($safeCred !== false){ - $user = $safeCred["user"]; - $password = $safeCred["password"]; - } - } - return array("user" => $user, "password" => $password); - - } - -} - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * Credential keeper that can be stored in the session, the credentials are kept crypted. + * @package AjaXplorer + * @subpackage Core + */ +class AJXP_Safe +{ + private static $instance; + + private $user; + private $encodedPassword; + private $secretKey; + private $separator = "__SAFE_SEPARATOR__"; + private $forceSessionCredentials = false; + /** + * Instance constructor + */ + public function __construct() + { + if (defined('AJXP_SAFE_SECRET_KEY')) { + $this->secretKey = AJXP_SAFE_SECRET_KEY; + } else { + $this->secretKey = "\1CDAFx¨op#"; + } + } + /** + * Store the user/password pair. Password will be encoded + * @param string $user + * @param string $password + * @return void + */ + public function setCredentials($user, $password) + { + $this->user = $user; + $this->encodedPassword = $this->_encodePassword($password, $user); + } + /** + * Return the user/password pair, or false if cannot find it. + * @return array|bool + */ + public function getCredentials() + { + if (isSet($this->user) && isSet($this->encodedPassword)) { + $decoded = $this->_decodePassword($this->encodedPassword, $this->user); + return array( + "user" => $this->user, + "password" => $decoded, + 0 => $this->user, + 1 => $decoded + ); + } else { + return false; + } + } + /** + * Use mcrypt function to encode the password + * @param $password + * @param $user + * @return string + */ + private function _encodePassword($password, $user) + { + if (function_exists('mcrypt_encrypt')) { + // The initialisation vector is only required to avoid a warning, as ECB ignore IV + $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); + // We encode as base64 so if we need to store the result in a database, it can be stored in text column + $password = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($user.$this->secretKey), $password, MCRYPT_MODE_ECB, $iv)); + } + return $password; + } + /** + * Use mcrypt functions to decode the password + * @param $encoded + * @param $user + * @return string + */ + private function _decodePassword($encoded, $user) + { + if (function_exists('mcrypt_decrypt')) { + // The initialisation vector is only required to avoid a warning, as ECB ignore IV + $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); + // We have encoded as base64 so if we need to store the result in a database, it can be stored in text column + $encoded = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($user.$this->secretKey), base64_decode($encoded), MCRYPT_MODE_ECB, $iv), "\0"); + } + return $encoded; + } + /** + * Store the password credentials in the session + * @return void + */ + public function store() + { + $_SESSION["AJXP_SAFE_CREDENTIALS"] = base64_encode($this->user.$this->separator.$this->encodedPassword); + } + /** + * Load the credentials from session + * @return + */ + public function load($encodedString = "") + { + if ($encodedString == "" && !empty($_SESSION["AJXP_SAFE_CREDENTIALS"])) { + $encodedString = $_SESSION["AJXP_SAFE_CREDENTIALS"]; + } + if(empty($encodedString)) return; + $sessData = base64_decode($encodedString); + $parts = explode($this->separator, $sessData); + $this->user = $parts[0]; + $this->encodedPassword = $parts[1]; + } + /** + * Remove the credentials from session + * @return void + */ + public function clear() + { + unset($_SESSION["AJXP_SAFE_CREDENTIALS"]); + $this->user = null; + $this->encodedPassword = null; + } + /** + * For the session credentials to override other credentials set via config + * @return void + */ + public function forceSessionCredentialsUsage() + { + $this->forceSessionCredentials = true; + } + + + + /** + * Creates the singleton instance + * @return AJXP_Safe + */ + public static function getInstance() + { + if (empty(self::$instance)) { + self::$instance = new AJXP_Safe(); + } + return self::$instance; + } + /** + * Store the user/pass key pair + * @static + * @param string $user + * @param string $password + * @return void + */ + public static function storeCredentials($user, $password) + { + $inst = AJXP_Safe::getInstance(); + $inst->setCredentials($user, $password); + $inst->store(); + } + /** + * Remove the user/pass encoded from the session + * @static + * @return void + */ + public static function clearCredentials() + { + $inst = AJXP_Safe::getInstance(); + $inst->clear(); + } + /** + * Retrieve the user/pass from the session + * @static + * @return array|bool + */ + public static function loadCredentials() + { + $inst = AJXP_Safe::getInstance(); + $inst->load(); + return $inst->getCredentials(); + } + + public static function getEncodedCredentialString() + { + return $_SESSION["AJXP_SAFE_CREDENTIALS"]; + } + + public static function getCredentialsFromEncodedString($encoded) + { + $tmpInstance = new AJXP_Safe(); + $tmpInstance->load($encoded); + return $tmpInstance->getCredentials(); + } + + /** + * Will try to get the credentials for a given repository as follow : + * + Try to get the credentials from the url parsing + * + Try to get them from the user "Wallet" (personal data) + * + Try to get them from the repository configuration + * + Try to get them from the AJXP_Safe. + * + * @param array $parsedUrl + * @param Repository $repository + * @return array + */ + public static function tryLoadingCredentialsFromSources($parsedUrl, $repository) + { + $user = $password = ""; + $optionsPrefix = ""; + if ($repository->getAccessType() == "ftp") { + $optionsPrefix = "FTP_"; + } + // Get USER/PASS + // 1. Try from URL + if (isSet($parsedUrl["user"]) && isset($parsedUrl["pass"])) { + $user = rawurldecode($parsedUrl["user"]); + $password = rawurldecode($parsedUrl["pass"]); + } + // 2. Try from user wallet + if ($user=="") { + $loggedUser = AuthService::getLoggedUser(); + if ($loggedUser != null) { + $wallet = $loggedUser->getPref("AJXP_WALLET"); + if (is_array($wallet) && isSet($wallet[$repository->getId()][$optionsPrefix."USER"])) { + $user = $wallet[$repository->getId()][$optionsPrefix."USER"]; + $password = $loggedUser->decodeUserPassword($wallet[$repository->getId()][$optionsPrefix."PASS"]); + } + } + } + // 2bis. Wallet is now a custom parameter + if ($user =="") { + $loggedUser = AuthService::getLoggedUser(); + if ($loggedUser != null) { + $u = $loggedUser->mergedRole->filterParameterValue("access.".$repository->getAccessType(), $optionsPrefix."USER", $repository->getId(), ""); + $p = $loggedUser->mergedRole->filterParameterValue("access.".$repository->getAccessType(), $optionsPrefix."PASS", $repository->getId(), ""); + if (!empty($u) && !empty($p)) { + $user = $u; + $password = $loggedUser->decodeUserPassword($p); + } + } + } + // 3. Try from repository config + if ($user=="") { + $user = $repository->getOption($optionsPrefix."USER"); + $password = $repository->getOption($optionsPrefix."PASS"); + } + // 4. Test if there are encoded credentials available + if ($user == "" && $repository->getOption("ENCODED_CREDENTIALS") != "") { + list($user, $password) = AJXP_Safe::getCredentialsFromEncodedString($repository->getOption("ENCODED_CREDENTIALS")); + } + // 5. Try from session + if ($user=="" && ( $repository->getOption("USE_SESSION_CREDENTIALS") || self::getInstance()->forceSessionCredentials )) { + $safeCred = AJXP_Safe::loadCredentials(); + if ($safeCred !== false) { + $user = $safeCred["user"]; + $password = $safeCred["password"]; + } + } + return array("user" => $user, "password" => $password); + + } + +} diff --git a/core/src/core/classes/class.AJXP_ShutdownScheduler.php b/core/src/core/classes/class.AJXP_ShutdownScheduler.php index 7a50d674c7..23568624a1 100644 --- a/core/src/core/classes/class.AJXP_ShutdownScheduler.php +++ b/core/src/core/classes/class.AJXP_ShutdownScheduler.php @@ -1,97 +1,102 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die('Access not allowed'); -/** - * - * @package AjaXplorer - * @subpackage Core - * - */ -class AJXP_ShutdownScheduler -{ - private static $instance; - - private $callbacks; // array to store user callbacks - - /** - * @static - * @return AJXP_ShutdownScheduler - */ - public static function getInstance(){ - if(self::$instance == null) self::$instance = new AJXP_ShutdownScheduler(); - return self::$instance; - } - - public function __construct() { - $this->callbacks = array(); - register_shutdown_function(array($this, 'callRegisteredShutdown')); - ob_start(); - } - public function registerShutdownEventArray() { - $callback = func_get_args(); - - if (empty($callback)) { - throw new Exception('No callback passed to '.__FUNCTION__.' method'); - } - if (!is_callable($callback[0])) { - throw new Exception('Invalid callback ('.$callback[0].') passed to the '.__FUNCTION__.' method'); - } - $flattenArray = array(); - $flattenArray[0] = $callback[0]; - if(is_array($callback[1])) { - foreach($callback[1] as $argument) $flattenArray[] = $argument; - } - $this->callbacks[] = $flattenArray; - return true; - } - public function registerShutdownEvent() { - $callback = func_get_args(); - - if (empty($callback)) { - throw new Exception('No callback passed to '.__FUNCTION__.' method'); - } - if (!is_callable($callback[0])) { - throw new Exception('Invalid callback ('.$callback[0].') passed to the '.__FUNCTION__.' method'); - } - $this->callbacks[] = $callback; - return true; - } - public function callRegisteredShutdown() { - session_write_close(); - if(!headers_sent()){ - $size = ob_get_length(); - header("Connection: close\r\n"); - //header("Content-Encoding: none\r\n"); - header("Content-Length: $size"); - } - ob_end_flush(); - flush(); - foreach ($this->callbacks as $arguments) { - $callback = array_shift($arguments); - try{ - call_user_func_array($callback, $arguments); - }catch (Exception $e){ - AJXP_Logger::logAction("error", array("context"=>"Applying hook ".get_class($callback[0])."::".$callback[1], "message" => $e->getMessage())); - } - } - } -} + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die('Access not allowed'); +/** + * + * @package AjaXplorer + * @subpackage Core + * + */ +class AJXP_ShutdownScheduler +{ + private static $instance; + + private $callbacks; // array to store user callbacks + + /** + * @static + * @return AJXP_ShutdownScheduler + */ + public static function getInstance() + { + if(self::$instance == null) self::$instance = new AJXP_ShutdownScheduler(); + return self::$instance; + } + + public function __construct() + { + $this->callbacks = array(); + register_shutdown_function(array($this, 'callRegisteredShutdown')); + ob_start(); + } + public function registerShutdownEventArray() + { + $callback = func_get_args(); + + if (empty($callback)) { + throw new Exception('No callback passed to '.__FUNCTION__.' method'); + } + if (!is_callable($callback[0])) { + throw new Exception('Invalid callback ('.$callback[0].') passed to the '.__FUNCTION__.' method'); + } + $flattenArray = array(); + $flattenArray[0] = $callback[0]; + if (is_array($callback[1])) { + foreach($callback[1] as $argument) $flattenArray[] = $argument; + } + $this->callbacks[] = $flattenArray; + return true; + } + public function registerShutdownEvent() + { + $callback = func_get_args(); + + if (empty($callback)) { + throw new Exception('No callback passed to '.__FUNCTION__.' method'); + } + if (!is_callable($callback[0])) { + throw new Exception('Invalid callback ('.$callback[0].') passed to the '.__FUNCTION__.' method'); + } + $this->callbacks[] = $callback; + return true; + } + public function callRegisteredShutdown() + { + session_write_close(); + if (!headers_sent()) { + $size = ob_get_length(); + header("Connection: close\r\n"); + //header("Content-Encoding: none\r\n"); + header("Content-Length: $size"); + } + ob_end_flush(); + flush(); + foreach ($this->callbacks as $arguments) { + $callback = array_shift($arguments); + try { + call_user_func_array($callback, $arguments); + } catch (Exception $e) { + AJXP_Logger::logAction("error", array("context"=>"Applying hook ".get_class($callback[0])."::".$callback[1], "message" => $e->getMessage())); + } + } + } +} diff --git a/core/src/core/classes/class.AJXP_Utils.php b/core/src/core/classes/class.AJXP_Utils.php index f4ffbc7674..fa854576ce 100644 --- a/core/src/core/classes/class.AJXP_Utils.php +++ b/core/src/core/classes/class.AJXP_Utils.php @@ -27,7 +27,7 @@ // THESE ARE DEFINED IN bootstrap_context.php // REPEAT HERE FOR BACKWARD COMPATIBILITY. -if(!defined('PBKDF2_HASH_ALGORITHM')){ +if (!defined('PBKDF2_HASH_ALGORITHM')) { define("PBKDF2_HASH_ALGORITHM", "sha256"); define("PBKDF2_ITERATIONS", 1000); @@ -60,7 +60,7 @@ class AJXP_Utils * @param Array $array The array to sort * @return boolean */ - static function natksort(&$array) + public static function natksort(&$array) { uksort($array, 'strnatcasecmp'); return true; @@ -73,7 +73,7 @@ static function natksort(&$array) * @param Array $array The array to sort * @return boolean */ - static function natkrsort(&$array) + public static function natkrsort(&$array) { natksort($array); $array = array_reverse($array, TRUE); @@ -86,15 +86,15 @@ static function natkrsort(&$array) * @param string $path * @return string */ - static function securePath($path) + public static function securePath($path) { if ($path == null) $path = ""; // // REMOVE ALL "../" TENTATIVES // + $path = str_replace(chr(0), "", $path); $dirs = explode('/', $path); - for ($i = 0; $i < count($dirs); $i++) - { + for ($i = 0; $i < count($dirs); $i++) { if ($dirs[$i] == '.' or $dirs[$i] == '..') { $dirs[$i] = ''; } @@ -105,8 +105,7 @@ static function securePath($path) // // REPLACE DOUBLE SLASHES // - while (preg_match('/\/\//', $path)) - { + while (preg_match('/\/\//', $path)) { $path = str_replace('//', '/', $path); } return $path; @@ -194,19 +193,23 @@ public static function getAjxpTmpDir() return realpath(sys_get_temp_dir()); } - public static function detectApplicationFirstRun(){ + public static function detectApplicationFirstRun() + { return !file_exists(AJXP_CACHE_DIR."/first_run_passed"); } - public static function setApplicationFirstRunPassed(){ + public static function setApplicationFirstRunPassed() + { @file_put_contents(AJXP_CACHE_DIR."/first_run_passed", "true"); } - public static function forwardSlashDirname($path){ + public static function forwardSlashDirname($path) + { return (DIRECTORY_SEPARATOR === "\\" ? str_replace("\\", "/", dirname($path)): dirname($path)); } - public static function forwardSlashBasename($path){ + public static function forwardSlashBasename($path) + { return (DIRECTORY_SEPARATOR === "\\" ? str_replace("\\", "/", basename($path)): basename($path)); } @@ -237,7 +240,7 @@ public static function parseCSL($string, $hash = false) * @param $boxData * @return array|null */ - static function parseFileDataErrors($boxData) + public static function parseFileDataErrors($boxData) { $mess = ConfService::getMessages(); $userfile_error = $boxData["error"]; @@ -254,9 +257,7 @@ static function parseFileDataErrors($boxData) if (!ereg('Opera', $_SERVER['HTTP_USER_AGENT'])) { return $errorsArray[$userfile_error]; } - } - else - { + } else { return $errorsArray[$userfile_error]; } } @@ -285,10 +286,10 @@ public static function parseApplicationGetParameters($parameters, &$output, &$se $output["EXT_REP"] = "/"; if (isSet($parameters["repository_id"]) && isSet($parameters["folder"]) || isSet($parameters["goto"])) { - if(isSet($parameters["goto"])){ + if (isSet($parameters["goto"])) { $repoId = array_shift(explode("/", ltrim($parameters["goto"], "/"))); $parameters["folder"] = str_replace($repoId, "", ltrim($parameters["goto"], "/")); - }else{ + } else { $repoId = $parameters["repository_id"]; } $repository = ConfService::getRepositoryById($repoId); @@ -297,7 +298,7 @@ public static function parseApplicationGetParameters($parameters, &$output, &$se if ($repository != null) { $parameters["repository_id"] = $repository->getId(); } - }else{ + } else { $parameters["repository_id"] = $repository->getId(); } require_once(AJXP_BIN_FOLDER . "/class.SystemTextEncoding.php"); @@ -338,7 +339,7 @@ public static function parseApplicationGetParameters($parameters, &$output, &$se @unlink(AJXP_PLUGINS_CACHE_FILE); @unlink(AJXP_PLUGINS_REQUIRES_FILE); } - if (AJXP_SERVER_DEBUG && isSet($parameters["extract_application_hooks"])){ + if (AJXP_SERVER_DEBUG && isSet($parameters["extract_application_hooks"])) { self::extractHooksToDoc(); } @@ -369,7 +370,7 @@ public static function parseApplicationGetParameters($parameters, &$output, &$se * @param $fileContent * @return mixed */ - static function removeWinReturn($fileContent) + public static function removeWinReturn($fileContent) { $fileContent = str_replace(chr(10), "", $fileContent); $fileContent = str_replace(chr(13), "", $fileContent); @@ -384,7 +385,7 @@ static function removeWinReturn($fileContent) * @param bool $isDir * @return string Returns the icon name ("image") or the mime label ("text") */ - static function mimetype($fileName, $mode, $isDir) + public static function mimetype($fileName, $mode, $isDir) { $mess = ConfService::getMessages(); $fileName = strtolower($fileName); @@ -408,19 +409,20 @@ static function mimetype($fileName, $mode, $isDir) return (($mode == "image" ? $mime[1] : $mime[2])); } - static $registeredExtensions; - static function mimeData($fileName, $isDir){ + public static $registeredExtensions; + public static function mimeData($fileName, $isDir) + { $fileName = strtolower($fileName); - if(self::$registeredExtensions == null){ + if (self::$registeredExtensions == null) { self::$registeredExtensions = ConfService::getRegisteredExtensions(); } if ($isDir) { $mime = self::$registeredExtensions["ajxp_folder"]; } else { $pos = strrpos($fileName, "."); - if($pos !== false){ + if ($pos !== false) { $fileExt = substr($fileName, $pos + 1); - if(!empty($fileExt) && array_key_exists($fileExt, self::$registeredExtensions) && $fileExt != "ajxp_folder" && $fileExt != "ajxp_empty"){ + if (!empty($fileExt) && array_key_exists($fileExt, self::$registeredExtensions) && $fileExt != "ajxp_folder" && $fileExt != "ajxp_empty") { $mime = self::$registeredExtensions[$fileExt]; } } @@ -439,7 +441,7 @@ static function mimeData($fileName, $isDir){ * @param string $keyword "editable", "image", "audio", "zip" * @return string */ - static function getAjxpMimes($keyword) + public static function getAjxpMimes($keyword) { if ($keyword == "editable") { // Gather editors! @@ -478,7 +480,7 @@ static function getAjxpMimes($keyword) * @param $fileName * @return bool */ - static function is_image($fileName) + public static function is_image($fileName) { if (preg_match("/\.png$|\.bmp$|\.jpg$|\.jpeg$|\.gif$/i", $fileName)) { return 1; @@ -492,7 +494,7 @@ static function is_image($fileName) * @return bool * @deprecated */ - static function is_mp3($fileName) + public static function is_mp3($fileName) { if (preg_match("/\.mp3$/i", $fileName)) return 1; return 0; @@ -503,18 +505,15 @@ static function is_mp3($fileName) * @param $fileName * @return string */ - static function getImageMimeType($fileName) + public static function getImageMimeType($fileName) { if (preg_match("/\.jpg$|\.jpeg$/i", $fileName)) { return "image/jpeg"; - } - else if (preg_match("/\.png$/i", $fileName)) { + } else if (preg_match("/\.png$/i", $fileName)) { return "image/png"; - } - else if (preg_match("/\.bmp$/i", $fileName)) { + } else if (preg_match("/\.bmp$/i", $fileName)) { return "image/bmp"; - } - else if (preg_match("/\.gif$/i", $fileName)) { + } else if (preg_match("/\.gif$/i", $fileName)) { return "image/gif"; } } @@ -524,42 +523,32 @@ static function getImageMimeType($fileName) * @param $fileName * @return bool|string */ - static function getStreamingMimeType($fileName) + public static function getStreamingMimeType($fileName) { if (preg_match("/\.mp3$/i", $fileName)) { return "audio/mp3"; - } - else if (preg_match("/\.wav$/i", $fileName)) { + } else if (preg_match("/\.wav$/i", $fileName)) { return "audio/wav"; - } - else if (preg_match("/\.aac$/i", $fileName)) { + } else if (preg_match("/\.aac$/i", $fileName)) { return "audio/aac"; - } - else if (preg_match("/\.m4a$/i", $fileName)) { + } else if (preg_match("/\.m4a$/i", $fileName)) { return "audio/m4a"; - } - else if (preg_match("/\.aiff$/i", $fileName)) { + } else if (preg_match("/\.aiff$/i", $fileName)) { return "audio/aiff"; - } - else if (preg_match("/\.mp4$/i", $fileName)) { + } else if (preg_match("/\.mp4$/i", $fileName)) { return "video/mp4"; - } - else if (preg_match("/\.mov$/i", $fileName)) { + } else if (preg_match("/\.mov$/i", $fileName)) { return "video/quicktime"; - } - else if (preg_match("/\.m4v$/i", $fileName)) { + } else if (preg_match("/\.m4v$/i", $fileName)) { return "video/x-m4v"; - } - else if (preg_match("/\.3gp$/i", $fileName)) { + } else if (preg_match("/\.3gp$/i", $fileName)) { return "video/3gpp"; - } - else if (preg_match("/\.3g2$/i", $fileName)) { + } else if (preg_match("/\.3g2$/i", $fileName)) { return "video/3gpp2"; - } - else return false; + } else return false; } - static $sizeUnit; + public static $sizeUnit; /** * Display a human readable string for a bytesize (1MB, 2,3Go, etc) * @static @@ -567,9 +556,9 @@ static function getStreamingMimeType($fileName) * @param bool $phpConfig * @return string */ - static function roundSize($filesize, $phpConfig = false) + public static function roundSize($filesize, $phpConfig = false) { - if(self::$sizeUnit == null){ + if (self::$sizeUnit == null) { $mess = ConfService::getMessages(); self::$sizeUnit = $mess["byte_unit_symbol"]; } @@ -578,14 +567,11 @@ static function roundSize($filesize, $phpConfig = false) } if ($filesize >= 1073741824) { $filesize = round($filesize / 1073741824 * 100) / 100 . ($phpConfig ? "G" : " G" . self::$sizeUnit); - } - elseif ($filesize >= 1048576) { + } elseif ($filesize >= 1048576) { $filesize = round($filesize / 1048576 * 100) / 100 . ($phpConfig ? "M" : " M" . self::$sizeUnit); - } - elseif ($filesize >= 1024) { + } elseif ($filesize >= 1024) { $filesize = round($filesize / 1024 * 100) / 100 . ($phpConfig ? "K" : " K" . self::$sizeUnit); - } - else { + } else { $filesize = $filesize . " " . self::$sizeUnit; } if ($filesize == 0) { @@ -600,7 +586,7 @@ static function roundSize($filesize, $phpConfig = false) * @param string $fileName * @return bool */ - static function isHidden($fileName) + public static function isHidden($fileName) { return (substr($fileName, 0, 1) == "."); } @@ -611,7 +597,7 @@ static function isHidden($fileName) * @param string $fileName * @return int */ - static function isBrowsableArchive($fileName) + public static function isBrowsableArchive($fileName) { return preg_match("/\.zip$/i", $fileName); } @@ -621,18 +607,15 @@ static function isBrowsableArchive($fileName) * @param string $value * @return int */ - static function convertBytes($value) + public static function convertBytes($value) { if (is_numeric($value)) { return intval($value); - } - else - { + } else { $value_length = strlen($value); $qty = substr($value, 0, $value_length - 1); $unit = strtolower(substr($value, $value_length - 1)); - switch ($unit) - { + switch ($unit) { case 'k': $qty *= 1024; break; @@ -650,8 +633,8 @@ static function convertBytes($value) //Relative Date Function - public static function relativeDate($time, $messages) { - + public static function relativeDate($time, $messages) + { $today = strtotime(date('M j, Y')); $reldays = ($time - $today)/86400; $relTime = date($messages['date_relative_time_format'], $time); @@ -690,7 +673,7 @@ public static function relativeDate($time, $messages) { * @param bool $toUtf8 * @return mixed|string */ - static function xmlEntities($string, $toUtf8 = false) + public static function xmlEntities($string, $toUtf8 = false) { $xmlSafe = str_replace(array("&", "<", ">", "\"", "\n", "\r"), array("&", "<", ">", """, " ", " "), $string); if ($toUtf8 && SystemTextEncoding::getEncoding() != "UTF-8") { @@ -708,7 +691,7 @@ static function xmlEntities($string, $toUtf8 = false) * @param bool $toUtf8 * @return mixed|string */ - static function xmlContentEntities($string, $toUtf8 = false) + public static function xmlContentEntities($string, $toUtf8 = false) { $xmlSafe = str_replace(array("&", "<", ">", "\""), array("&", "<", ">", """), $string); if ($toUtf8) { @@ -724,11 +707,10 @@ static function xmlContentEntities($string, $toUtf8 = false) * @param string $file * @return bool */ - static public function searchIncludePath($file) + public static function searchIncludePath($file) { $ps = explode(PATH_SEPARATOR, ini_get('include_path')); - foreach ($ps as $path) - { + foreach ($ps as $path) { if (@file_exists($path . DIRECTORY_SEPARATOR . $file)) return true; } if (@file_exists($file)) return true; @@ -741,21 +723,21 @@ static public function searchIncludePath($file) * @param $to * @return string */ - static public function getTravelPath($from, $to) + public static function getTravelPath($from, $to) { $from = explode('/', $from); $to = explode('/', $to); $relPath = $to; - foreach($from as $depth => $dir) { + foreach ($from as $depth => $dir) { // find first non-matching dir - if($dir === $to[$depth]) { + if ($dir === $to[$depth]) { // ignore this directory array_shift($relPath); } else { // get number of remaining dirs to $from $remaining = count($from) - $depth; - if($remaining > 1) { + if ($remaining > 1) { // add traversals up to first matching dir $padLength = (count($relPath) + $remaining - 1) * -1; $relPath = array_pad($relPath, $padLength, '..'); @@ -776,22 +758,22 @@ static public function getTravelPath($from, $to) * @static * @return string */ - static function detectServerURL($withURI = false) + public static function detectServerURL($withURI = false) { $setUrl = ConfService::getCoreConf("SERVER_URL"); - if(!empty($setUrl)){ + if (!empty($setUrl)) { return $setUrl; } - if(php_sapi_name() == "cli"){ + if (php_sapi_name() == "cli") { AJXP_Logger::debug("WARNING, THE SERVER_URL IS NOT SET, WE CANNOT BUILD THE MAIL ADRESS WHEN WORKING IN CLI"); } $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http'); $port = (($protocol === 'http' && $_SERVER['SERVER_PORT'] == 80 || $protocol === 'https' && $_SERVER['SERVER_PORT'] == 443) ? "" : ":" . $_SERVER['SERVER_PORT']); $name = $_SERVER["SERVER_NAME"]; - if(!$withURI){ + if (!$withURI) { return "$protocol://$name$port"; - }else{ + } else { return "$protocol://$name$port".dirname($_SERVER["REQUEST_URI"]); } } @@ -801,7 +783,7 @@ static function detectServerURL($withURI = false) * @param string $text * @return string */ - static public function slugify($text) + public static function slugify($text) { if (empty($text)) return ""; // replace non letter or digits by - @@ -828,28 +810,29 @@ static public function slugify($text) return $text; } - static function getHooksFile(){ + public static function getHooksFile() + { return AJXP_INSTALL_PATH."/".AJXP_DOCS_FOLDER."/hooks.json"; } - static function extractHooksToDoc(){ - + public static function extractHooksToDoc() + { $docFile = self::getHooksFile(); - if(is_file($docFile)){ + if (is_file($docFile)) { copy($docFile, $docFile.".bak"); $existingHooks = json_decode(file_get_contents($docFile), true); - }else{ + } else { $existingHooks = array(); } $allPhpFiles = glob_recursive(AJXP_INSTALL_PATH."/*.php"); $hooks = array(); - foreach($allPhpFiles as $phpFile){ + foreach ($allPhpFiles as $phpFile) { $fileContent = file($phpFile); - foreach($fileContent as $lineNumber => $line){ - if(preg_match_all('/AJXP_Controller::applyHook\("([^"]+)", (.*)\)/', $line, $matches)){ + foreach ($fileContent as $lineNumber => $line) { + if (preg_match_all('/AJXP_Controller::applyHook\("([^"]+)", (.*)\)/', $line, $matches)) { $names = $matches[1]; $params = $matches[2]; - foreach($names as $index => $hookName){ + foreach ($names as $index => $hookName) { if(!isSet($hooks[$hookName])) $hooks[$hookName] = array("TRIGGERS" => array(), "LISTENERS" => array()); $hooks[$hookName]["TRIGGERS"][] = array("FILE" => substr($phpFile, strlen(AJXP_INSTALL_PATH)), "LINE" => $lineNumber); $hooks[$hookName]["PARAMETER_SAMPLE"] = $params[$index]; @@ -860,7 +843,7 @@ static function extractHooksToDoc(){ } $registryHooks = AJXP_PluginsService::getInstance()->searchAllManifests("//hooks/serverCallback", "xml", false, false, true); $regHooks = array(); - foreach($registryHooks as $xmlHook){ + foreach ($registryHooks as $xmlHook) { $name = $xmlHook->getAttribute("hookName"); $method = $xmlHook->getAttribute("methodName"); $pluginId = $xmlHook->getAttribute("pluginId"); @@ -869,16 +852,16 @@ static function extractHooksToDoc(){ $regHooks[$name][] = array("PLUGIN_ID" => $pluginId, "METHOD" => $method); } - foreach($hooks as $h => $data) { + foreach ($hooks as $h => $data) { - if(isSet($regHooks[$h])){ + if (isSet($regHooks[$h])) { $data["LISTENERS"] = $regHooks[$h]; } - if(isSet($existingHooks[$h])){ + if (isSet($existingHooks[$h])) { $existingHooks[$h]["TRIGGERS"] = $data["TRIGGERS"]; $existingHooks[$h]["LISTENERS"] = $data["LISTENERS"]; $existingHooks[$h]["PARAMETER_SAMPLE"] = $data["PARAMETER_SAMPLE"]; - }else{ + } else { $existingHooks[$h] = $data; } } @@ -893,8 +876,8 @@ static function extractHooksToDoc(){ * * @return string Indented version of the original JSON string. */ - function prettyPrintJSON($json) { - + public function prettyPrintJSON($json) + { $result = ''; $pos = 0; $strLen = strlen($json); @@ -914,7 +897,7 @@ function prettyPrintJSON($json) { // If this character is the end of an element, // output a new line and indent the next line. - } else if(($char == '}' || $char == ']') && $outOfQuotes) { + } else if (($char == '}' || $char == ']') && $outOfQuotes) { $result .= $newLine; $pos --; for ($j=0; $j<$pos; $j++) { @@ -949,7 +932,7 @@ function prettyPrintJSON($json) { * @static * @return void */ - static function extractConfStringsFromManifests() + public static function extractConfStringsFromManifests() { $plugins = AJXP_PluginsService::getInstance()->getDetectedPlugins(); $plug = new AJXP_Plugin("", ""); @@ -992,7 +975,7 @@ static function extractConfStringsFromManifests() * @param string $createLanguage * @return void */ - static function updateAllI18nLibraries($createLanguage = "") + public static function updateAllI18nLibraries($createLanguage = "") { // UPDATE EN => OTHER LANGUAGES $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//i18n", "nodes"); @@ -1017,7 +1000,7 @@ static function updateAllI18nLibraries($createLanguage = "") * @param string $createLanguage * @return */ - static function updateI18nFiles($baseDir, $detectLanguages = true, $createLanguage = "") + public static function updateI18nFiles($baseDir, $detectLanguages = true, $createLanguage = "") { if (!is_dir($baseDir) || !is_file($baseDir . "/en.php")) return; if ($createLanguage != "" && !is_file($baseDir . "/$createLanguage.php")) { @@ -1048,7 +1031,7 @@ static function updateI18nFiles($baseDir, $detectLanguages = true, $createLangua * @param $reference * @return */ - static function updateI18nFromRef($filename, $reference) + public static function updateI18nFromRef($filename, $reference) { if (!is_file($filename)) return; include($filename); @@ -1091,7 +1074,7 @@ static function updateI18nFromRef($filename, $reference) * @param bool $showSkipLink * @return string */ - static function testResultsToTable($outputArray, $testedParams, $showSkipLink = true) + public static function testResultsToTable($outputArray, $testedParams, $showSkipLink = true) { $dumpRows = ""; $passedRows = array(); @@ -1110,8 +1093,7 @@ static function testResultsToTable($outputArray, $testedParams, $showSkipLink = "dump" => "Server Information", "passed" => "Other tests passed", ); - foreach ($outputArray as $item) - { + foreach ($outputArray as $item) { // A test is output only if it hasn't succeeded (doText returned FALSE) $result = $item["result"] ? "passed" : ($item["level"] == "info" ? "dump" : ($item["level"] == "warning" @@ -1130,7 +1112,7 @@ static function testResultsToTable($outputArray, $testedParams, $showSkipLink = * @param $testedParams * @return bool */ - static function runTests(&$outputArray, &$testedParams) + public static function runTests(&$outputArray, &$testedParams) { // At first, list folder in the tests subfolder chdir(AJXP_TESTS_FOLDER); @@ -1139,8 +1121,7 @@ static function runTests(&$outputArray, &$testedParams) $outputArray = array(); $testedParams = array(); $passed = true; - foreach ($files as $file) - { + foreach ($files as $file) { require_once($file); // Then create the test class $testName = str_replace(".php", "", substr($file, 5)); @@ -1176,8 +1157,7 @@ static function runTests(&$outputArray, &$testedParams) // NOW TRY THE PLUGIN TESTS chdir(AJXP_INSTALL_PATH . "/" . AJXP_PLUGINS_FOLDER); $files = glob('access.*/test.*.php'); - foreach ($files as $file) - { + foreach ($files as $file) { require_once($file); // Then create the test class list($accessFolder, $testFileName) = explode("/", $file); @@ -1211,7 +1191,7 @@ static function runTests(&$outputArray, &$testedParams) * @param $testedParams * @return void */ - static function testResultsToFile($outputArray, $testedParams) + public static function testResultsToFile($outputArray, $testedParams) { ob_start(); echo '$diagResults = '; @@ -1226,7 +1206,8 @@ static function testResultsToFile($outputArray, $testedParams) file_put_contents(TESTS_RESULT_FILE, $content); } - static function isStream($path){ + public static function isStream($path) + { $wrappers = stream_get_wrappers(); $wrappers_re = '(' . join('|', $wrappers) . ')'; return preg_match( "!^$wrappers_re://!", $path ) === 1; @@ -1239,13 +1220,13 @@ static function isStream($path){ * @param Boolean $skipCheck do not test for file existence before opening * @return Array */ - static function loadSerialFile($filePath, $skipCheck = false, $format="ser") + public static function loadSerialFile($filePath, $skipCheck = false, $format="ser") { $filePath = AJXP_VarsFilter::filter($filePath); $result = array(); - if($skipCheck){ + if ($skipCheck) { $fileLines = @file($filePath); - if($fileLines !== false) { + if ($fileLines !== false) { if($format == "ser") $result = unserialize(implode("", $fileLines)); else if($format == "json") $result = json_decode(implode("", $fileLines), true); } @@ -1269,12 +1250,12 @@ static function loadSerialFile($filePath, $skipCheck = false, $format="ser") * @param string $format * @throws Exception */ - static function saveSerialFile($filePath, $value, $createDir = true, $silent = false, $format="ser", $jsonPrettyPrint = false) + public static function saveSerialFile($filePath, $value, $createDir = true, $silent = false, $format="ser", $jsonPrettyPrint = false) { $filePath = AJXP_VarsFilter::filter($filePath); - if ($createDir && !is_dir(dirname($filePath))){ + if ($createDir && !is_dir(dirname($filePath))) { @mkdir(dirname($filePath), 0755, true); - if(!is_dir(dirname($filePath))){ + if (!is_dir(dirname($filePath))) { // Creation failed if($silent) return; else throw new Exception("[AJXP_Utils::saveSerialFile] Cannot write into " . dirname(dirname($filePath))); @@ -1283,7 +1264,7 @@ static function saveSerialFile($filePath, $value, $createDir = true, $silent = f try { $fp = fopen($filePath, "w"); if($format == "ser") $content = serialize($value); - else if($format == "json") { + else if ($format == "json") { $content = json_encode($value); if($jsonPrettyPrint) $content = self::prettyPrintJSON($content); } @@ -1433,10 +1414,11 @@ public static function safeIniSet($paramName, $paramValue) * @param string $url * @return bool|mixed|string */ - public static function getRemoteContent($url){ - if(ini_get("allow_url_fopen")){ + public static function getRemoteContent($url) + { + if (ini_get("allow_url_fopen")) { return file_get_contents($url); - }else if(function_exists("curl_init")){ + } else if (function_exists("curl_init")) { $ch = curl_init(); $timeout = 30; // set to zero for no timeout curl_setopt ($ch, CURLOPT_URL, $url); @@ -1445,7 +1427,7 @@ public static function getRemoteContent($url){ $return = curl_exec($ch); curl_close($ch); return $return; - }else{ + } else { $i = parse_url($url); $httpClient = new HttpClient($i["host"]); $httpClient->timeout = 30; @@ -1453,94 +1435,92 @@ public static function getRemoteContent($url){ } } - public static function parseStandardFormParameters(&$repDef, &$options, $userId = null, $prefix = "DRIVER_OPTION_", $binariesContext = null){ - - if($binariesContext === null){ + public static function parseStandardFormParameters(&$repDef, &$options, $userId = null, $prefix = "DRIVER_OPTION_", $binariesContext = null) + { + if ($binariesContext === null) { $binariesContext = array("USER" => (AuthService::getLoggedUser()!= null)?AuthService::getLoggedUser()->getId():"shared"); } $replicationGroups = array(); $switchesGroups = array(); - foreach ($repDef as $key => $value) - { + foreach ($repDef as $key => $value) { $value = SystemTextEncoding::magicDequote($value); if( ( ( !empty($prefix) && strpos($key, $prefix)!== false && strpos($key, $prefix)==0 ) || empty($prefix) ) && strpos($key, "ajxptype") === false && strpos($key, "_original_binary") === false && strpos($key, "_replication") === false && strpos($key, "_checkbox") === false){ - if(isSet($repDef[$key."_ajxptype"])){ + if (isSet($repDef[$key."_ajxptype"])) { $type = $repDef[$key."_ajxptype"]; - if($type == "boolean"){ + if ($type == "boolean") { $value = ($value == "true"?true:false); - }else if($type == "integer"){ + } else if ($type == "integer") { $value = intval($value); - }else if($type == "array"){ + } else if ($type == "array") { $value = explode(",", $value); - }else if($type == "password" && $userId!=null){ - if (trim($value != "") && function_exists('mcrypt_encrypt')) - { + } else if ($type == "password" && $userId!=null) { + if (trim($value != "") && function_exists('mcrypt_encrypt')) { // The initialisation vector is only required to avoid a warning, as ECB ignore IV $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); // We encode as base64 so if we need to store the result in a database, it can be stored in text column $value = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($userId."\1CDAFx¨op#"), $value, MCRYPT_MODE_ECB, $iv)); } - }else if($type == "binary" && $binariesContext !== null){ - if(!empty($value)){ - if($value == "ajxp-remove-original"){ - if(!empty($repDef[$key."_original_binary"])){ + } else if ($type == "binary" && $binariesContext !== null) { + if (!empty($value)) { + if ($value == "ajxp-remove-original") { + if (!empty($repDef[$key."_original_binary"])) { ConfService::getConfStorageImpl()->deleteBinary($binariesContext, $repDef[$key."_original_binary"]); } $value = ""; - }else{ + } else { $file = AJXP_Utils::getAjxpTmpDir()."/".$value; - if(file_exists($file)){ + if (file_exists($file)) { $id= !empty($repDef[$key."_original_binary"]) ? $repDef[$key."_original_binary"] : null; $id=ConfService::getConfStorageImpl()->saveBinary($binariesContext, $file, $id); $value = $id; } } - }else if(!empty($repDef[$key."_original_binary"])){ + } else if (!empty($repDef[$key."_original_binary"])) { $value = $repDef[$key."_original_binary"]; } - }else if(strpos($type,"group_switch:") === 0){ + } else if (strpos($type,"group_switch:") === 0) { $tmp = explode(":", $type); $gSwitchName = $tmp[1]; $switchesGroups[substr($key, strlen($prefix))] = $gSwitchName; - }else if($type == "text/json"){ + } else if ($type == "text/json") { $value = json_decode($value, true); } - if(!in_array($type, array("textarea", "boolean", "text/json"))){ + if (!in_array($type, array("textarea", "boolean", "text/json"))) { $value = AJXP_Utils::sanitize($value, AJXP_SANITIZE_HTML); } unset($repDef[$key."_ajxptype"]); } - if(isSet($repDef[$key."_checkbox"])){ + if (isSet($repDef[$key."_checkbox"])) { $checked = $repDef[$key."_checkbox"] == "checked"; unset($repDef[$key."_checkbox"]); if(!$checked) continue; } - if(isSet($repDef[$key."_replication"])){ + if (isSet($repDef[$key."_replication"])) { $repKey = $repDef[$key."_replication"]; if(!is_array($replicationGroups[$repKey])) $replicationGroups[$repKey] = array(); $replicationGroups[$repKey][] = $key; } $options[substr($key, strlen($prefix))] = $value; unset($repDef[$key]); - }else{ - if($key == "DISPLAY"){ + } else { + if ($key == "DISPLAY") { $value = SystemTextEncoding::fromUTF8(AJXP_Utils::securePath($value)); } $repDef[$key] = $value; } } // DO SOMETHING WITH REPLICATED PARAMETERS? - if(count($switchesGroups)){ - foreach($switchesGroups as $fieldName => $groupName){ - if(isSet($options[$fieldName])){ + if (count($switchesGroups)) { + foreach ($switchesGroups as $fieldName => $groupName) { + if (isSet($options[$fieldName])) { $gValues = array(); $radic = $groupName."_".$options[$fieldName]."_"; - foreach($options as $optN => $optV){ - if(strpos($optN, $radic) === 0){ + foreach ($options as $optN => $optV) { + if (strpos($optN, $radic) === 0) { $newName = substr($optN, strlen($radic)); $gValues[$newName] = $optV; } @@ -1553,21 +1533,22 @@ public static function parseStandardFormParameters(&$repDef, &$options, $userId } - public static function cleanDibiDriverParameters($params){ + public static function cleanDibiDriverParameters($params) + { if(!is_array($params)) return $params; $value = $params["group_switch_value"]; - if(isSet($value)){ - if($value == "core"){ + if (isSet($value)) { + if ($value == "core") { $bootStorage = ConfService::getBootConfStorageImpl(); $configs = $bootStorage->loadPluginConfig("core", "conf"); $params = $configs["DIBI_PRECONFIGURATION"]; - if(!is_array($params)){ + if (!is_array($params)) { throw new Exception("Empty SQL default connexion, there is something wrong with your setup! You may have switch to an SQL-based plugin without defining a connexion."); } - }else{ + } else { unset($params["group_switch_value"]); } - foreach($params as $k => $v){ + foreach ($params as $k => $v) { $params[array_pop(explode("_", $k, 2))] = AJXP_VarsFilter::filter($v); unset($params[$k]); } @@ -1575,11 +1556,12 @@ public static function cleanDibiDriverParameters($params){ return $params; } - public static function runCreateTablesQuery($p, $file){ + public static function runCreateTablesQuery($p, $file) + { require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); $result = array(); - if($p["driver"] == "sqlite" || $p["driver"] == "sqlite3"){ - if(!file_exists(dirname($p["database"]))){ + if ($p["driver"] == "sqlite" || $p["driver"] == "sqlite3") { + if (!file_exists(dirname($p["database"]))) { @mkdir(dirname($p["database"]), 0755, true); } dibi::connect($p); @@ -1587,32 +1569,32 @@ public static function runCreateTablesQuery($p, $file){ $sql = file_get_contents($file); dibi::begin(); $parts = explode("CREATE TABLE", $sql); - foreach($parts as $createPart){ + foreach ($parts as $createPart) { if(empty($createPart)) continue; $sqlPart = trim("CREATE TABLE".$createPart); - try{ + try { dibi::nativeQuery($sqlPart); $resKey = str_replace("\n", "", substr($sqlPart, 0, 50))."..."; $result[] = "OK: $resKey executed successfully"; - }catch (DibiException $e){ + } catch (DibiException $e) { $result[] = "ERROR! $sqlPart failed"; } } $message = implode("\n", $result); dibi::commit(); dibi::disconnect(); - }else{ + } else { dibi::connect($p); $sql = file_get_contents($file); $parts = explode("CREATE TABLE", $sql); - foreach($parts as $createPart){ + foreach ($parts as $createPart) { if(empty($createPart)) continue; $sqlPart = trim("CREATE TABLE".$createPart); - try{ + try { dibi::nativeQuery($sqlPart); $resKey = str_replace("\n", "", substr($sqlPart, 0, 50))."..."; $result[] = "OK: $resKey executed successfully"; - }catch (DibiException $e){ + } catch (DibiException $e) { $result[] = "ERROR! $sqlPart failed"; } } @@ -1640,8 +1622,8 @@ public static function runCreateTablesQuery($p, $file){ * This implementation of PBKDF2 was originally created by https://defuse.ca * With improvements by http://www.variations-of-shadow.com */ - static function pbkdf2_apply($algorithm, $password, $salt, $count, $key_length, $raw_output = false) { - + public static function pbkdf2_apply($algorithm, $password, $salt, $count, $key_length, $raw_output = false) + { $algorithm = strtolower($algorithm); if(!in_array($algorithm, hash_algos(), true)) @@ -1654,7 +1636,7 @@ static function pbkdf2_apply($algorithm, $password, $salt, $count, $key_length, $output = ""; - for($i = 1; $i <= $block_count; $i++) { + for ($i = 1; $i <= $block_count; $i++) { // $i encoded as 4 bytes, big endian. $last = $salt . pack("N", $i); // first iteration @@ -1676,21 +1658,22 @@ static function pbkdf2_apply($algorithm, $password, $salt, $count, $key_length, // Compares two strings $a and $b in length-constant time. - static function pbkdf2_slow_equals($a, $b) { + public static function pbkdf2_slow_equals($a, $b) + { $diff = strlen($a) ^ strlen($b); - for($i = 0; $i < strlen($a) && $i < strlen($b); $i++) - { + for ($i = 0; $i < strlen($a) && $i < strlen($b); $i++) { $diff |= ord($a[$i]) ^ ord($b[$i]); } return $diff === 0; } - static function pbkdf2_validate_password($password, $correct_hash) { + public static function pbkdf2_validate_password($password, $correct_hash) + { $params = explode(":", $correct_hash); - if(count($params) < HASH_SECTIONS){ - if(strlen($correct_hash) == 32 && count($params) == 1){ + if (count($params) < HASH_SECTIONS) { + if (strlen($correct_hash) == 32 && count($params) == 1) { return md5($password) == $correct_hash; } return false; @@ -1703,7 +1686,7 @@ static function pbkdf2_validate_password($password, $correct_hash) { $params[HASH_ALGORITHM_INDEX], $password, $params[HASH_SALT_INDEX], - (int)$params[HASH_ITERATION_INDEX], + (int) $params[HASH_ITERATION_INDEX], strlen($pbkdf2), true ) @@ -1711,7 +1694,8 @@ static function pbkdf2_validate_password($password, $correct_hash) { } - static function pbkdf2_create_hash($password) { + public static function pbkdf2_create_hash($password) + { // format: algorithm:iterations:salt:hash $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTE_SIZE, MCRYPT_DEV_URANDOM)); return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" . $salt . ":" . @@ -1730,8 +1714,9 @@ static function pbkdf2_create_hash($password) { * @param int [optional] $length length of password, default 24 (144 Bit) * @return string password */ - static function generateRandomString($length = 24) { - if(function_exists('openssl_random_pseudo_bytes') && USE_OPENSSL_RANDOM) { + public static function generateRandomString($length = 24) + { + if (function_exists('openssl_random_pseudo_bytes') && USE_OPENSSL_RANDOM) { $password = base64_encode(openssl_random_pseudo_bytes($length, $strong)); if($strong == TRUE) return substr(str_replace(array("/","+"), "", $password), 0, $length); //base64 is about 33% longer, so we need to truncate the result @@ -1751,4 +1736,4 @@ static function generateRandomString($length = 24) { return $password; } -} \ No newline at end of file +} diff --git a/core/src/core/classes/class.AJXP_VarsFilter.php b/core/src/core/classes/class.AJXP_VarsFilter.php index 27a817e47a..3f7895b569 100644 --- a/core/src/core/classes/class.AJXP_VarsFilter.php +++ b/core/src/core/classes/class.AJXP_VarsFilter.php @@ -1,80 +1,81 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * Standard values filtering used in the core. - * @static - * @package AjaXplorer - * @subpackage Core - */ -class AJXP_VarsFilter { - - /** - * Filter the very basic keywords from the XML : AJXP_USER, AJXP_INSTALL_PATH, AJXP_DATA_PATH - * Calls the vars.filter hooks. - * @static - * @param $value - * @return mixed|string - */ - public static function filter($value){ - if(is_string($value) && strpos($value, "AJXP_USER")!==false){ - if(AuthService::usersEnabled()){ - $loggedUser = AuthService::getLoggedUser(); - if($loggedUser != null){ - if($loggedUser->hasParent() && $loggedUser->getResolveAsParent()){ - $loggedUserId = $loggedUser->getParent(); - }else{ - $loggedUserId = $loggedUser->getId(); - } - $value = str_replace("AJXP_USER", $loggedUserId, $value); - }else{ - return ""; - } - }else{ - $value = str_replace("AJXP_USER", "shared", $value); - } - } - if(is_string($value) && strpos($value, "AJXP_GROUP_PATH")!==false){ - if(AuthService::usersEnabled()){ - $loggedUser = AuthService::getLoggedUser(); - if($loggedUser != null){ - $gPath = $loggedUser->getGroupPath(); - $value = str_replace("AJXP_GROUP_PATH_FLAT", str_replace("/", "_", trim($gPath, "/")), $value); - $value = str_replace("AJXP_GROUP_PATH", $gPath, $value); - }else{ - return ""; - } - }else{ - $value = str_replace(array("AJXP_GROUP_PATH", "AJXP_GROUP_PATH_FLAT"), "shared", $value); - } - } - if(is_string($value) && strpos($value, "AJXP_INSTALL_PATH") !== false){ - $value = str_replace("AJXP_INSTALL_PATH", AJXP_INSTALL_PATH, $value); - } - if(is_string($value) && strpos($value, "AJXP_DATA_PATH") !== false){ - $value = str_replace("AJXP_DATA_PATH", AJXP_DATA_PATH, $value); - } - $tab = array(&$value); - AJXP_Controller::applyIncludeHook("vars.filter", $tab); - return $value; - } -} + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * Standard values filtering used in the core. + * @static + * @package AjaXplorer + * @subpackage Core + */ +class AJXP_VarsFilter +{ + /** + * Filter the very basic keywords from the XML : AJXP_USER, AJXP_INSTALL_PATH, AJXP_DATA_PATH + * Calls the vars.filter hooks. + * @static + * @param $value + * @return mixed|string + */ + public static function filter($value) + { + if (is_string($value) && strpos($value, "AJXP_USER")!==false) { + if (AuthService::usersEnabled()) { + $loggedUser = AuthService::getLoggedUser(); + if ($loggedUser != null) { + if ($loggedUser->hasParent() && $loggedUser->getResolveAsParent()) { + $loggedUserId = $loggedUser->getParent(); + } else { + $loggedUserId = $loggedUser->getId(); + } + $value = str_replace("AJXP_USER", $loggedUserId, $value); + } else { + return ""; + } + } else { + $value = str_replace("AJXP_USER", "shared", $value); + } + } + if (is_string($value) && strpos($value, "AJXP_GROUP_PATH")!==false) { + if (AuthService::usersEnabled()) { + $loggedUser = AuthService::getLoggedUser(); + if ($loggedUser != null) { + $gPath = $loggedUser->getGroupPath(); + $value = str_replace("AJXP_GROUP_PATH_FLAT", str_replace("/", "_", trim($gPath, "/")), $value); + $value = str_replace("AJXP_GROUP_PATH", $gPath, $value); + } else { + return ""; + } + } else { + $value = str_replace(array("AJXP_GROUP_PATH", "AJXP_GROUP_PATH_FLAT"), "shared", $value); + } + } + if (is_string($value) && strpos($value, "AJXP_INSTALL_PATH") !== false) { + $value = str_replace("AJXP_INSTALL_PATH", AJXP_INSTALL_PATH, $value); + } + if (is_string($value) && strpos($value, "AJXP_DATA_PATH") !== false) { + $value = str_replace("AJXP_DATA_PATH", AJXP_DATA_PATH, $value); + } + $tab = array(&$value); + AJXP_Controller::applyIncludeHook("vars.filter", $tab); + return $value; + } +} diff --git a/core/src/core/classes/class.AJXP_XMLWriter.php b/core/src/core/classes/class.AJXP_XMLWriter.php index 3f010b6e0d..d024894917 100644 --- a/core/src/core/classes/class.AJXP_XMLWriter.php +++ b/core/src/core/classes/class.AJXP_XMLWriter.php @@ -1,634 +1,646 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * XML output Generator - * @package AjaXplorer - * @subpackage Core - */ -class AJXP_XMLWriter -{ - static $headerSent = false; - - /** - * Output Headers, XML tag and a root node - * @static - * @param string $docNode - * @param array $attributes - */ - static function header($docNode="tree", $attributes=array()) - { - if(self::$headerSent !== false && self::$headerSent == $docNode) return ; - header('Content-Type: text/xml; charset=UTF-8'); - header('Cache-Control: no-cache'); - print(''); - $attString = ""; - if(count($attributes)){ - foreach ($attributes as $name=>$value){ - $attString.="$name=\"$value\" "; - } - } - self::$headerSent = $docNode; - print("<$docNode $attString>"); - - } - /** - * Outputs a closing root not () - * @static - * @param string $docNode - * @return void - */ - static function close($docNode="tree") - { - print(""); - } - - /** - * @static - * @param string $data - * @param bool $print - * @return string - */ - static function write($data, $print){ - if($print) { - print($data); - return ""; - }else{ - return $data; - } - } - - /** - * Ouput the tag - * @static - * @param integer $count - * @param integer $currentPage - * @param integer $totalPages - * @param integer $dirsCount - * @return void - */ - static function renderPaginationData($count, $currentPage, $totalPages, $dirsCount = -1){ - $string = ''; - AJXP_XMLWriter::write($string, true); - } - /** - * Prints out the XML headers and preamble, then an open node - * @static - * @param $nodeName - * @param $nodeLabel - * @param $isLeaf - * @param array $metaData - * @return void - */ - static function renderHeaderNode($nodeName, $nodeLabel, $isLeaf, $metaData = array()){ - header('Content-Type: text/xml; charset=UTF-8'); - header('Cache-Control: no-cache'); - print(''); - self::$headerSent = "tree"; - AJXP_XMLWriter::renderNode($nodeName, $nodeLabel, $isLeaf, $metaData, false); - } - - /** - * @static - * @param AJXP_Node $ajxpNode - * @return void - */ - static function renderAjxpHeaderNode($ajxpNode){ - header('Content-Type: text/xml; charset=UTF-8'); - header('Cache-Control: no-cache'); - print(''); - self::$headerSent = "tree"; - self::renderAjxpNode($ajxpNode, false); - } - - /** - * The basic node - * @static - * @param string $nodeName - * @param string $nodeLabel - * @param bool $isLeaf - * @param array $metaData - * @param bool $close - * @param bool $print - * @return void|string - */ - static function renderNode($nodeName, $nodeLabel, $isLeaf, $metaData = array(), $close=true, $print = true){ - $string = " $value){ - $value = AJXP_Utils::xmlEntities($value, true); - $string .= " $key=\"$value\""; - } - if($close){ - $string .= "/>"; - }else{ - $string .= ">"; - } - return AJXP_XMLWriter::write($string, $print); - } - - /** - * @static - * @param AJXP_Node $ajxpNode - * @param bool $close - * @param bool $print - * @return void|string - */ - static function renderAjxpNode($ajxpNode, $close = true, $print = true){ - return AJXP_XMLWriter::renderNode( - $ajxpNode->getPath(), - $ajxpNode->getLabel(), - $ajxpNode->isLeaf(), - $ajxpNode->metadata, - $close, - $print); - } - - /** - * Render a node with arguments passed as array - * @static - * @param $array - * @return void - */ - static function renderNodeArray($array){ - self::renderNode($array[0],$array[1],$array[2],$array[3]); - } - /** - * Error Catcher for PHP errors. Depending on the SERVER_DEBUG config - * shows the file/line info or not. - * @static - * @param $code - * @param $message - * @param $fichier - * @param $ligne - * @param $context - * @return - */ - static function catchError($code, $message, $fichier, $ligne, $context){ - if(error_reporting() == 0) return ; - if(ConfService::getConf("SERVER_DEBUG")){ - $message = "$message in $fichier (l.$ligne)"; - } - try{ - AJXP_Logger::logAction("error", array("message" => $message)); - }catch(Exception $e){ - // This will probably trigger a double exception! - echo "
    Error in error";
    -            debug_print_backtrace();
    -            echo "
    "; - die("Recursive exception. Original error was : ".$message. " in $fichier , line $ligne"); - } - if(!headers_sent()) AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, SystemTextEncoding::toUTF8($message), true); - AJXP_XMLWriter::close(); - exit(1); - } - - /** - * Catch exceptions, @see catchError - * @param Exception $exception - */ - static function catchException($exception){ - try{ - AJXP_XMLWriter::catchError($exception->getCode(), SystemTextEncoding::fromUTF8($exception->getMessage()), $exception->getFile(), $exception->getLine(), null); - }catch(Exception $innerEx){ - print get_class($innerEx)." thrown within the exception handler! Message was: ".$innerEx->getMessage()." in ".$innerEx->getFile()." on line ".$innerEx->getLine()." ".$innerEx->getTraceAsString(); - } - } - /** - * Dynamically replace XML keywords with their live values. - * AJXP_SERVER_ACCESS, AJXP_MIMES_*,AJXP_ALL_MESSAGES, etc. - * @static - * @param string $xml - * @param bool $stripSpaces - * @return mixed - */ - static function replaceAjxpXmlKeywords($xml, $stripSpaces = false){ - $messages = ConfService::getMessages(); - $confMessages = ConfService::getMessagesConf(); - $matches = array(); - if(isSet($_SESSION["AJXP_SERVER_PREFIX_URI"])){ - //$xml = str_replace("AJXP_THEME_FOLDER", $_SESSION["AJXP_SERVER_PREFIX_URI"].AJXP_THEME_FOLDER, $xml); - $xml = str_replace("AJXP_SERVER_ACCESS", $_SESSION["AJXP_SERVER_PREFIX_URI"].AJXP_SERVER_ACCESS, $xml); - }else{ - //$xml = str_replace("AJXP_THEME_FOLDER", AJXP_THEME_FOLDER, $xml); - $xml = str_replace("AJXP_SERVER_ACCESS", AJXP_SERVER_ACCESS, $xml); - } - $xml = str_replace("AJXP_MIMES_EDITABLE", AJXP_Utils::getAjxpMimes("editable"), $xml); - $xml = str_replace("AJXP_MIMES_IMAGE", AJXP_Utils::getAjxpMimes("image"), $xml); - $xml = str_replace("AJXP_MIMES_AUDIO", AJXP_Utils::getAjxpMimes("audio"), $xml); - $xml = str_replace("AJXP_MIMES_ZIP", AJXP_Utils::getAjxpMimes("zip"), $xml); - $authDriver = ConfService::getAuthDriverImpl(); - if($authDriver != NULL){ - $loginRedirect = $authDriver->getLoginRedirect(); - $xml = str_replace("AJXP_LOGIN_REDIRECT", ($loginRedirect!==false?"'".$loginRedirect."'":"false"), $xml); - } - $xml = str_replace("AJXP_REMOTE_AUTH", "false", $xml); - $xml = str_replace("AJXP_NOT_REMOTE_AUTH", "true", $xml); - $xml = str_replace("AJXP_ALL_MESSAGES", "MessageHash=".json_encode(ConfService::getMessages()).";", $xml); - - if(preg_match_all("/AJXP_MESSAGE(\[.*?\])/", $xml, $matches, PREG_SET_ORDER)){ - foreach($matches as $match){ - $messId = str_replace("]", "", str_replace("[", "", $match[1])); - $xml = str_replace("AJXP_MESSAGE[$messId]", $messages[$messId], $xml); - } - } - if(preg_match_all("/CONF_MESSAGE(\[.*?\])/", $xml, $matches, PREG_SET_ORDER)){ - foreach($matches as $match){ - $messId = str_replace(array("[", "]"), "", $match[1]); - $message = $messId; - if(array_key_exists($messId, $confMessages)){ - $message = $confMessages[$messId]; - } - $xml = str_replace("CONF_MESSAGE[$messId]", $message, $xml); - } - } - if(preg_match_all("/MIXIN_MESSAGE(\[.*?\])/", $xml, $matches, PREG_SET_ORDER)){ - foreach($matches as $match){ - $messId = str_replace(array("[", "]"), "", $match[1]); - $message = $messId; - if(array_key_exists($messId, $confMessages)){ - $message = $confMessages[$messId]; - } - $xml = str_replace("MIXIN_MESSAGE[$messId]", $message, $xml); - } - } - if($stripSpaces){ - $xml = preg_replace("/[\n\r]?/", "", $xml); - $xml = preg_replace("/\t/", " ", $xml); - } - $xml = str_replace(array('xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"','xsi:noNamespaceSchemaLocation="file:../core.ajaxplorer/ajxp_registry.xsd"'), "", $xml); - $tab = array(&$xml); - AJXP_Controller::applyIncludeHook("xml.filter", $tab); - return $xml; - } - /** - * Send a XML instruction for refreshing the list - * @static - * @param string $nodePath - * @param string $pendingSelection - * @param bool $print - * @return string - */ - static function reloadDataNode($nodePath="", $pendingSelection="", $print = true){ - $nodePath = AJXP_Utils::xmlEntities($nodePath, true); - $pendingSelection = AJXP_Utils::xmlEntities($pendingSelection, true); - return AJXP_XMLWriter::write("", $print); - } - - - /** - * Send a XML instruction for refreshing the list - * @static - * @param string $nodePath - * @param string $pendingSelection - * @param bool $print - * @return string - */ - static function writeNodesDiff($diffNodes, $print = false){ - $mess = ConfService::getMessages(); - $buffer = ""; - if(isSet($diffNodes["REMOVE"]) && count($diffNodes["REMOVE"])){ - $buffer .= ""; - foreach($diffNodes["REMOVE"] as $nodePath){ - $nodePath = AJXP_Utils::xmlEntities($nodePath, true); - $buffer .= ""; - } - $buffer .= ""; - } - if(isSet($diffNodes["ADD"]) && count($diffNodes["ADD"])){ - $buffer .= ""; - foreach($diffNodes["ADD"] as $ajxpNode){ - $ajxpNode->loadNodeInfo(false, false, "all"); - if(!empty($ajxpNode->metaData["mimestring_id"]) && array_key_exists($ajxpNode->metaData["mimestring_id"], $mess)){ - $ajxpNode->mergeMetadata(array("mimestring" => $mess[$ajxpNode->metaData["mimestring_id"]])); - } - $buffer .= self::renderAjxpNode($ajxpNode, true, false); - } - $buffer .= ""; - } - if(isSet($diffNodes["UPDATE"]) && count($diffNodes["UPDATE"])){ - $buffer .= ""; - foreach($diffNodes["UPDATE"] as $originalPath => $ajxpNode){ - $ajxpNode->loadNodeInfo(false, false, "all"); - if(!empty($ajxpNode->metaData["mimestring_id"]) && array_key_exists($ajxpNode->metaData["mimestring_id"], $mess)){ - $ajxpNode->mergeMetadata(array("mimestring" => $mess[$ajxpNode->metaData["mimestring_id"]])); - } - $ajxpNode->original_path = $originalPath; - $buffer .= self::renderAjxpNode($ajxpNode, true, false); - } - $buffer .= ""; - } - $buffer .= ""; - return AJXP_XMLWriter::write($buffer, $print); - - /* - $nodePath = AJXP_Utils::xmlEntities($nodePath, true); - $pendingSelection = AJXP_Utils::xmlEntities($pendingSelection, true); - return AJXP_XMLWriter::write("", $print); - */ - } - - - /** - * Send a XML instruction for refreshing the repositories list - * @static - * @param bool $print - * @return string - */ - static function reloadRepositoryList($print = true){ - return AJXP_XMLWriter::write("", $print); - } - /** - * Outputs a tag - * @static - * @param bool $print - * @return string - */ - static function requireAuth($print = true) - { - return AJXP_XMLWriter::write("", $print); - } - /** - * Triggers a background action client side - * @static - * @param $actionName - * @param $parameters - * @param $messageId - * @param bool $print - * @param int $delay - * @return string - */ - static function triggerBgAction($actionName, $parameters, $messageId, $print=true, $delay = 0){ - $messageId = AJXP_Utils::xmlEntities($messageId); - $data = AJXP_XMLWriter::write("", $print); - foreach ($parameters as $paramName=>$paramValue){ - $paramValue = AJXP_Utils::xmlEntities($paramValue); - $data .= AJXP_XMLWriter::write("", $print); - } - $data .= AJXP_XMLWriter::write("", $print); - return $data; - } - - static function triggerBgJSAction($jsCode, $messageId, $print=true, $delay = 0){ - $data = AJXP_XMLWriter::write("", $print); - $data .= AJXP_XMLWriter::write("", $print); - $data .= AJXP_XMLWriter::write("", $print); - return $data; - } - - /** - * List all bookmmarks as XML - * @static - * @param $allBookmarks - * @param bool $print - * @param string $format legacy|node_list - * @return string - */ - static function writeBookmarks($allBookmarks, $print = true, $format = "legacy") - { - if($format == "node_list") { - $driver = ConfService::loadRepositoryDriver(); - if(!is_a($driver, "AjxpWrapperProvider")){ - $driver = false; - } - } - $buffer = ""; - foreach ($allBookmarks as $bookmark) - { - $path = ""; $title = ""; - if(is_array($bookmark)){ - $path = $bookmark["PATH"]; - $title = $bookmark["TITLE"]; - }else if(is_string($bookmark)){ - $path = $bookmark; - $title = basename($bookmark); - } - if($format == "node_list"){ - if($driver){ - $node = new AJXP_Node($driver->getResourceUrl($path)); - $buffer .= AJXP_XMLWriter::renderAjxpNode($node, true, false); - }else{ - $buffer .= AJXP_XMLWriter::renderNode($path, $title, false, array('icon' => "mime_empty.png"), true, false); - } - }else{ - $buffer .= ""; - } - } - if($print) print $buffer; - else return $buffer; - } - /** - * Utilitary for generating a tag for the FilesList component - * @static - * @param $config - * @return void - */ - static function sendFilesListComponentConfig($config){ - if(is_string($config)){ - print("$config"); - } - } - /** - * Send a success or error message to the client. - * @static - * @param $logMessage - * @param $errorMessage - * @param bool $print - * @return string - */ - static function sendMessage($logMessage, $errorMessage, $print = true) - { - $messageType = ""; - $message = ""; - if($errorMessage == null) - { - $messageType = "SUCCESS"; - $message = AJXP_Utils::xmlContentEntities($logMessage); - } - else - { - $messageType = "ERROR"; - $message = AJXP_Utils::xmlContentEntities($errorMessage); - } - return AJXP_XMLWriter::write("".$message."", $print); - } - /** - * Writes the user data as XML - * @static - * @param null $userObject - * @param bool $details - * @return void - */ - static function sendUserData($userObject = null, $details=false){ - print(AJXP_XMLWriter::getUserXML($userObject, $details)); - } - /** - * Extract all the user data and put it in XML - * @static - * @param null $userObject - * @param bool $details - * @return string - */ - static function getUserXML($userObject = null, $details=false) - { - $buffer = ""; - $loggedUser = AuthService::getLoggedUser(); - $confDriver = ConfService::getConfStorageImpl(); - if($userObject != null) $loggedUser = $userObject; - if(!AuthService::usersEnabled()){ - $buffer.=""; - if(!$details){ - $buffer.=""; - } - $buffer.= AJXP_XMLWriter::writeRepositoriesData(null, $details); - $buffer.=""; - }else if($loggedUser != null){ - $lock = $loggedUser->getLock(); - $buffer.="id."\">"; - if(!$details){ - $buffer.="canWrite(ConfService::getCurrentRepositoryId())?"1":"0")."\" read=\"".($loggedUser->canRead(ConfService::getCurrentRepositoryId())?"1":"0")."\"/>"; - }else{ - $buffer .= ""; - foreach ($loggedUser->getRoles() as $roleId => $boolean){ - if($boolean === true) $buffer.= ""; - } - $buffer .= ""; - } - $buffer.= AJXP_XMLWriter::writeRepositoriesData($loggedUser, $details); - $buffer.=""; - $preferences = $confDriver->getExposedPreferences($loggedUser); - foreach($preferences as $prefName => $prefData){ - $atts = ""; - if(isSet($prefData["exposed"]) && $prefData["exposed"] == true){ - foreach($prefData as $k => $v) { - if($k=="name") continue; - if($k == "value") $k = "default"; - $atts .= "$k='$v' "; - } - } - if(isset($prefData["pluginId"])){ - $atts .= "pluginId='".$prefData["pluginId"]."' "; - } - if($prefData["type"] == "string"){ - $buffer.=""; - }else if($prefData["type"] == "json"){ - $buffer.=""; - } - } - $buffer.=""; - $buffer.="isAdmin()?"1":"0")."\" ".($lock!==false?"lock=\"$lock\"":"")."/>"; - $bMarks = $loggedUser->getBookmarks(); - if(count($bMarks)){ - $buffer.= "".AJXP_XMLWriter::writeBookmarks($bMarks, false).""; - } - $buffer.=""; - } - return $buffer; - } - /** - * Write the repositories access rights in XML format - * @static - * @param AbstractAjxpUser|null $loggedUser - * @param bool $details - * @return string - */ - static function writeRepositoriesData($loggedUser, $details=false){ - $st = ""; - $streams = ConfService::detectRepositoryStreams(false); - foreach(ConfService::getAccessibleRepositories($loggedUser, $details, false) as $repoId => $repoObject){ - $toLast = false; - if($repoObject->getAccessType()=="ajxp_conf"){ - if(AuthService::usersEnabled() && !$loggedUser->isAdmin())continue; - $toLast = true; - } - $rightString = ""; - if($details){ - $rightString = " r=\"".($loggedUser->canRead($repoId)?"1":"0")."\" w=\"".($loggedUser->canWrite($repoId)?"1":"0")."\""; - } - $streamString = ""; - if(in_array($repoObject->accessType, $streams)){ - $streamString = "allowCrossRepositoryCopy=\"true\""; - } - if($repoObject->getUniqueUser()){ - $streamString .= " user_editable_repository=\"true\" "; - } - $slugString = ""; - $slug = $repoObject->getSlug(); - if(!empty($slug)){ - $slugString = "repositorySlug=\"$slug\""; - } - $isSharedString = ""; - if($repoObject->hasOwner()){ - $uId = $repoObject->getOwner(); - $uObject = ConfService::getConfStorageImpl()->createUserObject($uId); - $label = $uObject->personalRole->filterParameterValue("core.conf", "USER_DISPLAY_NAME", AJXP_REPO_SCOPE_ALL, $uId); - $isSharedString = "owner='".$label."'"; - } - $descTag = ""; - $description = $repoObject->getDescription(); - if(!empty($description)){ - $descTag = ''.AJXP_Utils::xmlEntities($description, true).''; - } - $xmlString = "accessType."\" id=\"".$repoId."\"$rightString $streamString $slugString $isSharedString>".$descTag.$repoObject->getClientSettings().""; - if($toLast){ - $lastString = $xmlString; - }else{ - $st .= $xmlString; - } - } - - if(isSet($lastString)){ - $st.= $lastString; - } - $st .= ""; - return $st; - } - /** - * Writes a tag - * @static - * @param integer $result - * @param string $rememberLogin - * @param string $rememberPass - * @param string $secureToken - * @return void - */ - static function loggingResult($result, $rememberLogin="", $rememberPass = "", $secureToken="") - { - $remString = ""; - if($rememberPass != "" && $rememberLogin!= ""){ - $remString = " remember_login=\"$rememberLogin\" remember_pass=\"$rememberPass\""; - } - if($secureToken != ""){ - $remString .= " secure_token=\"$secureToken\""; - } - print(""); - } - -} - -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * XML output Generator + * @package AjaXplorer + * @subpackage Core + */ +class AJXP_XMLWriter +{ + public static $headerSent = false; + + /** + * Output Headers, XML tag and a root node + * @static + * @param string $docNode + * @param array $attributes + */ + public static function header($docNode="tree", $attributes=array()) + { + if(self::$headerSent !== false && self::$headerSent == $docNode) return ; + header('Content-Type: text/xml; charset=UTF-8'); + header('Cache-Control: no-cache'); + print(''); + $attString = ""; + if (count($attributes)) { + foreach ($attributes as $name=>$value) { + $attString.="$name=\"$value\" "; + } + } + self::$headerSent = $docNode; + print("<$docNode $attString>"); + + } + /** + * Outputs a closing root not () + * @static + * @param string $docNode + * @return void + */ + public static function close($docNode="tree") + { + print(""); + } + + /** + * @static + * @param string $data + * @param bool $print + * @return string + */ + public static function write($data, $print) + { + if ($print) { + print($data); + return ""; + } else { + return $data; + } + } + + /** + * Ouput the tag + * @static + * @param integer $count + * @param integer $currentPage + * @param integer $totalPages + * @param integer $dirsCount + * @return void + */ + public static function renderPaginationData($count, $currentPage, $totalPages, $dirsCount = -1) + { + $string = ''; + AJXP_XMLWriter::write($string, true); + } + /** + * Prints out the XML headers and preamble, then an open node + * @static + * @param $nodeName + * @param $nodeLabel + * @param $isLeaf + * @param array $metaData + * @return void + */ + public static function renderHeaderNode($nodeName, $nodeLabel, $isLeaf, $metaData = array()) + { + header('Content-Type: text/xml; charset=UTF-8'); + header('Cache-Control: no-cache'); + print(''); + self::$headerSent = "tree"; + AJXP_XMLWriter::renderNode($nodeName, $nodeLabel, $isLeaf, $metaData, false); + } + + /** + * @static + * @param AJXP_Node $ajxpNode + * @return void + */ + public static function renderAjxpHeaderNode($ajxpNode) + { + header('Content-Type: text/xml; charset=UTF-8'); + header('Cache-Control: no-cache'); + print(''); + self::$headerSent = "tree"; + self::renderAjxpNode($ajxpNode, false); + } + + /** + * The basic node + * @static + * @param string $nodeName + * @param string $nodeLabel + * @param bool $isLeaf + * @param array $metaData + * @param bool $close + * @param bool $print + * @return void|string + */ + public static function renderNode($nodeName, $nodeLabel, $isLeaf, $metaData = array(), $close=true, $print = true) + { + $string = " $value) { + $value = AJXP_Utils::xmlEntities($value, true); + $string .= " $key=\"$value\""; + } + if ($close) { + $string .= "/>"; + } else { + $string .= ">"; + } + return AJXP_XMLWriter::write($string, $print); + } + + /** + * @static + * @param AJXP_Node $ajxpNode + * @param bool $close + * @param bool $print + * @return void|string + */ + public static function renderAjxpNode($ajxpNode, $close = true, $print = true) + { + return AJXP_XMLWriter::renderNode( + $ajxpNode->getPath(), + $ajxpNode->getLabel(), + $ajxpNode->isLeaf(), + $ajxpNode->metadata, + $close, + $print); + } + + /** + * Render a node with arguments passed as array + * @static + * @param $array + * @return void + */ + public static function renderNodeArray($array) + { + self::renderNode($array[0],$array[1],$array[2],$array[3]); + } + /** + * Error Catcher for PHP errors. Depending on the SERVER_DEBUG config + * shows the file/line info or not. + * @static + * @param $code + * @param $message + * @param $fichier + * @param $ligne + * @param $context + * @return + */ + public static function catchError($code, $message, $fichier, $ligne, $context) + { + if(error_reporting() == 0) return ; + if (ConfService::getConf("SERVER_DEBUG")) { + $message = "$message in $fichier (l.$ligne)"; + } + try { + AJXP_Logger::logAction("error", array("message" => $message)); + } catch (Exception $e) { + // This will probably trigger a double exception! + echo "
    Error in error";
    +            debug_print_backtrace();
    +            echo "
    "; + die("Recursive exception. Original error was : ".$message. " in $fichier , line $ligne"); + } + if(!headers_sent()) AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, SystemTextEncoding::toUTF8($message), true); + AJXP_XMLWriter::close(); + exit(1); + } + + /** + * Catch exceptions, @see catchError + * @param Exception $exception + */ + public static function catchException($exception) + { + try { + AJXP_XMLWriter::catchError($exception->getCode(), SystemTextEncoding::fromUTF8($exception->getMessage()), $exception->getFile(), $exception->getLine(), null); + } catch (Exception $innerEx) { + print get_class($innerEx)." thrown within the exception handler! Message was: ".$innerEx->getMessage()." in ".$innerEx->getFile()." on line ".$innerEx->getLine()." ".$innerEx->getTraceAsString(); + } + } + /** + * Dynamically replace XML keywords with their live values. + * AJXP_SERVER_ACCESS, AJXP_MIMES_*,AJXP_ALL_MESSAGES, etc. + * @static + * @param string $xml + * @param bool $stripSpaces + * @return mixed + */ + public static function replaceAjxpXmlKeywords($xml, $stripSpaces = false) + { + $messages = ConfService::getMessages(); + $confMessages = ConfService::getMessagesConf(); + $matches = array(); + if (isSet($_SESSION["AJXP_SERVER_PREFIX_URI"])) { + //$xml = str_replace("AJXP_THEME_FOLDER", $_SESSION["AJXP_SERVER_PREFIX_URI"].AJXP_THEME_FOLDER, $xml); + $xml = str_replace("AJXP_SERVER_ACCESS", $_SESSION["AJXP_SERVER_PREFIX_URI"].AJXP_SERVER_ACCESS, $xml); + } else { + //$xml = str_replace("AJXP_THEME_FOLDER", AJXP_THEME_FOLDER, $xml); + $xml = str_replace("AJXP_SERVER_ACCESS", AJXP_SERVER_ACCESS, $xml); + } + $xml = str_replace("AJXP_MIMES_EDITABLE", AJXP_Utils::getAjxpMimes("editable"), $xml); + $xml = str_replace("AJXP_MIMES_IMAGE", AJXP_Utils::getAjxpMimes("image"), $xml); + $xml = str_replace("AJXP_MIMES_AUDIO", AJXP_Utils::getAjxpMimes("audio"), $xml); + $xml = str_replace("AJXP_MIMES_ZIP", AJXP_Utils::getAjxpMimes("zip"), $xml); + $authDriver = ConfService::getAuthDriverImpl(); + if ($authDriver != NULL) { + $loginRedirect = $authDriver->getLoginRedirect(); + $xml = str_replace("AJXP_LOGIN_REDIRECT", ($loginRedirect!==false?"'".$loginRedirect."'":"false"), $xml); + } + $xml = str_replace("AJXP_REMOTE_AUTH", "false", $xml); + $xml = str_replace("AJXP_NOT_REMOTE_AUTH", "true", $xml); + $xml = str_replace("AJXP_ALL_MESSAGES", "MessageHash=".json_encode(ConfService::getMessages()).";", $xml); + + if (preg_match_all("/AJXP_MESSAGE(\[.*?\])/", $xml, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $messId = str_replace("]", "", str_replace("[", "", $match[1])); + $xml = str_replace("AJXP_MESSAGE[$messId]", $messages[$messId], $xml); + } + } + if (preg_match_all("/CONF_MESSAGE(\[.*?\])/", $xml, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $messId = str_replace(array("[", "]"), "", $match[1]); + $message = $messId; + if (array_key_exists($messId, $confMessages)) { + $message = $confMessages[$messId]; + } + $xml = str_replace("CONF_MESSAGE[$messId]", $message, $xml); + } + } + if (preg_match_all("/MIXIN_MESSAGE(\[.*?\])/", $xml, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $messId = str_replace(array("[", "]"), "", $match[1]); + $message = $messId; + if (array_key_exists($messId, $confMessages)) { + $message = $confMessages[$messId]; + } + $xml = str_replace("MIXIN_MESSAGE[$messId]", $message, $xml); + } + } + if ($stripSpaces) { + $xml = preg_replace("/[\n\r]?/", "", $xml); + $xml = preg_replace("/\t/", " ", $xml); + } + $xml = str_replace(array('xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"','xsi:noNamespaceSchemaLocation="file:../core.ajaxplorer/ajxp_registry.xsd"'), "", $xml); + $tab = array(&$xml); + AJXP_Controller::applyIncludeHook("xml.filter", $tab); + return $xml; + } + /** + * Send a XML instruction for refreshing the list + * @static + * @param string $nodePath + * @param string $pendingSelection + * @param bool $print + * @return string + */ + public static function reloadDataNode($nodePath="", $pendingSelection="", $print = true) + { + $nodePath = AJXP_Utils::xmlEntities($nodePath, true); + $pendingSelection = AJXP_Utils::xmlEntities($pendingSelection, true); + return AJXP_XMLWriter::write("", $print); + } + + + /** + * Send a XML instruction for refreshing the list + * @static + * @param string $nodePath + * @param string $pendingSelection + * @param bool $print + * @return string + */ + public static function writeNodesDiff($diffNodes, $print = false) + { + $mess = ConfService::getMessages(); + $buffer = ""; + if (isSet($diffNodes["REMOVE"]) && count($diffNodes["REMOVE"])) { + $buffer .= ""; + foreach ($diffNodes["REMOVE"] as $nodePath) { + $nodePath = AJXP_Utils::xmlEntities($nodePath, true); + $buffer .= ""; + } + $buffer .= ""; + } + if (isSet($diffNodes["ADD"]) && count($diffNodes["ADD"])) { + $buffer .= ""; + foreach ($diffNodes["ADD"] as $ajxpNode) { + $ajxpNode->loadNodeInfo(false, false, "all"); + if (!empty($ajxpNode->metaData["mimestring_id"]) && array_key_exists($ajxpNode->metaData["mimestring_id"], $mess)) { + $ajxpNode->mergeMetadata(array("mimestring" => $mess[$ajxpNode->metaData["mimestring_id"]])); + } + $buffer .= self::renderAjxpNode($ajxpNode, true, false); + } + $buffer .= ""; + } + if (isSet($diffNodes["UPDATE"]) && count($diffNodes["UPDATE"])) { + $buffer .= ""; + foreach ($diffNodes["UPDATE"] as $originalPath => $ajxpNode) { + $ajxpNode->loadNodeInfo(false, false, "all"); + if (!empty($ajxpNode->metaData["mimestring_id"]) && array_key_exists($ajxpNode->metaData["mimestring_id"], $mess)) { + $ajxpNode->mergeMetadata(array("mimestring" => $mess[$ajxpNode->metaData["mimestring_id"]])); + } + $ajxpNode->original_path = $originalPath; + $buffer .= self::renderAjxpNode($ajxpNode, true, false); + } + $buffer .= ""; + } + $buffer .= ""; + return AJXP_XMLWriter::write($buffer, $print); + + /* + $nodePath = AJXP_Utils::xmlEntities($nodePath, true); + $pendingSelection = AJXP_Utils::xmlEntities($pendingSelection, true); + return AJXP_XMLWriter::write("", $print); + */ + } + + + /** + * Send a XML instruction for refreshing the repositories list + * @static + * @param bool $print + * @return string + */ + public static function reloadRepositoryList($print = true) + { + return AJXP_XMLWriter::write("", $print); + } + /** + * Outputs a tag + * @static + * @param bool $print + * @return string + */ + public static function requireAuth($print = true) + { + return AJXP_XMLWriter::write("", $print); + } + /** + * Triggers a background action client side + * @static + * @param $actionName + * @param $parameters + * @param $messageId + * @param bool $print + * @param int $delay + * @return string + */ + public static function triggerBgAction($actionName, $parameters, $messageId, $print=true, $delay = 0) + { + $messageId = AJXP_Utils::xmlEntities($messageId); + $data = AJXP_XMLWriter::write("", $print); + foreach ($parameters as $paramName=>$paramValue) { + $paramValue = AJXP_Utils::xmlEntities($paramValue); + $data .= AJXP_XMLWriter::write("", $print); + } + $data .= AJXP_XMLWriter::write("", $print); + return $data; + } + + public static function triggerBgJSAction($jsCode, $messageId, $print=true, $delay = 0) + { + $data = AJXP_XMLWriter::write("", $print); + $data .= AJXP_XMLWriter::write("", $print); + $data .= AJXP_XMLWriter::write("", $print); + return $data; + } + + /** + * List all bookmmarks as XML + * @static + * @param $allBookmarks + * @param bool $print + * @param string $format legacy|node_list + * @return string + */ + public static function writeBookmarks($allBookmarks, $print = true, $format = "legacy") + { + if ($format == "node_list") { + $driver = ConfService::loadRepositoryDriver(); + if (!is_a($driver, "AjxpWrapperProvider")) { + $driver = false; + } + } + $buffer = ""; + foreach ($allBookmarks as $bookmark) { + $path = ""; $title = ""; + if (is_array($bookmark)) { + $path = $bookmark["PATH"]; + $title = $bookmark["TITLE"]; + } else if (is_string($bookmark)) { + $path = $bookmark; + $title = basename($bookmark); + } + if ($format == "node_list") { + if ($driver) { + $node = new AJXP_Node($driver->getResourceUrl($path)); + $buffer .= AJXP_XMLWriter::renderAjxpNode($node, true, false); + } else { + $buffer .= AJXP_XMLWriter::renderNode($path, $title, false, array('icon' => "mime_empty.png"), true, false); + } + } else { + $buffer .= ""; + } + } + if($print) print $buffer; + else return $buffer; + } + /** + * Utilitary for generating a tag for the FilesList component + * @static + * @param $config + * @return void + */ + public static function sendFilesListComponentConfig($config) + { + if (is_string($config)) { + print("$config"); + } + } + /** + * Send a success or error message to the client. + * @static + * @param $logMessage + * @param $errorMessage + * @param bool $print + * @return string + */ + public static function sendMessage($logMessage, $errorMessage, $print = true) + { + $messageType = ""; + $message = ""; + if ($errorMessage == null) { + $messageType = "SUCCESS"; + $message = AJXP_Utils::xmlContentEntities($logMessage); + } else { + $messageType = "ERROR"; + $message = AJXP_Utils::xmlContentEntities($errorMessage); + } + return AJXP_XMLWriter::write("".$message."", $print); + } + /** + * Writes the user data as XML + * @static + * @param null $userObject + * @param bool $details + * @return void + */ + public static function sendUserData($userObject = null, $details=false) + { + print(AJXP_XMLWriter::getUserXML($userObject, $details)); + } + /** + * Extract all the user data and put it in XML + * @static + * @param null $userObject + * @param bool $details + * @return string + */ + public static function getUserXML($userObject = null, $details=false) + { + $buffer = ""; + $loggedUser = AuthService::getLoggedUser(); + $confDriver = ConfService::getConfStorageImpl(); + if($userObject != null) $loggedUser = $userObject; + if (!AuthService::usersEnabled()) { + $buffer.=""; + if (!$details) { + $buffer.=""; + } + $buffer.= AJXP_XMLWriter::writeRepositoriesData(null, $details); + $buffer.=""; + } else if ($loggedUser != null) { + $lock = $loggedUser->getLock(); + $buffer.="id."\">"; + if (!$details) { + $buffer.="canWrite(ConfService::getCurrentRepositoryId())?"1":"0")."\" read=\"".($loggedUser->canRead(ConfService::getCurrentRepositoryId())?"1":"0")."\"/>"; + } else { + $buffer .= ""; + foreach ($loggedUser->getRoles() as $roleId => $boolean) { + if($boolean === true) $buffer.= ""; + } + $buffer .= ""; + } + $buffer.= AJXP_XMLWriter::writeRepositoriesData($loggedUser, $details); + $buffer.=""; + $preferences = $confDriver->getExposedPreferences($loggedUser); + foreach ($preferences as $prefName => $prefData) { + $atts = ""; + if (isSet($prefData["exposed"]) && $prefData["exposed"] == true) { + foreach ($prefData as $k => $v) { + if($k=="name") continue; + if($k == "value") $k = "default"; + $atts .= "$k='$v' "; + } + } + if (isset($prefData["pluginId"])) { + $atts .= "pluginId='".$prefData["pluginId"]."' "; + } + if ($prefData["type"] == "string") { + $buffer.=""; + } else if ($prefData["type"] == "json") { + $buffer.=""; + } + } + $buffer.=""; + $buffer.="isAdmin()?"1":"0")."\" ".($lock!==false?"lock=\"$lock\"":"")."/>"; + $bMarks = $loggedUser->getBookmarks(); + if (count($bMarks)) { + $buffer.= "".AJXP_XMLWriter::writeBookmarks($bMarks, false).""; + } + $buffer.=""; + } + return $buffer; + } + /** + * Write the repositories access rights in XML format + * @static + * @param AbstractAjxpUser|null $loggedUser + * @param bool $details + * @return string + */ + public static function writeRepositoriesData($loggedUser, $details=false) + { + $st = ""; + $streams = ConfService::detectRepositoryStreams(false); + foreach (ConfService::getAccessibleRepositories($loggedUser, $details, false) as $repoId => $repoObject) { + $toLast = false; + if ($repoObject->getAccessType()=="ajxp_conf") { + if(AuthService::usersEnabled() && !$loggedUser->isAdmin())continue; + $toLast = true; + } + $rightString = ""; + if ($details) { + $rightString = " r=\"".($loggedUser->canRead($repoId)?"1":"0")."\" w=\"".($loggedUser->canWrite($repoId)?"1":"0")."\""; + } + $streamString = ""; + if (in_array($repoObject->accessType, $streams)) { + $streamString = "allowCrossRepositoryCopy=\"true\""; + } + if ($repoObject->getUniqueUser()) { + $streamString .= " user_editable_repository=\"true\" "; + } + $slugString = ""; + $slug = $repoObject->getSlug(); + if (!empty($slug)) { + $slugString = "repositorySlug=\"$slug\""; + } + $isSharedString = ""; + if ($repoObject->hasOwner()) { + $uId = $repoObject->getOwner(); + $uObject = ConfService::getConfStorageImpl()->createUserObject($uId); + $label = $uObject->personalRole->filterParameterValue("core.conf", "USER_DISPLAY_NAME", AJXP_REPO_SCOPE_ALL, $uId); + $isSharedString = "owner='".$label."'"; + } + $descTag = ""; + $description = $repoObject->getDescription(); + if (!empty($description)) { + $descTag = ''.AJXP_Utils::xmlEntities($description, true).''; + } + $xmlString = "accessType."\" id=\"".$repoId."\"$rightString $streamString $slugString $isSharedString>".$descTag.$repoObject->getClientSettings().""; + if ($toLast) { + $lastString = $xmlString; + } else { + $st .= $xmlString; + } + } + + if (isSet($lastString)) { + $st.= $lastString; + } + $st .= ""; + return $st; + } + /** + * Writes a tag + * @static + * @param integer $result + * @param string $rememberLogin + * @param string $rememberPass + * @param string $secureToken + * @return void + */ + public static function loggingResult($result, $rememberLogin="", $rememberPass = "", $secureToken="") + { + $remString = ""; + if ($rememberPass != "" && $rememberLogin!= "") { + $remString = " remember_login=\"$rememberLogin\" remember_pass=\"$rememberPass\""; + } + if ($secureToken != "") { + $remString .= " secure_token=\"$secureToken\""; + } + print(""); + } + +} diff --git a/core/src/core/classes/class.AbstractTest.php b/core/src/core/classes/class.AbstractTest.php index e2b423822d..00d3046a9c 100644 --- a/core/src/core/classes/class.AbstractTest.php +++ b/core/src/core/classes/class.AbstractTest.php @@ -32,19 +32,19 @@ class AbstractTest { /** The test name */ - var $name; + public $name; /** The test information when failed */ - var $failedInfo; + public $failedInfo; /** The test results output (used for report) */ - var $resultOutput; + public $resultOutput; /** Tested params - When used as a diagnostic tool, can store variables used by the test*/ - var $testedParas; + public $testedParas; /** The test level when failed (warning, info or error, default to error) */ - var $failedLevel; + public $failedLevel; /** The test parameters */ - var $params; - - function AbstractTest($name, $failedInfo, $params = NULL) + public $params; + + public function AbstractTest($name, $failedInfo, $params = NULL) { $this->name = $name; $this->failedInfo = $failedInfo; @@ -54,42 +54,41 @@ function AbstractTest($name, $failedInfo, $params = NULL) global $MAIN_testsArray; $MAIN_testsArray[] = $this; } - + /** * Perform the test, should be overwritten in concrete classes * @abstract * @return Boolean */ - function doTest() { return FALSE; } - - /** - * Perform the test on a given repository object, should be overwritten in concrete classes + public function doTest() { return FALSE; } + + /** + * Perform the test on a given repository object, should be overwritten in concrete classes * @param Repository $repository * @return Boolean */ - function doRepositoryTest($repository) { return FALSE; } - + public function doRepositoryTest($repository) { return FALSE; } + /** * Utilitary to convert php config to numerical values. * * @param String $val * @return Integer */ - function returnBytes($val) { - $val = trim($val); - $last = strtolower($val[strlen($val)-1]); - switch($last) { - // Le modifieur 'G' est disponible depuis PHP 5.1.0 - case 'g': - $val *= 1024; - case 'm': - $val *= 1024; - case 'k': - $val *= 1024; - } + public function returnBytes($val) + { + $val = trim($val); + $last = strtolower($val[strlen($val)-1]); + switch ($last) { + // Le modifieur 'G' est disponible depuis PHP 5.1.0 + case 'g': + $val *= 1024; + case 'm': + $val *= 1024; + case 'k': + $val *= 1024; + } - return $val; + return $val; } }; - -?> \ No newline at end of file diff --git a/core/src/core/classes/class.AjxpRole.php b/core/src/core/classes/class.AjxpRole.php index eedbdc9371..8eca3f5de8 100644 --- a/core/src/core/classes/class.AjxpRole.php +++ b/core/src/core/classes/class.AjxpRole.php @@ -29,65 +29,71 @@ */ class AjxpRole implements AjxpGroupPathProvider { - private $id; - private $rights = array(); + private $id; + private $rights = array(); private $default = false; /** * @var String */ protected $groupPath; - /** + /** * Constructor * @param string $id * @return void */ - function AjxpRole($id){ - $this->id = $id; - } - /** + public function AjxpRole($id) + { + $this->id = $id; + } + /** * @param $id * @return void */ - function setId($id){ - $this->id = $id; - } - /** + public function setId($id) + { + $this->id = $id; + } + /** * @return string */ - function getId(){ - return $this->id; - } - /** + public function getId() + { + return $this->id; + } + /** * Whether this role can read the given repo * @param string $rootDirId Repository ID * @return bool */ - function canRead($rootDirId){ - $right = $this->getRight($rootDirId); - if($right == "rw" || $right == "r") return true; - return false; - } - + public function canRead($rootDirId) + { + $right = $this->getRight($rootDirId); + if($right == "rw" || $right == "r") return true; + return false; + } + /** * Whether this role can write the given repo * @param string $rootDirId Repository ID * @return bool */ - function canWrite($rootDirId){ - $right = $this->getRight($rootDirId); - if($right == "rw" || $right == "w") return true; - return false; - } - + public function canWrite($rootDirId) + { + $right = $this->getRight($rootDirId); + if($right == "rw" || $right == "w") return true; + return false; + } + /** * Current definitioon (r, rw, w, empty string) for the given repo * @param string $rootDirId Repository ID * @return string */ - function getRight($rootDirId){ - if(isSet($this->rights[$rootDirId])) return $this->rights[$rootDirId]; - return ""; - } + public function getRight($rootDirId) + { + if(isSet($this->rights[$rootDirId])) return $this->rights[$rootDirId]; + return ""; + } /** * Set the right @@ -95,51 +101,56 @@ function getRight($rootDirId){ * @param string $rightString ("r", "rw", "w", "") * @return void */ - function setRight($rootDirId, $rightString){ - $this->rights[$rootDirId] = $rightString; - } - /** + public function setRight($rootDirId, $rightString) + { + $this->rights[$rootDirId] = $rightString; + } + /** * Remove a right entry for the repository * @param string $rootDirId * @return void */ - function removeRights($rootDirId){ - if(isSet($this->rights[$rootDirId])) unset($this->rights[$rootDirId]); - } - /** + public function removeRights($rootDirId) + { + if(isSet($this->rights[$rootDirId])) unset($this->rights[$rootDirId]); + } + /** * Remove all rights * @return void */ - function clearRights(){ - $this->rights = array(); - } - /** + public function clearRights() + { + $this->rights = array(); + } + /** * Get the specific actions rights (see setSpecificActionsRights) * @param $rootDirId * @return array */ - function getSpecificActionsRights($rootDirId){ - $res = array(); - if($rootDirId."" != "ajxp.all"){ - $res = $this->getSpecificActionsRights("ajxp.all"); - } - if(isSet($this->rights["ajxp.actions"]) && isSet($this->rights["ajxp.actions"][$rootDirId])){ - $res = array_merge($res, $this->rights["ajxp.actions"][$rootDirId]); - } - return $res; - } - /** + public function getSpecificActionsRights($rootDirId) + { + $res = array(); + if ($rootDirId."" != "ajxp.all") { + $res = $this->getSpecificActionsRights("ajxp.all"); + } + if (isSet($this->rights["ajxp.actions"]) && isSet($this->rights["ajxp.actions"][$rootDirId])) { + $res = array_merge($res, $this->rights["ajxp.actions"][$rootDirId]); + } + return $res; + } + /** * This method allows to specifically disable some actions for a given role for one or more repository. * @param string $rootDirId Repository id or "ajxp.all" for all repositories * @param string $actionName * @param bool $allowed * @return void */ - function setSpecificActionRight($rootDirId, $actionName, $allowed){ - if(!isSet($this->rights["ajxp.actions"])) $this->rights["ajxp.actions"] = array(); - if(!isset($this->rights["ajxp.actions"][$rootDirId])) $this->rights["ajxp.actions"][$rootDirId] = array(); - $this->rights["ajxp.actions"][$rootDirId][$actionName] = $allowed; - } + public function setSpecificActionRight($rootDirId, $actionName, $allowed) + { + if(!isSet($this->rights["ajxp.actions"])) $this->rights["ajxp.actions"] = array(); + if(!isset($this->rights["ajxp.actions"][$rootDirId])) $this->rights["ajxp.actions"][$rootDirId] = array(); + $this->rights["ajxp.actions"][$rootDirId][$actionName] = $allowed; + } public function setDefault($default) { @@ -168,5 +179,3 @@ public function getGroupPath() } } - -?> \ No newline at end of file diff --git a/core/src/core/classes/class.AuthService.php b/core/src/core/classes/class.AuthService.php index e798c98e4c..7337e5d57d 100644 --- a/core/src/core/classes/class.AuthService.php +++ b/core/src/core/classes/class.AuthService.php @@ -1,998 +1,1020 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * Static access to the authentication mechanism. Encapsulates the authDriver implementation - * @package AjaXplorer - * @subpackage Core - */ -class AuthService -{ - static $roles; - public static $useSession = true; - private static $currentUser; - /** - * Whether the whole users management system is enabled or not. - * @static - * @return bool - */ - static function usersEnabled() - { - return ConfService::getCoreConf("ENABLE_USERS", "auth"); - } - /** - * Whether the current auth driver supports password update or not - * @static - * @return bool - */ - static function changePasswordEnabled() - { - $authDriver = ConfService::getAuthDriverImpl(); - return $authDriver->passwordsEditable(); - } - /** - * Get a unique seed from the current auth driver - * @static - * @return int|string - */ - static function generateSeed(){ - $authDriver = ConfService::getAuthDriverImpl(); - return $authDriver->getSeed(true); - } - - /** - * Put a secure token in the session - * @static - * @return - */ - static function generateSecureToken(){ - - $_SESSION["SECURE_TOKEN"] = AJXP_Utils::generateRandomString(32); //md5(time()); - return $_SESSION["SECURE_TOKEN"]; - } - /** - * Get the secure token from the session - * @static - * @return string|bool - */ - static function getSecureToken(){ - return (isSet($_SESSION["SECURE_TOKEN"])?$_SESSION["SECURE_TOKEN"]:FALSE); - } - /** - * Verify a secure token value from the session - * @static - * @param string $token - * @return bool - */ - static function checkSecureToken($token){ - if(isSet($_SESSION["SECURE_TOKEN"]) && $_SESSION["SECURE_TOKEN"] == $token){ - return true; - } - return false; - } - - /** - * Get the currently logged user object - * @return AbstractAjxpUser - */ - static function getLoggedUser() - { - if(self::$useSession && isSet($_SESSION["AJXP_USER"])) { - if(is_a($_SESSION["AJXP_USER"], "__PHP_Incomplete_Class")){ - session_unset("AJXP_USER"); - return null; - } - return $_SESSION["AJXP_USER"]; - } - if(!self::$useSession && isSet(self::$currentUser)) return self::$currentUser; - return null; - } - /** - * Call the preLogUser() functino on the auth driver implementation - * @static - * @param string $remoteSessionId - * @return void - */ - static function preLogUser($remoteSessionId = "") - { - if(AuthService::getLoggedUser() != null) return ; - $authDriver = ConfService::getAuthDriverImpl(); - $authDriver->preLogUser($remoteSessionId); - return ; - } - /** - * The array is located in the AjxpTmpDir/failedAJXP.log - * @static - * @return array - */ - static function getBruteForceLoginArray() - { - $failedLog = AJXP_Utils::getAjxpTmpDir()."/failedAJXP.log"; - $loginAttempt = @file_get_contents($failedLog); - $loginArray = unserialize($loginAttempt); - $ret = array(); - $curTime = time(); - if (is_array($loginArray)){ - // Filter the array (all old time are cleaned) - foreach($loginArray as $key => $login) - { - if (($curTime - $login["time"]) <= 60 * 60 * 24) $ret[$key] = $login; - } - } - return $ret; - } - /** - * Store the array - * @static - * @param $loginArray - * @return void - */ - static function setBruteForceLoginArray($loginArray) - { - $failedLog = AJXP_Utils::getAjxpTmpDir()."/failedAJXP.log"; - @file_put_contents($failedLog, serialize($loginArray)); - } - /** - * Determines whether the user is try to make many attemps - * @static - * @param $loginArray - * @return bool - */ - static function checkBruteForceLogin(&$loginArray) - { - if(isSet($_SERVER['REMOTE_ADDR'])){ - $serverAddress = $_SERVER['REMOTE_ADDR']; - }else{ - $serverAddress = $_SERVER['SERVER_ADDR']; - } - $login = null; - if(isSet($loginArray[$serverAddress])){ - $login = $loginArray[$serverAddress]; - } - if (is_array($login)){ - $login["count"]++; - } else $login = array("count"=>1, "time"=>time()); - $loginArray[$serverAddress] = $login; - if ($login["count"] > 3) { - if(AJXP_SERVER_DEBUG){ - AJXP_Logger::debug("DEBUG : IGNORING BRUTE FORCE ATTEMPTS!"); - return true; - } - return FALSE; - } - return TRUE; - } - /** - * Is there a brute force login attempt? - * @static - * @return bool - */ - static function suspectBruteForceLogin(){ - $loginAttempt = AuthService::getBruteForceLoginArray(); - return !AuthService::checkBruteForceLogin($loginAttempt); - } - - static function filterUserSensitivity($user){ - if(!ConfService::getCoreConf("CASE_SENSITIVE", "auth")){ - return strtolower($user); - }else{ - return $user; - } - } - - static function ignoreUserCase(){ - return !ConfService::getCoreConf("CASE_SENSITIVE", "auth"); - } - - /** - * @static - * @param AbstractAjxpUser $user - */ - static function refreshRememberCookie($user){ - $current = $_COOKIE["AjaXplorer-remember"]; - if(!empty($current)){ - $user->invalidateCookieString(substr($current, strpos($current, ":")+1)); - } - $rememberPass = $user->getCookieString(); - setcookie("AjaXplorer-remember", $user->id.":".$rememberPass, time()+3600*24*10, null, null, (isSet($_SERVER["HTTPS"]) && strtolower($_SERVER["HTTPS"]) == "on"), true); - } - - /** - * @static - * @return bool - */ - static function hasRememberCookie(){ - return (isSet($_COOKIE["AjaXplorer-remember"]) && !empty($_COOKIE["AjaXplorer-remember"])); - } - - /** - * @static - * Warning, must be called before sending other headers! - */ - static function clearRememberCookie(){ - $current = $_COOKIE["AjaXplorer-remember"]; - $user = AuthService::getLoggedUser(); - if(!empty($current) && $user != null){ - $user->invalidateCookieString(substr($current, strpos($current, ":")+1)); - } - setcookie("AjaXplorer-remember", "", time()-3600, null, null, (isSet($_SERVER["HTTPS"]) && strtolower($_SERVER["HTTPS"]) == "on"), true); - } - - static function logTemporaryUser($parentUserId, $temporaryUserId){ - $parentUserId = self::filterUserSensitivity($parentUserId); - $temporaryUserId = self::filterUserSensitivity($temporaryUserId); - $confDriver = ConfService::getConfStorageImpl(); - $parentUser = $confDriver->createUserObject($parentUserId); - $temporaryUser = $confDriver->createUserObject($temporaryUserId); - $temporaryUser->mergedRole = $parentUser->mergedRole; - $temporaryUser->rights = $parentUser->rights; - $temporaryUser->setGroupPath($parentUser->getGroupPath()); - $temporaryUser->setParent($parentUserId); - $temporaryUser->setResolveAsParent(true); - AJXP_Logger::logAction("Log in", array("temporary user" => $temporaryUserId, "owner" => $parentUserId)); - self::updateUser($temporaryUser); - } - - static function clearTemporaryUser($temporaryUserId){ - AJXP_Logger::logAction("Log out", array("temporary user"), $temporaryUserId); - if(isSet($_SESSION["AJXP_USER"]) || isSet(self::$currentUser)){ - AJXP_Logger::logAction("Log Out"); - unset($_SESSION["AJXP_USER"]); - if(isSet(self::$currentUser)) unset(self::$currentUser); - if(ConfService::getCoreConf("SESSION_SET_CREDENTIALS", "auth")){ - AJXP_Safe::clearCredentials(); - } - } - } - - /** - * Log the user from its credentials - * @static - * @param string $user_id The user id - * @param string $pwd The password - * @param bool $bypass_pwd Ignore password or not - * @param bool $cookieLogin Is it a logging from the remember me cookie? - * @param string $returnSeed The unique seed - * @return int - */ - static function logUser($user_id, $pwd, $bypass_pwd = false, $cookieLogin = false, $returnSeed="") - { - $user_id = self::filterUserSensitivity($user_id); - if($cookieLogin && !isSet($_COOKIE["AjaXplorer-remember"])){ - return -5; // SILENT IGNORE - } - if($cookieLogin){ - list($user_id, $pwd) = explode(":", $_COOKIE["AjaXplorer-remember"]); - } - $confDriver = ConfService::getConfStorageImpl(); - if($user_id == null) - { - if(self::$useSession){ - if(isSet($_SESSION["AJXP_USER"]) && is_object($_SESSION["AJXP_USER"])) return 1; - }else{ - if(isSet(self::$currentUser) && is_object(self::$currentUser)) return 1; - } - if(ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth")) - { - $authDriver = ConfService::getAuthDriverImpl(); - if(!$authDriver->userExists("guest")) - { - AuthService::createUser("guest", ""); - $guest = $confDriver->createUserObject("guest"); - $guest->save("superuser"); - } - AuthService::logUser("guest", null); - return 1; - } - return -1; - } - $authDriver = ConfService::getAuthDriverImpl(); - // CHECK USER PASSWORD HERE! - $loginAttempt = AuthService::getBruteForceLoginArray(); - $bruteForceLogin = AuthService::checkBruteForceLogin($loginAttempt); - AuthService::setBruteForceLoginArray($loginAttempt); - - if(!$authDriver->userExists($user_id)){ - if ($bruteForceLogin === FALSE){ - return -4; - }else{ - return -1; - } - } - if(!$bypass_pwd){ - if(!AuthService::checkPassword($user_id, $pwd, $cookieLogin, $returnSeed)){ - if ($bruteForceLogin === FALSE){ - return -4; - }else{ - if($cookieLogin) return -5; - return -1; - } - } - } - // Successful login attempt - unset($loginAttempt[$_SERVER["REMOTE_ADDR"]]); - AuthService::setBruteForceLoginArray($loginAttempt); - - // Setting session credentials if asked in config - if(ConfService::getCoreConf("SESSION_SET_CREDENTIALS", "auth")) { - list($authId, $authPwd) = $authDriver->filterCredentials($user_id, $pwd); - AJXP_Safe::storeCredentials($authId, $authPwd); - } - - $user = $confDriver->createUserObject($user_id); - if($user->getLock() == "logout"){ - return -1; - } - if($authDriver->isAjxpAdmin($user_id)){ - $user->setAdmin(true); - } - if($user->isAdmin()) - { - $user = AuthService::updateAdminRights($user); - } - else{ - if(!$user->hasParent() && $user_id != "guest"){ - //$user->setAcl("ajxp_shared", "rw"); - } - } - if(self::$useSession) $_SESSION["AJXP_USER"] = $user; - else self::$currentUser = $user; - - if($authDriver->autoCreateUser() && !$user->storageExists()){ - $user->save("superuser"); // make sure update rights now - } - AJXP_Logger::logAction("Log In"); - return 1; - } - /** - * Store the object in the session - * @static - * @param $userObject - * @return void - */ - static function updateUser($userObject) - { - if(self::$useSession) $_SESSION["AJXP_USER"] = $userObject; - else self::$currentUser = $userObject; - } - /** - * Clear the session - * @static - * @return void - */ - static function disconnect() - { - if(isSet($_SESSION["AJXP_USER"]) || isSet(self::$currentUser)){ - AuthService::clearRememberCookie(); - AJXP_Logger::logAction("Log Out"); - unset($_SESSION["AJXP_USER"]); - if(isSet(self::$currentUser)) unset(self::$currentUser); - if(ConfService::getCoreConf("SESSION_SET_CREDENTIALS", "auth")){ - AJXP_Safe::clearCredentials(); - } - } - } - /** - * Specific operations to perform at boot time - * @static - * @param array $START_PARAMETERS A HashTable of parameters to send back to the client - * @return void - */ - public static function bootSequence(&$START_PARAMETERS){ - - if(AJXP_Utils::detectApplicationFirstRun()) return; - if(file_exists(AJXP_CACHE_DIR."/admin_counted")) return; - $rootRole = AuthService::getRole("ROOT_ROLE", false); - if($rootRole === false){ - $rootRole = new AJXP_Role("ROOT_ROLE"); - $rootRole->setLabel("Root Role"); - $rootRole->setAutoApplies(array("standard")); - foreach (ConfService::getRepositoriesList("all") as $repositoryId => $repoObject) - { - if($repoObject->isTemplate) continue; - $gp = $repoObject->getGroupPath(); - if(empty($gp) || $gp == "/"){ - if($repoObject->getDefaultRight() != ""){ - $rootRole->setAcl($repositoryId, $repoObject->getDefaultRight()); - } - } - } - AuthService::updateRole($rootRole); - } - $miniRole = AuthService::getRole("MINISITE", false); - if($miniRole === false){ - $rootRole = new AJXP_Role("MINISITE"); - $rootRole->setLabel("Minisite Users"); - $actions = array( - "access.fs" => array("ajxp_link", "chmod", "purge"), - "meta.watch" => array("toggle_watch"), - "conf.serial"=> array("get_bookmarks"), - "conf.sql"=> array("get_bookmarks"), - "index.lucene" => array("index"), - "action.share" => array("share"), - "gui.ajax" => array("bookmark"), - "auth.serial" => array("pass_change"), - "auth.sql" => array("pass_change"), - ); - foreach($actions as $pluginId => $acts){ - foreach($acts as $act){ - $rootRole->setActionState($pluginId, $act, AJXP_REPO_SCOPE_SHARED, false); - } - } - AuthService::updateRole($rootRole); - } - $miniRole = AuthService::getRole("MINISITE_NODOWNLOAD", false); - if($miniRole === false){ - $rootRole = new AJXP_Role("MINISITE_NODOWNLOAD"); - $rootRole->setLabel("Minisite Users - No Download"); - $actions = array( - "access.fs" => array("download", "download_chunk", "prepare_chunk_dl", "download_all") - ); - foreach($actions as $pluginId => $acts){ - foreach($acts as $act){ - $rootRole->setActionState($pluginId, $act, AJXP_REPO_SCOPE_SHARED, false); - } - } - AuthService::updateRole($rootRole); - } - $miniRole = AuthService::getRole("GUEST", false); - if($miniRole === false){ - $rootRole = new AJXP_Role("GUEST"); - $rootRole->setLabel("Guest user role"); - $actions = array( - "access.fs" => array("purge"), - "meta.watch" => array("toggle_watch"), - "index.lucene" => array("index"), - ); - $rootRole->setAutoApplies(array("guest")); - foreach($actions as $pluginId => $acts){ - foreach($acts as $act){ - $rootRole->setActionState($pluginId, $act, AJXP_REPO_SCOPE_ALL); - } - } - AuthService::updateRole($rootRole); - } - $adminCount = AuthService::countAdminUsers(); - if($adminCount == 0){ - $authDriver = ConfService::getAuthDriverImpl(); - $adminPass = ADMIN_PASSWORD; - if($authDriver->getOption("TRANSMIT_CLEAR_PASS") !== true){ - $adminPass = md5(ADMIN_PASSWORD); - } - AuthService::createUser("admin", $adminPass, true); - if(ADMIN_PASSWORD == INITIAL_ADMIN_PASSWORD) - { - $userObject = ConfService::getConfStorageImpl()->createUserObject("admin"); - $userObject->setAdmin(true); - AuthService::updateAdminRights($userObject); - if(AuthService::changePasswordEnabled()){ - $userObject->setLock("pass_change"); - } - $userObject->save("superuser"); - $START_PARAMETERS["ALERT"] .= "Warning! User 'admin' was created with the initial password '". INITIAL_ADMIN_PASSWORD ."'. \\nPlease log in as admin and change the password now!"; - } - AuthService::updateUser($userObject); - }else if($adminCount == -1){ - // Here we may come from a previous version! Check the "admin" user and set its right as admin. - $confStorage = ConfService::getConfStorageImpl(); - $adminUser = $confStorage->createUserObject("admin"); - $adminUser->setAdmin(true); - $adminUser->save("superuser"); - $START_PARAMETERS["ALERT"] .= "There is an admin user, but without admin right. Now any user can have the administration rights, \\n your 'admin' user was set with the admin rights. Please check that this suits your security configuration."; - } - file_put_contents(AJXP_CACHE_DIR."/admin_counted", "true"); - - } - /** - * If the auth driver implementatino has a logout redirect URL, clear session and return it. - * @static - * @param bool $logUserOut - * @return bool - */ - static function getLogoutAddress($logUserOut = true) - { - $authDriver = ConfService::getAuthDriverImpl(); - $logout = $authDriver->getLogoutRedirect(); - if($logUserOut){ - self::disconnect(); - } - return $logout; - } - /** - * Compute the default repository id to log the current user - * @static - * @return int|string - */ - static function getDefaultRootId() - { - $loggedUser = AuthService::getLoggedUser(); - if($loggedUser == null) return 0; - $repoList = ConfService::getRepositoriesList(); - foreach ($repoList as $rootDirIndex => $rootDirObject) - { - if($loggedUser->canRead($rootDirIndex."") || $loggedUser->canWrite($rootDirIndex."")) { - // Warning : do not grant access to admin repository to a non admin, or there will be - // an "Empty Repository Object" error. - if($rootDirObject->getAccessType()=="ajxp_conf" && AuthService::usersEnabled() && !$loggedUser->isAdmin()){ - continue; - } - if($rootDirObject->getAccessType() == "ajxp_shared" && count($repoList) > 1){ - continue; - } - return $rootDirIndex; - } - } - return 0; - } - - /** - * Update a user with admin rights and return it - * @param AbstractAjxpUser $adminUser - * @return AbstractAjxpUser - */ - static function updateAdminRights($adminUser) - { - foreach (ConfService::getRepositoriesList() as $repoId => $repoObject) - { - if(!self::allowedForCurrentGroup($repoObject, $adminUser)) continue; - if($repoObject->hasParent() && $repoObject->getParentId() != $adminUser->getId()) continue; - $adminUser->personalRole->setAcl($repoId, "rw"); - $adminUser->recomputeMergedRole(); - } - $adminUser->save("superuser"); - return $adminUser; - } - - /** - * Update a user object with the default repositories rights - * - * @param AbstractAjxpUser $userObject - */ - static function updateDefaultRights(&$userObject){ - if(!$userObject->hasParent()){ - $changes = false; - foreach (ConfService::getRepositoriesList() as $repositoryId => $repoObject) - { - if(!self::allowedForCurrentGroup($repoObject, $userObject)) continue; - if($repoObject->isTemplate) continue; - if($repoObject->getDefaultRight() != ""){ - $changes = true; - $userObject->personalRole->setAcl($repositoryId, $repoObject->getDefaultRight()); - } - } - if($changes) { - $userObject->recomputeMergedRole(); - } - foreach(AuthService::getRolesList(array(), true) as $roleId => $roleObject){ - if(!self::allowedForCurrentGroup($roleObject, $userObject)) continue; - if($userObject->getProfile() == "shared" && $roleObject->autoAppliesTo("shared")){ - $userObject->addRole($roleObject); - }else if($roleObject->autoAppliesTo("standard")){ - $userObject->addRole($roleObject); - } - } - } - } - - /** - * @static - * @param AbstractAjxpUser $userObject - */ - static function updateAutoApplyRole(&$userObject){ - foreach(AuthService::getRolesList(array(), true) as $roleId => $roleObject){ - if(!self::allowedForCurrentGroup($roleObject, $userObject)) continue; - if($roleObject->autoAppliesTo($userObject->getProfile()) || $roleObject->autoAppliesTo("all")){ - $userObject->addRole($roleObject); - } - } - } - - static function updateAuthProvidedData(&$userObject){ - ConfService::getAuthDriverImpl()->updateUserObject($userObject); - } - - /** - * Use driver implementation to check whether the user exists or not. - * @static - * @param String $userId - * @param String $mode "r" or "w" - * @return bool - */ - static function userExists($userId, $mode = "r") - { - if($userId == "guest" && !ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth")){ - return false; - } - $userId = AuthService::filterUserSensitivity($userId); - $authDriver = ConfService::getAuthDriverImpl(); - if($mode == "w"){ - return $authDriver->userExistsWrite($userId); - } - return $authDriver->userExists($userId); - } - - /** - * Make sure a user id is not reserved for low-level tasks (currently "guest" and "shared"). - * @static - * @param String $username - * @return bool - */ - static function isReservedUserId($username){ - $username = AuthService::filterUserSensitivity($username); - return in_array($username, array("guest", "shared")); - } - - /** - * Simple password encoding, should be deported in a more complex/configurable function - * @static - * @param $pass - * @return string - */ - static function encodePassword($pass){ - return md5($pass); - } - /** - * Check a password - * @static - * @param $userId - * @param $userPass - * @param bool $cookieString - * @param string $returnSeed - * @return bool|void - */ - static function checkPassword($userId, $userPass, $cookieString = false, $returnSeed = "") - { - if(ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth") && $userId == "guest") return true; - $userId = AuthService::filterUserSensitivity($userId); - $authDriver = ConfService::getAuthDriverImpl(); - if($cookieString){ - $confDriver = ConfService::getConfStorageImpl(); - $userObject = $confDriver->createUserObject($userId); - $res = $userObject->checkCookieString($userPass); - return $res; - } - $seed = $authDriver->getSeed(false); - if($seed != $returnSeed) return false; - return $authDriver->checkPassword($userId, $userPass, $returnSeed); - } - /** - * Update the password in the auth driver implementation. - * @static - * @throws Exception - * @param $userId - * @param $userPass - * @return bool - */ - static function updatePassword($userId, $userPass) - { - if(strlen($userPass) < ConfService::getCoreConf("PASSWORD_MINLENGTH", "auth")){ - $messages = ConfService::getMessages(); - throw new Exception($messages[378]); - } - $userId = AuthService::filterUserSensitivity($userId); - $authDriver = ConfService::getAuthDriverImpl(); - $authDriver->changePassword($userId, $userPass); - if($authDriver->getOption("TRANSMIT_CLEAR_PASS") === true){ - // We can directly update the HA1 version of the WEBDAV Digest - $realm = ConfService::getCoreConf("WEBDAV_DIGESTREALM"); - $ha1 = md5("{$userId}:{$realm}:{$userPass}"); - $zObj = ConfService::getConfStorageImpl()->createUserObject($userId); - $wData = $zObj->getPref("AJXP_WEBDAV_DATA"); - if(!is_array($wData)) $wData = array(); - $wData["HA1"] = $ha1; - $zObj->setPref("AJXP_WEBDAV_DATA", $wData); - $zObj->save(); - } - AJXP_Logger::logAction("Update Password", array("user_id"=>$userId)); - return true; - } - /** - * Create a user - * @static - * @throws Exception - * @param $userId - * @param $userPass - * @param bool $isAdmin - * @return null - * @todo the minlength check is probably causing problem with the bridges - */ - static function createUser($userId, $userPass, $isAdmin=false) - { - $userId = AuthService::filterUserSensitivity($userId); - AJXP_Controller::applyHook("user.before_create", array($userId, $userPass, $isAdmin)); - if(!ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth") && $userId == "guest"){ - throw new Exception("Reserved user id"); - } - /* - if(strlen($userPass) < ConfService::getCoreConf("PASSWORD_MINLENGTH", "auth") && $userId != "guest"){ - $messages = ConfService::getMessages(); - throw new Exception($messages[378]); - } - */ - $authDriver = ConfService::getAuthDriverImpl(); - $confDriver = ConfService::getConfStorageImpl(); - $authDriver->createUser($userId, $userPass); - $user = null; - if($isAdmin){ - $user = $confDriver->createUserObject($userId); - $user->setAdmin(true); - $user->save("superuser"); - } - if($authDriver->getOption("TRANSMIT_CLEAR_PASS") === true){ - $realm = ConfService::getCoreConf("WEBDAV_DIGESTREALM"); - $ha1 = md5("{$userId}:{$realm}:{$userPass}"); - if(!isSet($user)){ - $user = $confDriver->createUserObject($userId); - } - $wData = $user->getPref("AJXP_WEBDAV_DATA"); - if(!is_array($wData)) $wData = array(); - $wData["HA1"] = $ha1; - $user->setPref("AJXP_WEBDAV_DATA", $wData); - $user->save(); - } - AJXP_Controller::applyHook("user.after_create", array($user)); - AJXP_Logger::logAction("Create User", array("user_id"=>$userId)); - return null; - } - /** - * Detect the number of admin users - * @static - * @return int|void - */ - static function countAdminUsers(){ - $confDriver = ConfService::getConfStorageImpl(); - $auth = ConfService::getAuthDriverImpl(); - $count = $confDriver->countAdminUsers(); - if(!$count && $auth->userExists("admin") && $confDriver->getName() == "serial"){ - return -1; - } - return $count; - } - - /** - * Delete a user in the auth/conf driver impl - * @static - * @param $userId - * @return bool - */ - static function deleteUser($userId) - { - $userId = AuthService::filterUserSensitivity($userId); - AJXP_Controller::applyHook("user.before_delete", array($userId)); - $authDriver = ConfService::getAuthDriverImpl(); - $authDriver->deleteUser($userId); - $subUsers = array(); - ConfService::getConfStorageImpl()->deleteUser($userId, $subUsers); - foreach ($subUsers as $deletedUser){ - $authDriver->deleteUser($deletedUser); - } - AJXP_Controller::applyHook("user.after_delete", array($userId)); - AJXP_Logger::logAction("Delete User", array("user_id"=>$userId, "sub_user" => implode(",", $subUsers))); - return true; - } - - static function filterBaseGroup($baseGroup){ - $u = self::getLoggedUser(); - // make sure it starts with a slash. - $baseGroup = "/".ltrim($baseGroup, "/"); - if($u == null) return $baseGroup; - if($u->getGroupPath() != "/") { - if($baseGroup == "/") return $u->getGroupPath(); - else return $u->getGroupPath().$baseGroup; - }else{ - return $baseGroup; - } - } - - static function listChildrenGroups($baseGroup = "/"){ - - return ConfService::getAuthDriverImpl()->listChildrenGroups(self::filterBaseGroup($baseGroup)); - - } - - static function createGroup($baseGroup, $groupName, $groupLabel){ - ConfService::getConfStorageImpl()->createGroup(rtrim(self::filterBaseGroup($baseGroup), "/")."/".$groupName, $groupLabel); - } - - static function deleteGroup($baseGroup, $groupName){ - ConfService::getConfStorageImpl()->deleteGroup(rtrim(self::filterBaseGroup($baseGroup), "/")."/".$groupName); - } - - static function getChildrenUsers($parentUserId){ - return ConfService::getConfStorageImpl()->getUserChildren($parentUserId); - } - - static function getUsersForRepository($repositoryId){ - return ConfService::getConfStorageImpl()->getUsersForRepository($repositoryId); - } - - /** - * @static - * @param string $baseGroup - * @param null $regexp - * @param $offset - * @param $limit - * @param bool $cleanLosts - * @return array - */ - static function listUsers($baseGroup = "/", $regexp = null, $offset = -1, $limit = -1, $cleanLosts = true) - { - $baseGroup = self::filterBaseGroup($baseGroup); - $authDriver = ConfService::getAuthDriverImpl(); - $confDriver = ConfService::getConfStorageImpl(); - $allUsers = array(); - $paginated = false; - if(($regexp != null || $offset != -1 || $limit != -1) && $authDriver->supportsUsersPagination()){ - $users = $authDriver->listUsersPaginated($baseGroup, $regexp, $offset, $limit); - $paginated = true; - }else{ - $users = $authDriver->listUsers($baseGroup); - } - foreach (array_keys($users) as $userId) - { - if(($userId == "guest" && !ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth")) || $userId == "ajxp.admin.users" || $userId == "") continue; - if($regexp != null && !$authDriver->supportsUsersPagination() && !preg_match("/$regexp/i", $userId)) continue; - $allUsers[$userId] = $confDriver->createUserObject($userId); - if($paginated){ - // Make sure to reload all children objects - foreach($confDriver->getUserChildren($userId) as $childObject){ - $allUsers[$childObject->getId()] = $childObject; - } - } - } - if($paginated && $cleanLosts){ - // Remove 'lost' items (children without parents). - foreach($allUsers as $id => $object){ - if($object->hasParent() && !array_key_exists($object->getParent(), $allUsers)){ - unset($allUsers[$id]); - } - } - } - return $allUsers; - } - - static function authSupportsPagination(){ - $authDriver = ConfService::getAuthDriverImpl(); - return $authDriver->supportsUsersPagination(); - } - - static function authCountUsers($baseGroup="/", $regexp=""){ - $authDriver = ConfService::getAuthDriverImpl(); - return $authDriver->getUsersCount($baseGroup, $regexp); - } - - static function getAuthScheme($userName){ - $authDriver = ConfService::getAuthDriverImpl(); - return $authDriver->getAuthScheme($userName); - } - - static function driverSupportsAuthSchemes(){ - $authDriver = ConfService::getAuthDriverImpl(); - return $authDriver->supportsAuthSchemes(); - } - - /** - * Get Role by Id - * - * @param string $roleId - * @param boolean $createIfNotExists - * @return AJXP_Role - */ - static function getRole($roleId, $createIfNotExists = false){ - $roles = self::getRolesList(array($roleId)); - if(isSet($roles[$roleId])) return $roles[$roleId]; - if($createIfNotExists){ - $role = new AJXP_Role($roleId); - if(self::getLoggedUser()!=null && self::getLoggedUser()->getGroupPath()!=null){ - $role->setGroupPath(self::getLoggedUser()->getGroupPath()); - } - self::updateRole($role); - return $role; - } - return false; - } - - /** - * Create or update role - * - * @param AJXP_Role $roleObject - */ - static function updateRole($roleObject, $userObject = null){ - ConfService::getConfStorageImpl()->updateRole($roleObject, $userObject); - } - /** - * Delete a role by its id - * @static - * @param string $roleId - * @return void - */ - static function deleteRole($roleId){ - ConfService::getConfStorageImpl()->deleteRole($roleId); - } - - static function filterPluginParameters($pluginId, $params, $repoId = null){ - $logged = self::getLoggedUser(); - if($logged == null) return $params; - if($repoId == null){ - $repo = ConfService::getRepository(); - if($repo!=null) $repoId = $repo->getId(); - } - if($logged == null || $logged->mergedRole == null) return $params; - $roleParams = $logged->mergedRole->listParameters(); - if(iSSet($roleParams[AJXP_REPO_SCOPE_ALL][$pluginId])){ - $params = array_merge($params, $roleParams[AJXP_REPO_SCOPE_ALL][$pluginId]); - } - if($repoId != null && isSet($roleParams[$repoId][$pluginId])){ - $params = array_merge($params, $roleParams[$repoId][$pluginId]); - } - return $params; - } - - /** - * Get all defined roles - * @static - * @param array $roleIds - * @param boolean $excludeReserved, - * @return AJXP_Role[] - */ - static function getRolesList($roleIds = array(), $excludeReserved = false){ - //if(isSet(self::$roles)) return self::$roles; - $confDriver = ConfService::getConfStorageImpl(); - self::$roles = $confDriver->listRoles($roleIds, $excludeReserved); - $repoList = null; - foreach(self::$roles as $roleId => $roleObject){ - if(is_a($roleObject, "AjxpRole")){ - if($repoList == null) $repoList = ConfService::getRepositoriesList("all"); - $newRole = new AJXP_Role($roleId); - $newRole->migrateDeprectated($repoList, $roleObject); - self::$roles[$roleId] = $newRole; - self::updateRole($newRole); - } - } - return self::$roles; - } - - static function allowedForCurrentGroup(AjxpGroupPathProvider $provider, $userObject = null){ - $l = ($userObject == null ? self::getLoggedUser() : $userObject); - $pGP = $provider->getGroupPath(); - if(empty($pGP)) $pGP = "/"; - if($l == null || $l->getGroupPath() == null || $pGP == null) return true; - return (strpos($l->getGroupPath(), $pGP, 0) === 0); - } - - static function canAdministrate(AjxpGroupPathProvider $provider, $userObject = null){ - $l = ($userObject == null ? self::getLoggedUser() : $userObject); - $pGP = $provider->getGroupPath(); - if(empty($pGP)) $pGP = "/"; - if($l == null || $l->getGroupPath() == null || $pGP == null) return true; - return (strpos($pGP, $l->getGroupPath(), 0) === 0); - } - - static function canAssign(AjxpGroupPathProvider $provider, $userObject = null){ - $l = ($userObject == null ? self::getLoggedUser() : $userObject); - $pGP = $provider->getGroupPath(); - if(empty($pGP)) $pGP = "/"; - if($l == null || $l->getGroupPath() == null || $pGP == null) return true; - return (strpos($l->getGroupPath(), $pGP, 0) === 0); - } - -} \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * Static access to the authentication mechanism. Encapsulates the authDriver implementation + * @package AjaXplorer + * @subpackage Core + */ +class AuthService +{ + public static $roles; + public static $useSession = true; + private static $currentUser; + /** + * Whether the whole users management system is enabled or not. + * @static + * @return bool + */ + public static function usersEnabled() + { + return ConfService::getCoreConf("ENABLE_USERS", "auth"); + } + /** + * Whether the current auth driver supports password update or not + * @static + * @return bool + */ + public static function changePasswordEnabled() + { + $authDriver = ConfService::getAuthDriverImpl(); + return $authDriver->passwordsEditable(); + } + /** + * Get a unique seed from the current auth driver + * @static + * @return int|string + */ + public static function generateSeed() + { + $authDriver = ConfService::getAuthDriverImpl(); + return $authDriver->getSeed(true); + } + + /** + * Put a secure token in the session + * @static + * @return + */ + public static function generateSecureToken() + { + $_SESSION["SECURE_TOKEN"] = AJXP_Utils::generateRandomString(32); //md5(time()); + return $_SESSION["SECURE_TOKEN"]; + } + /** + * Get the secure token from the session + * @static + * @return string|bool + */ + public static function getSecureToken() + { + return (isSet($_SESSION["SECURE_TOKEN"])?$_SESSION["SECURE_TOKEN"]:FALSE); + } + /** + * Verify a secure token value from the session + * @static + * @param string $token + * @return bool + */ + public static function checkSecureToken($token) + { + if (isSet($_SESSION["SECURE_TOKEN"]) && $_SESSION["SECURE_TOKEN"] == $token) { + return true; + } + return false; + } + + /** + * Get the currently logged user object + * @return AbstractAjxpUser + */ + public static function getLoggedUser() + { + if (self::$useSession && isSet($_SESSION["AJXP_USER"])) { + if (is_a($_SESSION["AJXP_USER"], "__PHP_Incomplete_Class")) { + session_unset("AJXP_USER"); + return null; + } + return $_SESSION["AJXP_USER"]; + } + if(!self::$useSession && isSet(self::$currentUser)) return self::$currentUser; + return null; + } + /** + * Call the preLogUser() functino on the auth driver implementation + * @static + * @param string $remoteSessionId + * @return void + */ + public static function preLogUser($remoteSessionId = "") + { + if(AuthService::getLoggedUser() != null) return ; + $authDriver = ConfService::getAuthDriverImpl(); + $authDriver->preLogUser($remoteSessionId); + return ; + } + /** + * The array is located in the AjxpTmpDir/failedAJXP.log + * @static + * @return array + */ + public static function getBruteForceLoginArray() + { + $failedLog = AJXP_Utils::getAjxpTmpDir()."/failedAJXP.log"; + $loginAttempt = @file_get_contents($failedLog); + $loginArray = unserialize($loginAttempt); + $ret = array(); + $curTime = time(); + if (is_array($loginArray)) { + // Filter the array (all old time are cleaned) + foreach ($loginArray as $key => $login) { + if (($curTime - $login["time"]) <= 60 * 60 * 24) $ret[$key] = $login; + } + } + return $ret; + } + /** + * Store the array + * @static + * @param $loginArray + * @return void + */ + public static function setBruteForceLoginArray($loginArray) + { + $failedLog = AJXP_Utils::getAjxpTmpDir()."/failedAJXP.log"; + @file_put_contents($failedLog, serialize($loginArray)); + } + /** + * Determines whether the user is try to make many attemps + * @static + * @param $loginArray + * @return bool + */ + public static function checkBruteForceLogin(&$loginArray) + { + if (isSet($_SERVER['REMOTE_ADDR'])) { + $serverAddress = $_SERVER['REMOTE_ADDR']; + } else { + $serverAddress = $_SERVER['SERVER_ADDR']; + } + $login = null; + if (isSet($loginArray[$serverAddress])) { + $login = $loginArray[$serverAddress]; + } + if (is_array($login)) { + $login["count"]++; + } else $login = array("count"=>1, "time"=>time()); + $loginArray[$serverAddress] = $login; + if ($login["count"] > 3) { + if (AJXP_SERVER_DEBUG) { + AJXP_Logger::debug("DEBUG : IGNORING BRUTE FORCE ATTEMPTS!"); + return true; + } + return FALSE; + } + return TRUE; + } + /** + * Is there a brute force login attempt? + * @static + * @return bool + */ + public static function suspectBruteForceLogin() + { + $loginAttempt = AuthService::getBruteForceLoginArray(); + return !AuthService::checkBruteForceLogin($loginAttempt); + } + + public static function filterUserSensitivity($user) + { + if (!ConfService::getCoreConf("CASE_SENSITIVE", "auth")) { + return strtolower($user); + } else { + return $user; + } + } + + public static function ignoreUserCase() + { + return !ConfService::getCoreConf("CASE_SENSITIVE", "auth"); + } + + /** + * @static + * @param AbstractAjxpUser $user + */ + public static function refreshRememberCookie($user) + { + $current = $_COOKIE["AjaXplorer-remember"]; + if (!empty($current)) { + $user->invalidateCookieString(substr($current, strpos($current, ":")+1)); + } + $rememberPass = $user->getCookieString(); + setcookie("AjaXplorer-remember", $user->id.":".$rememberPass, time()+3600*24*10, null, null, (isSet($_SERVER["HTTPS"]) && strtolower($_SERVER["HTTPS"]) == "on"), true); + } + + /** + * @static + * @return bool + */ + public static function hasRememberCookie() + { + return (isSet($_COOKIE["AjaXplorer-remember"]) && !empty($_COOKIE["AjaXplorer-remember"])); + } + + /** + * @static + * Warning, must be called before sending other headers! + */ + public static function clearRememberCookie() + { + $current = $_COOKIE["AjaXplorer-remember"]; + $user = AuthService::getLoggedUser(); + if (!empty($current) && $user != null) { + $user->invalidateCookieString(substr($current, strpos($current, ":")+1)); + } + setcookie("AjaXplorer-remember", "", time()-3600, null, null, (isSet($_SERVER["HTTPS"]) && strtolower($_SERVER["HTTPS"]) == "on"), true); + } + + public static function logTemporaryUser($parentUserId, $temporaryUserId) + { + $parentUserId = self::filterUserSensitivity($parentUserId); + $temporaryUserId = self::filterUserSensitivity($temporaryUserId); + $confDriver = ConfService::getConfStorageImpl(); + $parentUser = $confDriver->createUserObject($parentUserId); + $temporaryUser = $confDriver->createUserObject($temporaryUserId); + $temporaryUser->mergedRole = $parentUser->mergedRole; + $temporaryUser->rights = $parentUser->rights; + $temporaryUser->setGroupPath($parentUser->getGroupPath()); + $temporaryUser->setParent($parentUserId); + $temporaryUser->setResolveAsParent(true); + AJXP_Logger::logAction("Log in", array("temporary user" => $temporaryUserId, "owner" => $parentUserId)); + self::updateUser($temporaryUser); + } + + public static function clearTemporaryUser($temporaryUserId) + { + AJXP_Logger::logAction("Log out", array("temporary user"), $temporaryUserId); + if (isSet($_SESSION["AJXP_USER"]) || isSet(self::$currentUser)) { + AJXP_Logger::logAction("Log Out"); + unset($_SESSION["AJXP_USER"]); + if(isSet(self::$currentUser)) unset(self::$currentUser); + if (ConfService::getCoreConf("SESSION_SET_CREDENTIALS", "auth")) { + AJXP_Safe::clearCredentials(); + } + } + } + + /** + * Log the user from its credentials + * @static + * @param string $user_id The user id + * @param string $pwd The password + * @param bool $bypass_pwd Ignore password or not + * @param bool $cookieLogin Is it a logging from the remember me cookie? + * @param string $returnSeed The unique seed + * @return int + */ + public static function logUser($user_id, $pwd, $bypass_pwd = false, $cookieLogin = false, $returnSeed="") + { + $user_id = self::filterUserSensitivity($user_id); + if ($cookieLogin && !isSet($_COOKIE["AjaXplorer-remember"])) { + return -5; // SILENT IGNORE + } + if ($cookieLogin) { + list($user_id, $pwd) = explode(":", $_COOKIE["AjaXplorer-remember"]); + } + $confDriver = ConfService::getConfStorageImpl(); + if ($user_id == null) { + if (self::$useSession) { + if(isSet($_SESSION["AJXP_USER"]) && is_object($_SESSION["AJXP_USER"])) return 1; + } else { + if(isSet(self::$currentUser) && is_object(self::$currentUser)) return 1; + } + if (ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth")) { + $authDriver = ConfService::getAuthDriverImpl(); + if (!$authDriver->userExists("guest")) { + AuthService::createUser("guest", ""); + $guest = $confDriver->createUserObject("guest"); + $guest->save("superuser"); + } + AuthService::logUser("guest", null); + return 1; + } + return -1; + } + $authDriver = ConfService::getAuthDriverImpl(); + // CHECK USER PASSWORD HERE! + $loginAttempt = AuthService::getBruteForceLoginArray(); + $bruteForceLogin = AuthService::checkBruteForceLogin($loginAttempt); + AuthService::setBruteForceLoginArray($loginAttempt); + + if (!$authDriver->userExists($user_id)) { + if ($bruteForceLogin === FALSE) { + return -4; + } else { + return -1; + } + } + if (!$bypass_pwd) { + if (!AuthService::checkPassword($user_id, $pwd, $cookieLogin, $returnSeed)) { + if ($bruteForceLogin === FALSE) { + return -4; + } else { + if($cookieLogin) return -5; + return -1; + } + } + } + // Successful login attempt + unset($loginAttempt[$_SERVER["REMOTE_ADDR"]]); + AuthService::setBruteForceLoginArray($loginAttempt); + + // Setting session credentials if asked in config + if (ConfService::getCoreConf("SESSION_SET_CREDENTIALS", "auth")) { + list($authId, $authPwd) = $authDriver->filterCredentials($user_id, $pwd); + AJXP_Safe::storeCredentials($authId, $authPwd); + } + + $user = $confDriver->createUserObject($user_id); + if ($user->getLock() == "logout") { + return -1; + } + if ($authDriver->isAjxpAdmin($user_id)) { + $user->setAdmin(true); + } + if ($user->isAdmin()) { + $user = AuthService::updateAdminRights($user); + } else { + if (!$user->hasParent() && $user_id != "guest") { + //$user->setAcl("ajxp_shared", "rw"); + } + } + if(self::$useSession) $_SESSION["AJXP_USER"] = $user; + else self::$currentUser = $user; + + if ($authDriver->autoCreateUser() && !$user->storageExists()) { + $user->save("superuser"); // make sure update rights now + } + AJXP_Logger::logAction("Log In"); + return 1; + } + /** + * Store the object in the session + * @static + * @param $userObject + * @return void + */ + public static function updateUser($userObject) + { + if(self::$useSession) $_SESSION["AJXP_USER"] = $userObject; + else self::$currentUser = $userObject; + } + /** + * Clear the session + * @static + * @return void + */ + public static function disconnect() + { + if (isSet($_SESSION["AJXP_USER"]) || isSet(self::$currentUser)) { + AuthService::clearRememberCookie(); + AJXP_Logger::logAction("Log Out"); + unset($_SESSION["AJXP_USER"]); + if(isSet(self::$currentUser)) unset(self::$currentUser); + if (ConfService::getCoreConf("SESSION_SET_CREDENTIALS", "auth")) { + AJXP_Safe::clearCredentials(); + } + } + } + /** + * Specific operations to perform at boot time + * @static + * @param array $START_PARAMETERS A HashTable of parameters to send back to the client + * @return void + */ + public static function bootSequence(&$START_PARAMETERS) + { + if(AJXP_Utils::detectApplicationFirstRun()) return; + if(file_exists(AJXP_CACHE_DIR."/admin_counted")) return; + $rootRole = AuthService::getRole("ROOT_ROLE", false); + if ($rootRole === false) { + $rootRole = new AJXP_Role("ROOT_ROLE"); + $rootRole->setLabel("Root Role"); + $rootRole->setAutoApplies(array("standard")); + foreach (ConfService::getRepositoriesList("all") as $repositoryId => $repoObject) { + if($repoObject->isTemplate) continue; + $gp = $repoObject->getGroupPath(); + if (empty($gp) || $gp == "/") { + if ($repoObject->getDefaultRight() != "") { + $rootRole->setAcl($repositoryId, $repoObject->getDefaultRight()); + } + } + } + AuthService::updateRole($rootRole); + } + $miniRole = AuthService::getRole("MINISITE", false); + if ($miniRole === false) { + $rootRole = new AJXP_Role("MINISITE"); + $rootRole->setLabel("Minisite Users"); + $actions = array( + "access.fs" => array("ajxp_link", "chmod", "purge"), + "meta.watch" => array("toggle_watch"), + "conf.serial"=> array("get_bookmarks"), + "conf.sql"=> array("get_bookmarks"), + "index.lucene" => array("index"), + "action.share" => array("share"), + "gui.ajax" => array("bookmark"), + "auth.serial" => array("pass_change"), + "auth.sql" => array("pass_change"), + ); + foreach ($actions as $pluginId => $acts) { + foreach ($acts as $act) { + $rootRole->setActionState($pluginId, $act, AJXP_REPO_SCOPE_SHARED, false); + } + } + AuthService::updateRole($rootRole); + } + $miniRole = AuthService::getRole("MINISITE_NODOWNLOAD", false); + if ($miniRole === false) { + $rootRole = new AJXP_Role("MINISITE_NODOWNLOAD"); + $rootRole->setLabel("Minisite Users - No Download"); + $actions = array( + "access.fs" => array("download", "download_chunk", "prepare_chunk_dl", "download_all") + ); + foreach ($actions as $pluginId => $acts) { + foreach ($acts as $act) { + $rootRole->setActionState($pluginId, $act, AJXP_REPO_SCOPE_SHARED, false); + } + } + AuthService::updateRole($rootRole); + } + $miniRole = AuthService::getRole("GUEST", false); + if ($miniRole === false) { + $rootRole = new AJXP_Role("GUEST"); + $rootRole->setLabel("Guest user role"); + $actions = array( + "access.fs" => array("purge"), + "meta.watch" => array("toggle_watch"), + "index.lucene" => array("index"), + ); + $rootRole->setAutoApplies(array("guest")); + foreach ($actions as $pluginId => $acts) { + foreach ($acts as $act) { + $rootRole->setActionState($pluginId, $act, AJXP_REPO_SCOPE_ALL); + } + } + AuthService::updateRole($rootRole); + } + $adminCount = AuthService::countAdminUsers(); + if ($adminCount == 0) { + $authDriver = ConfService::getAuthDriverImpl(); + $adminPass = ADMIN_PASSWORD; + if ($authDriver->getOption("TRANSMIT_CLEAR_PASS") !== true) { + $adminPass = md5(ADMIN_PASSWORD); + } + AuthService::createUser("admin", $adminPass, true); + if (ADMIN_PASSWORD == INITIAL_ADMIN_PASSWORD) { + $userObject = ConfService::getConfStorageImpl()->createUserObject("admin"); + $userObject->setAdmin(true); + AuthService::updateAdminRights($userObject); + if (AuthService::changePasswordEnabled()) { + $userObject->setLock("pass_change"); + } + $userObject->save("superuser"); + $START_PARAMETERS["ALERT"] .= "Warning! User 'admin' was created with the initial password '". INITIAL_ADMIN_PASSWORD ."'. \\nPlease log in as admin and change the password now!"; + } + AuthService::updateUser($userObject); + } else if ($adminCount == -1) { + // Here we may come from a previous version! Check the "admin" user and set its right as admin. + $confStorage = ConfService::getConfStorageImpl(); + $adminUser = $confStorage->createUserObject("admin"); + $adminUser->setAdmin(true); + $adminUser->save("superuser"); + $START_PARAMETERS["ALERT"] .= "There is an admin user, but without admin right. Now any user can have the administration rights, \\n your 'admin' user was set with the admin rights. Please check that this suits your security configuration."; + } + file_put_contents(AJXP_CACHE_DIR."/admin_counted", "true"); + + } + /** + * If the auth driver implementatino has a logout redirect URL, clear session and return it. + * @static + * @param bool $logUserOut + * @return bool + */ + public static function getLogoutAddress($logUserOut = true) + { + $authDriver = ConfService::getAuthDriverImpl(); + $logout = $authDriver->getLogoutRedirect(); + if ($logUserOut) { + self::disconnect(); + } + return $logout; + } + /** + * Compute the default repository id to log the current user + * @static + * @return int|string + */ + public static function getDefaultRootId() + { + $loggedUser = AuthService::getLoggedUser(); + if($loggedUser == null) return 0; + $repoList = ConfService::getRepositoriesList(); + foreach ($repoList as $rootDirIndex => $rootDirObject) { + if ($loggedUser->canRead($rootDirIndex."") || $loggedUser->canWrite($rootDirIndex."")) { + // Warning : do not grant access to admin repository to a non admin, or there will be + // an "Empty Repository Object" error. + if ($rootDirObject->getAccessType()=="ajxp_conf" && AuthService::usersEnabled() && !$loggedUser->isAdmin()) { + continue; + } + if ($rootDirObject->getAccessType() == "ajxp_shared" && count($repoList) > 1) { + continue; + } + return $rootDirIndex; + } + } + return 0; + } + + /** + * Update a user with admin rights and return it + * @param AbstractAjxpUser $adminUser + * @return AbstractAjxpUser + */ + public static function updateAdminRights($adminUser) + { + foreach (ConfService::getRepositoriesList() as $repoId => $repoObject) { + if(!self::allowedForCurrentGroup($repoObject, $adminUser)) continue; + if($repoObject->hasParent() && $repoObject->getParentId() != $adminUser->getId()) continue; + $adminUser->personalRole->setAcl($repoId, "rw"); + $adminUser->recomputeMergedRole(); + } + $adminUser->save("superuser"); + return $adminUser; + } + + /** + * Update a user object with the default repositories rights + * + * @param AbstractAjxpUser $userObject + */ + public static function updateDefaultRights(&$userObject) + { + if (!$userObject->hasParent()) { + $changes = false; + foreach (ConfService::getRepositoriesList() as $repositoryId => $repoObject) { + if(!self::allowedForCurrentGroup($repoObject, $userObject)) continue; + if($repoObject->isTemplate) continue; + if ($repoObject->getDefaultRight() != "") { + $changes = true; + $userObject->personalRole->setAcl($repositoryId, $repoObject->getDefaultRight()); + } + } + if ($changes) { + $userObject->recomputeMergedRole(); + } + foreach (AuthService::getRolesList(array(), true) as $roleId => $roleObject) { + if(!self::allowedForCurrentGroup($roleObject, $userObject)) continue; + if ($userObject->getProfile() == "shared" && $roleObject->autoAppliesTo("shared")) { + $userObject->addRole($roleObject); + } else if ($roleObject->autoAppliesTo("standard")) { + $userObject->addRole($roleObject); + } + } + } + } + + /** + * @static + * @param AbstractAjxpUser $userObject + */ + public static function updateAutoApplyRole(&$userObject) + { + foreach (AuthService::getRolesList(array(), true) as $roleId => $roleObject) { + if(!self::allowedForCurrentGroup($roleObject, $userObject)) continue; + if ($roleObject->autoAppliesTo($userObject->getProfile()) || $roleObject->autoAppliesTo("all")) { + $userObject->addRole($roleObject); + } + } + } + + public static function updateAuthProvidedData(&$userObject) + { + ConfService::getAuthDriverImpl()->updateUserObject($userObject); + } + + /** + * Use driver implementation to check whether the user exists or not. + * @static + * @param String $userId + * @param String $mode "r" or "w" + * @return bool + */ + public static function userExists($userId, $mode = "r") + { + if ($userId == "guest" && !ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth")) { + return false; + } + $userId = AuthService::filterUserSensitivity($userId); + $authDriver = ConfService::getAuthDriverImpl(); + if ($mode == "w") { + return $authDriver->userExistsWrite($userId); + } + return $authDriver->userExists($userId); + } + + /** + * Make sure a user id is not reserved for low-level tasks (currently "guest" and "shared"). + * @static + * @param String $username + * @return bool + */ + public static function isReservedUserId($username) + { + $username = AuthService::filterUserSensitivity($username); + return in_array($username, array("guest", "shared")); + } + + /** + * Simple password encoding, should be deported in a more complex/configurable function + * @static + * @param $pass + * @return string + */ + public static function encodePassword($pass) + { + return md5($pass); + } + /** + * Check a password + * @static + * @param $userId + * @param $userPass + * @param bool $cookieString + * @param string $returnSeed + * @return bool|void + */ + public static function checkPassword($userId, $userPass, $cookieString = false, $returnSeed = "") + { + if(ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth") && $userId == "guest") return true; + $userId = AuthService::filterUserSensitivity($userId); + $authDriver = ConfService::getAuthDriverImpl(); + if ($cookieString) { + $confDriver = ConfService::getConfStorageImpl(); + $userObject = $confDriver->createUserObject($userId); + $res = $userObject->checkCookieString($userPass); + return $res; + } + $seed = $authDriver->getSeed(false); + if($seed != $returnSeed) return false; + return $authDriver->checkPassword($userId, $userPass, $returnSeed); + } + /** + * Update the password in the auth driver implementation. + * @static + * @throws Exception + * @param $userId + * @param $userPass + * @return bool + */ + public static function updatePassword($userId, $userPass) + { + if (strlen($userPass) < ConfService::getCoreConf("PASSWORD_MINLENGTH", "auth")) { + $messages = ConfService::getMessages(); + throw new Exception($messages[378]); + } + $userId = AuthService::filterUserSensitivity($userId); + $authDriver = ConfService::getAuthDriverImpl(); + $authDriver->changePassword($userId, $userPass); + if ($authDriver->getOption("TRANSMIT_CLEAR_PASS") === true) { + // We can directly update the HA1 version of the WEBDAV Digest + $realm = ConfService::getCoreConf("WEBDAV_DIGESTREALM"); + $ha1 = md5("{$userId}:{$realm}:{$userPass}"); + $zObj = ConfService::getConfStorageImpl()->createUserObject($userId); + $wData = $zObj->getPref("AJXP_WEBDAV_DATA"); + if(!is_array($wData)) $wData = array(); + $wData["HA1"] = $ha1; + $zObj->setPref("AJXP_WEBDAV_DATA", $wData); + $zObj->save(); + } + AJXP_Logger::logAction("Update Password", array("user_id"=>$userId)); + return true; + } + /** + * Create a user + * @static + * @throws Exception + * @param $userId + * @param $userPass + * @param bool $isAdmin + * @return null + * @todo the minlength check is probably causing problem with the bridges + */ + public static function createUser($userId, $userPass, $isAdmin=false) + { + $userId = AuthService::filterUserSensitivity($userId); + AJXP_Controller::applyHook("user.before_create", array($userId, $userPass, $isAdmin)); + if (!ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth") && $userId == "guest") { + throw new Exception("Reserved user id"); + } + /* + if (strlen($userPass) < ConfService::getCoreConf("PASSWORD_MINLENGTH", "auth") && $userId != "guest") { + $messages = ConfService::getMessages(); + throw new Exception($messages[378]); + } + */ + $authDriver = ConfService::getAuthDriverImpl(); + $confDriver = ConfService::getConfStorageImpl(); + $authDriver->createUser($userId, $userPass); + $user = null; + if ($isAdmin) { + $user = $confDriver->createUserObject($userId); + $user->setAdmin(true); + $user->save("superuser"); + } + if ($authDriver->getOption("TRANSMIT_CLEAR_PASS") === true) { + $realm = ConfService::getCoreConf("WEBDAV_DIGESTREALM"); + $ha1 = md5("{$userId}:{$realm}:{$userPass}"); + if (!isSet($user)) { + $user = $confDriver->createUserObject($userId); + } + $wData = $user->getPref("AJXP_WEBDAV_DATA"); + if(!is_array($wData)) $wData = array(); + $wData["HA1"] = $ha1; + $user->setPref("AJXP_WEBDAV_DATA", $wData); + $user->save(); + } + AJXP_Controller::applyHook("user.after_create", array($user)); + AJXP_Logger::logAction("Create User", array("user_id"=>$userId)); + return null; + } + /** + * Detect the number of admin users + * @static + * @return int|void + */ + public static function countAdminUsers() + { + $confDriver = ConfService::getConfStorageImpl(); + $auth = ConfService::getAuthDriverImpl(); + $count = $confDriver->countAdminUsers(); + if (!$count && $auth->userExists("admin") && $confDriver->getName() == "serial") { + return -1; + } + return $count; + } + + /** + * Delete a user in the auth/conf driver impl + * @static + * @param $userId + * @return bool + */ + public static function deleteUser($userId) + { + $userId = AuthService::filterUserSensitivity($userId); + AJXP_Controller::applyHook("user.before_delete", array($userId)); + $authDriver = ConfService::getAuthDriverImpl(); + $authDriver->deleteUser($userId); + $subUsers = array(); + ConfService::getConfStorageImpl()->deleteUser($userId, $subUsers); + foreach ($subUsers as $deletedUser) { + $authDriver->deleteUser($deletedUser); + } + AJXP_Controller::applyHook("user.after_delete", array($userId)); + AJXP_Logger::logAction("Delete User", array("user_id"=>$userId, "sub_user" => implode(",", $subUsers))); + return true; + } + + public static function filterBaseGroup($baseGroup) + { + $u = self::getLoggedUser(); + // make sure it starts with a slash. + $baseGroup = "/".ltrim($baseGroup, "/"); + if($u == null) return $baseGroup; + if ($u->getGroupPath() != "/") { + if($baseGroup == "/") return $u->getGroupPath(); + else return $u->getGroupPath().$baseGroup; + } else { + return $baseGroup; + } + } + + public static function listChildrenGroups($baseGroup = "/") + { + return ConfService::getAuthDriverImpl()->listChildrenGroups(self::filterBaseGroup($baseGroup)); + + } + + public static function createGroup($baseGroup, $groupName, $groupLabel) + { + ConfService::getConfStorageImpl()->createGroup(rtrim(self::filterBaseGroup($baseGroup), "/")."/".$groupName, $groupLabel); + } + + public static function deleteGroup($baseGroup, $groupName) + { + ConfService::getConfStorageImpl()->deleteGroup(rtrim(self::filterBaseGroup($baseGroup), "/")."/".$groupName); + } + + public static function getChildrenUsers($parentUserId) + { + return ConfService::getConfStorageImpl()->getUserChildren($parentUserId); + } + + public static function getUsersForRepository($repositoryId) + { + return ConfService::getConfStorageImpl()->getUsersForRepository($repositoryId); + } + + /** + * @static + * @param string $baseGroup + * @param null $regexp + * @param $offset + * @param $limit + * @param bool $cleanLosts + * @return array + */ + public static function listUsers($baseGroup = "/", $regexp = null, $offset = -1, $limit = -1, $cleanLosts = true) + { + $baseGroup = self::filterBaseGroup($baseGroup); + $authDriver = ConfService::getAuthDriverImpl(); + $confDriver = ConfService::getConfStorageImpl(); + $allUsers = array(); + $paginated = false; + if (($regexp != null || $offset != -1 || $limit != -1) && $authDriver->supportsUsersPagination()) { + $users = $authDriver->listUsersPaginated($baseGroup, $regexp, $offset, $limit); + $paginated = true; + } else { + $users = $authDriver->listUsers($baseGroup); + } + foreach (array_keys($users) as $userId) { + if(($userId == "guest" && !ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth")) || $userId == "ajxp.admin.users" || $userId == "") continue; + if($regexp != null && !$authDriver->supportsUsersPagination() && !preg_match("/$regexp/i", $userId)) continue; + $allUsers[$userId] = $confDriver->createUserObject($userId); + if ($paginated) { + // Make sure to reload all children objects + foreach ($confDriver->getUserChildren($userId) as $childObject) { + $allUsers[$childObject->getId()] = $childObject; + } + } + } + if ($paginated && $cleanLosts) { + // Remove 'lost' items (children without parents). + foreach ($allUsers as $id => $object) { + if ($object->hasParent() && !array_key_exists($object->getParent(), $allUsers)) { + unset($allUsers[$id]); + } + } + } + return $allUsers; + } + + public static function authSupportsPagination() + { + $authDriver = ConfService::getAuthDriverImpl(); + return $authDriver->supportsUsersPagination(); + } + + public static function authCountUsers($baseGroup="/", $regexp="") + { + $authDriver = ConfService::getAuthDriverImpl(); + return $authDriver->getUsersCount($baseGroup, $regexp); + } + + public static function getAuthScheme($userName) + { + $authDriver = ConfService::getAuthDriverImpl(); + return $authDriver->getAuthScheme($userName); + } + + public static function driverSupportsAuthSchemes() + { + $authDriver = ConfService::getAuthDriverImpl(); + return $authDriver->supportsAuthSchemes(); + } + + /** + * Get Role by Id + * + * @param string $roleId + * @param boolean $createIfNotExists + * @return AJXP_Role + */ + public static function getRole($roleId, $createIfNotExists = false) + { + $roles = self::getRolesList(array($roleId)); + if(isSet($roles[$roleId])) return $roles[$roleId]; + if ($createIfNotExists) { + $role = new AJXP_Role($roleId); + if (self::getLoggedUser()!=null && self::getLoggedUser()->getGroupPath()!=null) { + $role->setGroupPath(self::getLoggedUser()->getGroupPath()); + } + self::updateRole($role); + return $role; + } + return false; + } + + /** + * Create or update role + * + * @param AJXP_Role $roleObject + */ + public static function updateRole($roleObject, $userObject = null) + { + ConfService::getConfStorageImpl()->updateRole($roleObject, $userObject); + } + /** + * Delete a role by its id + * @static + * @param string $roleId + * @return void + */ + public static function deleteRole($roleId) + { + ConfService::getConfStorageImpl()->deleteRole($roleId); + } + + public static function filterPluginParameters($pluginId, $params, $repoId = null) + { + $logged = self::getLoggedUser(); + if($logged == null) return $params; + if ($repoId == null) { + $repo = ConfService::getRepository(); + if($repo!=null) $repoId = $repo->getId(); + } + if($logged == null || $logged->mergedRole == null) return $params; + $roleParams = $logged->mergedRole->listParameters(); + if (iSSet($roleParams[AJXP_REPO_SCOPE_ALL][$pluginId])) { + $params = array_merge($params, $roleParams[AJXP_REPO_SCOPE_ALL][$pluginId]); + } + if ($repoId != null && isSet($roleParams[$repoId][$pluginId])) { + $params = array_merge($params, $roleParams[$repoId][$pluginId]); + } + return $params; + } + + /** + * Get all defined roles + * @static + * @param array $roleIds + * @param boolean $excludeReserved, + * @return AJXP_Role[] + */ + public static function getRolesList($roleIds = array(), $excludeReserved = false) + { + //if(isSet(self::$roles)) return self::$roles; + $confDriver = ConfService::getConfStorageImpl(); + self::$roles = $confDriver->listRoles($roleIds, $excludeReserved); + $repoList = null; + foreach (self::$roles as $roleId => $roleObject) { + if (is_a($roleObject, "AjxpRole")) { + if($repoList == null) $repoList = ConfService::getRepositoriesList("all"); + $newRole = new AJXP_Role($roleId); + $newRole->migrateDeprectated($repoList, $roleObject); + self::$roles[$roleId] = $newRole; + self::updateRole($newRole); + } + } + return self::$roles; + } + + public static function allowedForCurrentGroup(AjxpGroupPathProvider $provider, $userObject = null) + { + $l = ($userObject == null ? self::getLoggedUser() : $userObject); + $pGP = $provider->getGroupPath(); + if(empty($pGP)) $pGP = "/"; + if($l == null || $l->getGroupPath() == null || $pGP == null) return true; + return (strpos($l->getGroupPath(), $pGP, 0) === 0); + } + + public static function canAdministrate(AjxpGroupPathProvider $provider, $userObject = null) + { + $l = ($userObject == null ? self::getLoggedUser() : $userObject); + $pGP = $provider->getGroupPath(); + if(empty($pGP)) $pGP = "/"; + if($l == null || $l->getGroupPath() == null || $pGP == null) return true; + return (strpos($pGP, $l->getGroupPath(), 0) === 0); + } + + public static function canAssign(AjxpGroupPathProvider $provider, $userObject = null) + { + $l = ($userObject == null ? self::getLoggedUser() : $userObject); + $pGP = $provider->getGroupPath(); + if(empty($pGP)) $pGP = "/"; + if($l == null || $l->getGroupPath() == null || $pGP == null) return true; + return (strpos($l->getGroupPath(), $pGP, 0) === 0); + } + +} diff --git a/core/src/core/classes/class.CaptchaProvider.php b/core/src/core/classes/class.CaptchaProvider.php index ed79ac46b9..c6965d63a2 100644 --- a/core/src/core/classes/class.CaptchaProvider.php +++ b/core/src/core/classes/class.CaptchaProvider.php @@ -27,48 +27,49 @@ * @package AjaXplorer * @subpackage Core */ -class CaptchaProvider{ - /** +class CaptchaProvider +{ + /** * Print out a Captcha image * @static * @return void */ - public static function sendCaptcha(){ - - $libPath = AJXP_BIN_FOLDER."/securimage"; - - $img = new Securimage(); - $img->wordlist_file = $libPath."/words/words.txt"; - $img->gd_font_file = $libPath."/gdfonts/automatic.gdf"; - $img->signature_font = $img->ttf_file = $libPath."/AHGBold.ttf"; - - $img->image_height = 80; - $img->image_width = 170; - $img->perturbation = 0.85; - $img->image_bg_color = new Securimage_Color("#f6f6f6"); - $img->multi_text_color = array(new Securimage_Color("#3399ff"), - new Securimage_Color("#3300cc"), - new Securimage_Color("#3333cc"), - new Securimage_Color("#6666ff"), - new Securimage_Color("#99cccc") - ); - $img->use_multi_text = true; - $img->text_angle_minimum = -5; - $img->text_angle_maximum = 5; - $img->use_transparent_text = true; - $img->text_transparency_percentage = 30; // 100 = completely transparent - $img->num_lines = 5; - $img->line_color = new Securimage_Color("#eaeaea"); - $img->signature_color = new Securimage_Color(rand(0, 64), rand(64, 128), rand(128, 255)); - $img->use_wordlist = true; - if(!function_exists('imagettftext')){ - $img->use_gd_font = true; - $img->use_transparent_text = false; - $img->use_multi_text = false; - } - //$img->show($libPath."/backgrounds/bg3.jpg"); - $img->show(); - } + public static function sendCaptcha() + { + $libPath = AJXP_BIN_FOLDER."/securimage"; + + $img = new Securimage(); + $img->wordlist_file = $libPath."/words/words.txt"; + $img->gd_font_file = $libPath."/gdfonts/automatic.gdf"; + $img->signature_font = $img->ttf_file = $libPath."/AHGBold.ttf"; + + $img->image_height = 80; + $img->image_width = 170; + $img->perturbation = 0.85; + $img->image_bg_color = new Securimage_Color("#f6f6f6"); + $img->multi_text_color = array(new Securimage_Color("#3399ff"), + new Securimage_Color("#3300cc"), + new Securimage_Color("#3333cc"), + new Securimage_Color("#6666ff"), + new Securimage_Color("#99cccc") + ); + $img->use_multi_text = true; + $img->text_angle_minimum = -5; + $img->text_angle_maximum = 5; + $img->use_transparent_text = true; + $img->text_transparency_percentage = 30; // 100 = completely transparent + $img->num_lines = 5; + $img->line_color = new Securimage_Color("#eaeaea"); + $img->signature_color = new Securimage_Color(rand(0, 64), rand(64, 128), rand(128, 255)); + $img->use_wordlist = true; + if (!function_exists('imagettftext')) { + $img->use_gd_font = true; + $img->use_transparent_text = false; + $img->use_multi_text = false; + } + //$img->show($libPath."/backgrounds/bg3.jpg"); + $img->show(); + } /** * Verify the code against the current image. @@ -76,13 +77,11 @@ public static function sendCaptcha(){ * @param $code * @return bool */ - public static function checkCaptchaResult($code){ - - $img = new Securimage(); - return $img->check($code); - - } - -} + public static function checkCaptchaResult($code) + { + $img = new Securimage(); + return $img->check($code); + + } -?> \ No newline at end of file +} diff --git a/core/src/core/classes/class.ConfService.php b/core/src/core/classes/class.ConfService.php index 9d1ef26882..94e7b19f3d 100644 --- a/core/src/core/classes/class.ConfService.php +++ b/core/src/core/classes/class.ConfService.php @@ -1,1246 +1,1288 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * Configuration holder. Singleton class accessed statically, encapsulates the confDriver implementation. - * @package AjaXplorer - * @subpackage Core - */ -class ConfService -{ - private static $instance; - private $errors = array(); - private $configs = array(); - - /** - * @param AJXP_PluginsService $ajxpPluginService - * @return AbstractConfDriver - */ - public function confPluginSoftLoad($ajxpPluginService){ - - $booter = $ajxpPluginService->softLoad("boot.conf", array()); - $coreConfigs = $booter->loadPluginConfig("core", "conf"); - $corePlug = $ajxpPluginService->softLoad("core.conf", array()); - $corePlug->loadConfigs($coreConfigs); - return $corePlug->getConfImpl(); - - } - - /** - * @return AbstractConfDriver - */ - public static function getBootConfStorageImpl(){ - $inst = AJXP_PluginsService::getInstance()->findPluginById("boot.conf"); - if(empty($inst)){ - $inst = AJXP_PluginsService::getInstance()->softLoad("boot.conf", array()); - } - return $inst; - } - - /** - * Initialize singleton - * @static - * @return void - */ - public static function init(){ - $inst = self::getInstance(); - $inst->initInst(); - } - /** - * Load the boostrap_* files and their configs - * @return void - */ - public function initInst() - { - // INIT AS GLOBAL - $this->configs["AVAILABLE_LANG"] = self::listAvailableLanguages(); - if(isSet($_SERVER["HTTPS"]) && strtolower($_SERVER["HTTPS"]) == "on"){ - $this->configs["USE_HTTPS"] = true; - } - if(isSet($this->configs["USE_HTTPS"])){ - AJXP_Utils::safeIniSet("session.cookie_secure", true); - } - $this->configs["JS_DEBUG"] = AJXP_CLIENT_DEBUG; - $this->configs["SERVER_DEBUG"] = AJXP_SERVER_DEBUG; - - - if(is_file(AJXP_CONF_PATH."/bootstrap_repositories.php")){ - include(AJXP_CONF_PATH."/bootstrap_repositories.php"); - $this->configs["DEFAULT_REPOSITORIES"] = $REPOSITORIES; - }else{ - $this->configs["DEFAULT_REPOSITORIES"] = array(); - } - } - /** - * Start the singleton - * @static - * @return void - */ - public static function start(){ - $inst = self::getInstance(); - $inst->startInst(); - } - /** - * Init CONF, AUTH drivers - * Init Repositories - * @return void - */ - public function startInst(){ - AJXP_PluginsService::getInstance()->setPluginUniqueActiveForType("conf", self::getConfStorageImpl()->getName()); - } - /** - * Get errors generated by the boot sequence (init/start) - * @static - * @return array - */ - public static function getErrors(){ - return self::getInstance()->errors; - } - - /** - * @static - * @param $globalsArray - * @param string $interfaceCheck - * @internal param string $bootstrapConfigKey - * @internal param string $bootstrapConfigType - * @return AJXP_Plugin|null - */ - public static function instanciatePluginFromGlobalParams($globalsArray, $interfaceCheck = ""){ - - $plugin = false; - - if(is_string($globalsArray)){ - $globalsArray = array("instance_name" => $globalsArray); - } - - if(isSet($globalsArray["instance_name"])){ - $pName = $globalsArray["instance_name"]; - unset($globalsArray["instance_name"]); - $plugin = AJXP_PluginsService::getInstance()->softLoad($pName, $globalsArray); - $plugin->performChecks(); - } - - if($plugin != false && !empty($interfaceCheck)){ - if(!is_a($plugin, $interfaceCheck)){ - $plugin = false; - } - } - if($plugin !== false){ - AJXP_PluginsService::getInstance()->setPluginActive($plugin->getType(), $plugin->getName(), true, $plugin); - } - return $plugin; - - } - /** - * Check if the STDIN constant is defined - * @static - * @return bool - */ - public static function currentContextIsCommandLine(){ - return php_sapi_name() === "cli"; - } - /** - * Check the presence of mcrypt and option CMDLINE_ACTIVE - * @static - * @return bool - */ - public static function backgroundActionsSupported(){ - return function_exists("mcrypt_create_iv") && ConfService::getCoreConf("CMDLINE_ACTIVE"); - } - - /** - * @var AbstractConfDriver - */ - private static $tmpConfStorageImpl; - /** - * @var AbstractAuthDriver - */ - private static $tmpAuthStorageImpl; - - /** - * @param $confStorage AbstractConfDriver - * @param $authStorage AbstractAuthDriver - */ - public static function setTmpStorageImplementations($confStorage, $authStorage){ - self::$tmpConfStorageImpl = $confStorage; - self::$tmpAuthStorageImpl = $authStorage; - } - - /** - * Get conf driver implementation - * - * @return AbstractConfDriver - */ - public static function getConfStorageImpl(){ - if(isSet(self::$tmpConfStorageImpl)) return self::$tmpConfStorageImpl; - return AJXP_PluginsService::getInstance()->getPluginById("core.conf")->getConfImpl(); - } - - /** - * Get auth driver implementation - * - * @return AbstractAuthDriver - */ - public static function getAuthDriverImpl(){ - if(isSet(self::$tmpAuthStorageImpl)) return self::$tmpAuthStorageImpl; - return AJXP_PluginsService::getInstance()->getPluginById("core.auth")->getAuthImpl(); - } - - public static function switchUserToActiveRepository($loggedUser, $parameterId = -1){ - if(isSet($_SESSION["PENDING_REPOSITORY_ID"]) && isSet($_SESSION["PENDING_FOLDER"])){ - $loggedUser->setArrayPref("history", "last_repository", $_SESSION["PENDING_REPOSITORY_ID"]); - $loggedUser->setPref("pending_folder", $_SESSION["PENDING_FOLDER"]); - $loggedUser->save("user"); - AuthService::updateUser($loggedUser); - unset($_SESSION["PENDING_REPOSITORY_ID"]); - unset($_SESSION["PENDING_FOLDER"]); - } - $currentRepoId = ConfService::getCurrentRepositoryId(); - $lastRepoId = $loggedUser->getArrayPref("history", "last_repository"); - $defaultRepoId = AuthService::getDefaultRootId(); - if($defaultRepoId == -1){ - return false; - }else { - if($lastRepoId !== "" && $lastRepoId!==$currentRepoId && $parameterId == -1 && $loggedUser->canSwitchTo($lastRepoId)){ - ConfService::switchRootDir($lastRepoId); - }else if($parameterId != -1 && $loggedUser->canSwitchTo($parameterId)){ - ConfService::switchRootDir($parameterId); - }else if(!$loggedUser->canSwitchTo($currentRepoId)){ - ConfService::switchRootDir($defaultRepoId); - } - } - return true; - } - - - /** - * See instance method - * @static - * @param $rootDirIndex - * @param bool $temporary - * @return void - */ - public static function switchRootDir($rootDirIndex = -1, $temporary = false){ - self::getInstance()->switchRootDirInst($rootDirIndex, $temporary); - } - /** - * Switch the current repository - * @param $rootDirIndex - * @param bool $temporary - * @return void - */ - public function switchRootDirInst($rootDirIndex=-1, $temporary=false) - { - $currentRepos = $this->getLoadedRepositories(); - if($rootDirIndex == -1){ - if(isSet($_SESSION['REPO_ID']) && array_key_exists($_SESSION['REPO_ID'], $currentRepos)) - { - $this->configs["REPOSITORY"] = $currentRepos[$_SESSION['REPO_ID']]; - } - else - { - $keys = array_keys($currentRepos); - $this->configs["REPOSITORY"] = $currentRepos[$keys[0]]; - $_SESSION['REPO_ID'] = $keys[0]; - } - } - else - { - if($temporary && isSet($_SESSION['REPO_ID'])){ - $crtId = $_SESSION['REPO_ID']; - if($crtId != $rootDirIndex && !isSet($_SESSION['SWITCH_BACK_REPO_ID'])){ - $_SESSION['SWITCH_BACK_REPO_ID'] = $crtId; - //AJXP_Logger::debug("switching to $rootDirIndex, registering $crtId"); - } - }else{ - $crtId = $_SESSION['REPO_ID']; - $_SESSION['PREVIOUS_REPO_ID'] = $crtId; - //AJXP_Logger::debug("switching back to $rootDirIndex"); - } - $this->configs["REPOSITORY"] = $currentRepos[$rootDirIndex]; - $_SESSION['REPO_ID'] = $rootDirIndex; - if(isSet($this->configs["ACCESS_DRIVER"])) unset($this->configs["ACCESS_DRIVER"]); - } - - if(isSet($this->configs["REPOSITORY"]) && $this->configs["REPOSITORY"]->getOption("CHARSET")!=""){ - $_SESSION["AJXP_CHARSET"] = $this->configs["REPOSITORY"]->getOption("CHARSET"); - }else{ - if(isSet($_SESSION["AJXP_CHARSET"])){ - unset($_SESSION["AJXP_CHARSET"]); - } - } - - - if($rootDirIndex!=-1 && AuthService::usersEnabled() && AuthService::getLoggedUser()!=null){ - $loggedUser = AuthService::getLoggedUser(); - $loggedUser->setArrayPref("history", "last_repository", $rootDirIndex); - $loggedUser->save("user"); - } - - } - - /** - * See instance method - * @static - * @param String $scope "user" or "all" - * @return Repository[] - */ - public static function getRepositoriesList($scope = "user"){ - if($scope == "user"){ - return self::getInstance()->getLoadedRepositories(); - }else{ - return self::getInstance()->initRepositoriesListInst("all"); - } - } - - /** - * @return Repository[] - */ - private function getLoadedRepositories(){ - if(isSet($this->configs["REPOSITORIES"])){ - return $this->configs["REPOSITORIES"]; - } - $this->configs["REPOSITORIES"] = $this->initRepositoriesListInst(); - return $this->configs["REPOSITORIES"]; - } - - private function invalidateLoadedRepositories(){ - $this->configs["REPOSITORIES"] = null; - } - - /** - * @static - * @param AbstractAjxpUser $userObject - * @param bool $details - * @param bool $labelOnly - * @param bool $skipShared - * @return Repository[] - */ - public static function getAccessibleRepositories($userObject=null, $details=false, $labelOnly = false, $skipShared = false){ - $result = array(); - $allReps = ConfService::getRepositoriesList("all"); - foreach ($allReps as $repositoryId => $repositoryObject) - { - if(!ConfService::repositoryIsAccessible($repositoryId, $repositoryObject, $userObject, $details, $skipShared)){ - continue; - } - - if($labelOnly){ - $result[$repositoryId] = $repositoryObject->getDisplay(); - }else{ - $result[$repositoryId] = $repositoryObject; - } - - } - return $result; - } - - /** - * @param String $repositoryId - * @param Repository $repositoryObject - * @param AbstractAjxpUser $userObject - * @param bool $details - * @param bool $skipShared - * - * @return bool - */ - public static function repositoryIsAccessible($repositoryId, $repositoryObject, $userObject = null, $details=false, $skipShared=false){ - if($userObject == null) $userObject = AuthService::getLoggedUser(); - if($userObject == null && AuthService::usersEnabled()){ - return false; - } - if(!AuthService::canAssign($repositoryObject, $userObject)) { - return false; - } - if($repositoryObject->isTemplate) { - return false; - } - if($repositoryObject->getAccessType()=="ajxp_conf" && $userObject != null){ - if(AuthService::usersEnabled() && !$userObject->isAdmin()){ - return false; - } - } - if($repositoryObject->getAccessType() == "ajxp_shared" && !AuthService::usersEnabled()){ - return false; - } - if($repositoryObject->getUniqueUser() && (!AuthService::usersEnabled() || $userObject == null || $userObject->getId() == "shared" || $userObject->getId() != $repositoryObject->getUniqueUser() )){ - return false; - } - if( $userObject != null && !($userObject->canRead($repositoryId) || $userObject->canWrite($repositoryId)) && !$details){ - return false; - } - if($userObject == null || $userObject->canRead($repositoryId) || $userObject->canWrite($repositoryId) || $details) { - // Do not display standard repositories even in details mode for "sub"users - if($userObject != null && $userObject->hasParent() && !($userObject->canRead($repositoryId) || $userObject->canWrite($repositoryId) )) { - return false; - } - // Do not display shared repositories otherwise. - if($repositoryObject->hasOwner() && $skipShared){ - return false; - } - if($userObject != null && $repositoryObject->hasOwner() && !$userObject->hasParent()){ - // Display the repositories if allow_crossusers is ok - if(ConfService::getCoreConf("ALLOW_CROSSUSERS_SHARING", "conf") === false - || ConfService::getCoreConf("ALLOW_CROSSUSERS_SHARING", "conf") === 0) { - return false; - } - // But still do not display its own shared repositories! - if($repositoryObject->getOwner() == $userObject->getId()) { - return false; - } - } - if($repositoryObject->hasOwner() && $userObject != null && $details && !($userObject->canRead($repositoryId) || $userObject->canWrite($repositoryId) ) ){ - return false; - } - } - return true; - } - - /** - * Return the full list of repositories, as id => objects - * @return array - */ - public function getRepositoriesListInst() - { - return $this->getLoadedRepositories(); - } - - /** - * See instance method - * @static - * @return string - */ - public static function getCurrentRepositoryId(){ - return self::getInstance()->getCurrentRepositoryIdInst(); - } - /** - * Get the current repository ID; - * @return string - */ - public function getCurrentRepositoryIdInst() - { - $currentRepos = $this->getLoadedRepositories(); - if(isSet($_SESSION['REPO_ID']) && isSet($currentRepos[$_SESSION['REPO_ID']])){ - return $_SESSION['REPO_ID']; - } - return array_shift(array_keys($currentRepos)); - } - /** - * Get the current repo label - * @static - * @return string - */ - public static function getCurrentRootDirDisplay(){ - return self::getInstance()->getCurrentRootDirDisplayInst(); - } - /** - * @return string - */ - public function getCurrentRootDirDisplayInst() - { - $currentRepos = $this->getLoadedRepositories(); - if(isSet($currentRepos[$_SESSION['REPO_ID']])){ - $repo = $currentRepos[$_SESSION['REPO_ID']]; - return $repo->getDisplay(); - } - return ""; - } - - /** - * @param $scope String "user", "all" - * @return array - */ - protected function initRepositoriesListInst($scope = "user") - { - // APPEND CONF FILE REPOSITORIES - - $objList = array(); - foreach($this->configs["DEFAULT_REPOSITORIES"] as $index=>$repository) - { - $repo = self::createRepositoryFromArray($index, $repository); - $repo->setWriteable(false); - $objList[$repo->getId()] = $repo; - } - // LOAD FROM DRIVER - $confDriver = self::getConfStorageImpl(); - $drvList = $confDriver->listRepositories($scope == "user" ? AuthService::getLoggedUser() : null); - if(is_array($drvList)){ - foreach ($drvList as $repoId=>$repoObject){ - $driver = AJXP_PluginsService::getInstance()->getPluginByTypeName("access", $repoObject->getAccessType()); - if(!is_object($driver) || !$driver->isEnabled()){ - unset($drvList[$repoId]); - }else{ - $repoObject->setId($repoId); - $drvList[$repoId] = $repoObject; - } - } - $objList = array_merge($objList, $drvList); - } - return $objList; - } - /** - * See instance method - * @static - * @param bool $register - * @return array - */ - public static function detectRepositoryStreams($register = false){ - return self::getInstance()->detectRepositoryStreamsInst($register); - } - /** - * Call the detectStreamWrapper method - * @param bool $register - * @return array - */ - public function detectRepositoryStreamsInst($register = false){ - $streams = array(); - $currentRepos = $this->getLoadedRepositories(); - foreach ($currentRepos as $repository) { - $repository->detectStreamWrapper($register, $streams); - } - return $streams; - } - - /** - * Create a repository object from a config options array - * - * @param integer $index - * @param Array $repository - * @return Repository - */ - public static function createRepositoryFromArray($index, $repository){ - return self::getInstance()->createRepositoryFromArrayInst($index, $repository); - } - /** - * See static method - * @param string $index - * @param array $repository - * @return Repository - */ - public function createRepositoryFromArrayInst($index, $repository){ - $repo = new Repository($index, $repository["DISPLAY"], $repository["DRIVER"]); - if(isSet($repository["DISPLAY_ID"])){ - $repo->setDisplayStringId($repository["DISPLAY_ID"]); - } - if(isSet($repository["DESCRIPTION_ID"])){ - $repo->setDescription($repository["DESCRIPTION_ID"]); - } - if(isSet($repository["AJXP_SLUG"])){ - $repo->setSlug($repository["AJXP_SLUG"]); - } - if(isSet($repository["IS_TEMPLATE"]) && $repository["IS_TEMPLATE"]){ - $repo->isTemplate = true; - $repo->uuid = $index; - } - if(array_key_exists("DRIVER_OPTIONS", $repository) && is_array($repository["DRIVER_OPTIONS"])){ - foreach ($repository["DRIVER_OPTIONS"] as $oName=>$oValue){ - $repo->addOption($oName, $oValue); - } - } - // BACKWARD COMPATIBILITY! - if(array_key_exists("PATH", $repository)){ - $repo->addOption("PATH", $repository["PATH"]); - $repo->addOption("CREATE", $repository["CREATE"]); - $repo->addOption("RECYCLE_BIN", $repository["RECYCLE_BIN"]); - } - return $repo; - } - - /** - * Add dynamically created repository - * - * @param Repository $oRepository - * @return void|-1 if error - */ - public static function addRepository($oRepository){ - return self::getInstance()->addRepositoryInst($oRepository); - } - /** - * @param $oRepository - * @return void|-1 on error - */ - public function addRepositoryInst($oRepository){ - $confStorage = self::getConfStorageImpl(); - $res = $confStorage->saveRepository($oRepository); - if($res == -1){ - return $res; - } - AJXP_Logger::logAction("Create Repository", array("repo_name"=>$oRepository->getDisplay())); - $this->invalidateLoadedRepositories(); - } - - public static function findRepositoryByIdOrAlias($idOrAlias){ - $repository = ConfService::getRepositoryById($idOrAlias); - if($repository != null ) return $repository; - $repository = ConfService::getRepositoryByAlias($idOrAlias); - if($repository != null) return $repository; - return null; - } - - /** - * Retrieve a repository object - * - * @param String $repoId - * @return Repository - */ - public static function getRepositoryById($repoId){ - return self::getInstance()->getRepositoryByIdInst($repoId); - } - /** - * See static method - * @param $repoId - * @return Repository|null - */ - public function getRepositoryByIdInst($repoId){ - $currentRepos = $this->getLoadedRepositories(); - if(isSet($currentRepos[$repoId])){ - return $currentRepos[$repoId]; - } - return $this->getConfStorageImpl()->getRepositoryById($repoId); - } - - /** - * Retrieve a repository object by its slug - * - * @param String $repoAlias - * @return Repository - */ - public static function getRepositoryByAlias($repoAlias){ - $repo = self::getConfStorageImpl()->getRepositoryByAlias($repoAlias); - if($repo !== null) return $repo; - // check default repositories - return self::getInstance()->getRepositoryByAliasInstDefaults($repoAlias); - } - /** - * See static method - * @param $repoAlias - * @return Repository|null - */ - public function getRepositoryByAliasInstDefaults($repoAlias){ - $conf = $this->configs["DEFAULT_REPOSITORIES"]; - foreach($conf as $repoId => $repoDef){ - if($repoDef["AJXP_SLUG"] == $repoAlias){ - return $this->getRepositoryByIdInst($repoId); - } - } - return null; - } - - - /** - * Replace a repository by an update one. - * - * @param String $oldId - * @param Repository $oRepositoryObject - * @return mixed - */ - public static function replaceRepository($oldId, $oRepositoryObject){ - return self::getInstance()->replaceRepositoryInst($oldId, $oRepositoryObject); - } - /** - * See static method - * @param $oldId - * @param $oRepositoryObject - * @return void - */ - public function replaceRepositoryInst($oldId, $oRepositoryObject){ - $confStorage = self::getConfStorageImpl(); - $res = $confStorage->saveRepository($oRepositoryObject, true); - if($res == -1){ - return $res; - } - AJXP_Logger::logAction("Edit Repository", array("repo_name"=>$oRepositoryObject->getDisplay())); - $this->invalidateLoadedRepositories(); - } - /** - * Set a temp repository id but not in the session - * @static - * @param $repositoryObject - * @return void - */ - public static function tmpReplaceRepository($repositoryObject){ - $inst = self::getInstance(); - if(isSet($inst->configs["REPOSITORIES"][$repositoryObject->getUniqueId()])){ - $inst->configs["REPOSITORIES"][$repositoryObject->getUniqueId()] = $repositoryObject; - } - } - /** - * Remove a repository using the conf driver implementation - * @static - * @param $repoId - * @return void - */ - public static function deleteRepository($repoId){ - return self::getInstance()->deleteRepositoryInst($repoId); - } - /** - * See static method - * @param $repoId - * @return void - */ - public function deleteRepositoryInst($repoId){ - $confStorage = self::getConfStorageImpl(); - $res = $confStorage->deleteRepository($repoId); - if($res == -1){ - return $res; - } - AJXP_Logger::logAction("Delete Repository", array("repo_id"=>$repoId)); - $this->invalidateLoadedRepositories(); - } - - /** - * Check if the gzopen function exists - * @static - * @return bool - */ - public static function zipEnabled() - { - if(ConfService::getCoreConf("DISABLE_ZIP_BROWSING") === true) return false; - return (function_exists("gzopen")?true:false); - } - /** - * Get the list of all "conf" messages - * @static - * @param bool $forceRefresh Refresh the list - * @return - */ - public static function getMessagesConf($forceRefresh = false){ - return self::getInstance()->getMessagesInstConf($forceRefresh); - } - /** - * See static method - * @param bool $forceRefresh - * @return - */ - public function getMessagesInstConf($forceRefresh = false) - { - // make sure they are loaded - $mess = $this->getMessagesInst($forceRefresh); - return $this->configs["CONF_MESSAGES"]; - } - - /** - * Get all i18n message - * @static - * @param bool $forceRefresh - * @return - */ - public static function getMessages($forceRefresh = false){ - return self::getInstance()->getMessagesInst($forceRefresh); - } - /** - * Get i18n messages - * @param bool $forceRefresh - * @return - */ - public function getMessagesInst($forceRefresh = false) - { - $crtLang = self::getLanguage(); - $messageCacheDir = dirname(AJXP_PLUGINS_MESSAGES_FILE)."/i18n"; - $messageFile = $messageCacheDir."/".$crtLang."_".basename(AJXP_PLUGINS_MESSAGES_FILE); - if(isSet($this->configs["MESSAGES"]) && !$forceRefresh){ - return $this->configs["MESSAGES"]; - } - if(!isset($this->configs["MESSAGES"]) && is_file($messageFile)){ - include($messageFile); - if(isSet($MESSAGES)){ - $this->configs["MESSAGES"] = $MESSAGES; - } - if(isSet($CONF_MESSAGES)){ - $this->configs["CONF_MESSAGES"] = $CONF_MESSAGES; - } - }else { - $this->configs["MESSAGES"] = array(); - $this->configs["CONF_MESSAGES"] = array(); - $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//i18n", "nodes"); - foreach ($nodes as $node){ - $nameSpace = $node->getAttribute("namespace"); - $path = $node->getAttribute("path"); - $lang = $crtLang; - if(!is_file($path."/".$crtLang.".php")){ - $lang = "en"; // Default language, minimum required. - } - if(is_file($path."/".$lang.".php")){ - require($path."/".$lang.".php"); - if(isSet($mess)){ - foreach ($mess as $key => $message){ - $this->configs["MESSAGES"][(empty($nameSpace)?"":$nameSpace.".").$key] = $message; - } - } - } - $lang = $crtLang; - if(!is_file($path."/conf/".$crtLang.".php")){ - $lang = "en"; - } - if(is_file($path."/conf/".$lang.".php")){ - require($path."/conf/".$lang.".php"); - $this->configs["CONF_MESSAGES"] = array_merge($this->configs["CONF_MESSAGES"], $mess); - } - } - if(!is_dir($messageCacheDir)) mkdir($messageCacheDir); - @file_put_contents($messageFile, "configs["MESSAGES"], true) ." ; \$CONF_MESSAGES = ".var_export($this->configs["CONF_MESSAGES"], true) ." ; "); - } - - return $this->configs["MESSAGES"]; - } - - /** - * Get all registered extensions, from both the conf/extensions.conf.php and from the plugins - * @static - * @return - */ - public static function getRegisteredExtensions(){ - return self::getInstance()->getRegisteredExtensionsInst(); - } - /** - * See static method - * @return - */ - public function getRegisteredExtensionsInst(){ - if(!isSet($this->configs["EXTENSIONS"])){ - $EXTENSIONS = array(); - $RESERVED_EXTENSIONS = array(); - include_once(AJXP_CONF_PATH."/extensions.conf.php"); - $EXTENSIONS = array_merge($RESERVED_EXTENSIONS, $EXTENSIONS); - foreach($EXTENSIONS as $key => $value){ - unset($EXTENSIONS[$key]); - $EXTENSIONS[$value[0]] = $value; - } - $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//extensions/extension", "nodes", true); - $res = array(); - foreach($nodes as $node){ - $res[$node->getAttribute("mime")] = array($node->getAttribute("mime"), $node->getAttribute("icon"), $node->getAttribute("messageId")); - } - if(count($res)){ - $EXTENSIONS = array_merge($EXTENSIONS, $res); - } - $this->configs["EXTENSIONS"] = $EXTENSIONS; - } - return $this->configs["EXTENSIONS"]; - } - /** - * Get the actions that declare to skip the secure token in the plugins - * @static - * @return array - */ - public static function getDeclaredUnsecureActions(){ - $test = AJXP_PluginsService::getInstance()->loadFromPluginQueriesCache("//action[@skipSecureToken]"); - if(!empty($test) && is_array($test)) { - return $test; - }else{ - $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//action[@skipSecureToken]", "nodes"); - $res = array(); - foreach($nodes as $node){ - $res[] = $node->getAttribute("name"); - } - AJXP_PluginsService::getInstance()->storeToPluginQueriesCache("//action[@skipSecureToken]", $res); - return $res; - } - - } - /** - * Detect available languages from the core i18n library - * @static - * @return array - */ - public static function listAvailableLanguages(){ - // Cache in session! - if(isSet($_SESSION["AJXP_LANGUAGES"]) && !isSet($_GET["refresh_langs"])){ - return $_SESSION["AJXP_LANGUAGES"]; - } - $langDir = AJXP_COREI18N_FOLDER; - $languages = array(); - if(($dh = opendir($langDir))!==FALSE){ - while (($file = readdir($dh)) !== false) { - $matches = array(); - if(preg_match("/(.*)\.php/", $file, $matches) == 1){ - $fRadical = $matches[1]; - include($langDir."/".$fRadical.".php"); - $langName = isSet($mess["languageLabel"])?$mess["languageLabel"]:"Not Found"; - $languages[$fRadical] = $langName; - } - } - closedir($dh); - } - if(count($languages)){ - $_SESSION["AJXP_LANGUAGES"] = $languages; - } - return $languages; - } - - /** - * Get a config by its name - * @static - * @param string $varName - * @return mixed - */ - public static function getConf($varName){ - return self::getInstance()->getConfInst($varName); - } - /** - * Set a config by its name - * @static - * @param string $varName - * @param mixed $varValue - * @return void - */ - public static function setConf($varName, $varValue){ - return self::getInstance()->setConfInst($varName, $varValue); - } - /** - * See static method - * @param $varName - * @return mixed - */ - public function getConfInst($varName) - { - if(isSet($this->configs[$varName])){ - return $this->configs[$varName]; - } - if(defined("AJXP_".$varName)){ - return eval("return AJXP_".$varName.";"); - } - return null; - } - /** - * See static method - * @param $varName - * @param $varValue - * @return void - */ - public function setConfInst($varName, $varValue) - { - $this->configs[$varName] = $varValue; - } - /** - * Get config from the core.$coreType plugin - * @static - * @param string $varName - * @param string $coreType - * @return mixed|null|string - */ - public static function getCoreConf($varName, $coreType = "ajaxplorer"){ - $coreP = AJXP_PluginsService::getInstance()->findPlugin("core", $coreType); - if($coreP === false) return null; - $confs = $coreP->getConfigs(); - $confs = AuthService::filterPluginParameters("core.".$coreType, $confs); - return (isSet($confs[$varName]) ? AJXP_VarsFilter::filter($confs[$varName]) : null); - } - - /** - * Set the language in the session - * @static - * @param string $lang - * @return void - */ - public static function setLanguage($lang){ - return self::getInstance()->setLanguageInst($lang); - } - /** - * See static method - * @param string $lang - * @return void - */ - public function setLanguageInst($lang) - { - if(array_key_exists($lang, $this->configs["AVAILABLE_LANG"])) - { - $this->configs["LANGUE"] = $lang; - } - } - /** - * Get the language from the session - * @static - * @return string - */ - public static function getLanguage() - { - $lang = self::getInstance()->getConfInst("LANGUE"); - if($lang == null){ - $lang = self::getInstance()->getCoreConf("DEFAULT_LANGUAGE"); - } - if(empty($lang)) return "en"; - return $lang; - } - - /** - * The current repository - * @return Repository - */ - public static function getRepository(){ - return self::getInstance()->getRepositoryInst(); - } - /** - * See static method - * @return Repository - */ - public function getRepositoryInst() - { - if(isSet($_SESSION['REPO_ID']) && isSet($this->configs["REPOSITORIES"]) && isSet($this->configs["REPOSITORIES"][$_SESSION['REPO_ID']])){ - return $this->configs["REPOSITORIES"][$_SESSION['REPO_ID']]; - } - return $this->configs["REPOSITORY"]; - } - - /** - * Returns the repository access driver - * @return AJXP_Plugin - */ - public static function loadRepositoryDriver(){ - return self::getInstance()->loadRepositoryDriverInst(); - } - /** - * See static method - * @throws Exception - * @return AJXP_Plugin - */ - public function loadRepositoryDriverInst() - { - if(isSet($this->configs["ACCESS_DRIVER"]) && is_a($this->configs["ACCESS_DRIVER"], "AbstractAccessDriver")){ - return $this->configs["ACCESS_DRIVER"]; - } - $this->switchRootDirInst(); - $crtRepository = $this->getRepositoryInst(); - $accessType = $crtRepository->getAccessType(); - $pServ = AJXP_PluginsService::getInstance(); - $plugInstance = $pServ->getPluginByTypeName("access", $accessType); - - // TRIGGER BEFORE INIT META - $metaSources = $crtRepository->getOption("META_SOURCES"); - if(isSet($metaSources) && is_array($metaSources) && count($metaSources)){ - $keys = array_keys($metaSources); - foreach ($keys as $plugId){ - if($plugId == "") continue; - $split = explode(".", $plugId); - $instance = $pServ->getPluginById($plugId); - if(!is_object($instance)) { - continue; - } - if(!method_exists($instance, "beforeInitMeta")){ - continue; - } - try{ - $instance->init(AuthService::filterPluginParameters($plugId, $metaSources[$plugId], $crtRepository->getId())); - $instance->beforeInitMeta($plugInstance); - }catch(Exception $e){ - AJXP_Logger::logAction('ERROR : Cannot instanciate Meta plugin, reason : '.$e->getMessage()); - $this->errors[] = $e->getMessage(); - } - } - } - - // INIT MAIN DRIVER - $plugInstance->init($crtRepository); - try{ - $plugInstance->initRepository(); - $crtRepository->driverInstance = $plugInstance; - }catch (Exception $e){ - // Remove repositories from the lists - unset($this->configs["REPOSITORIES"][$crtRepository->getId()]); - if(isSet($_SESSION["PREVIOUS_REPO_ID"]) && $_SESSION["PREVIOUS_REPO_ID"] !=$crtRepository->getId()){ - $this->switchRootDir($_SESSION["PREVIOUS_REPO_ID"]); - }else{ - $this->switchRootDir(); - } - throw $e; - } - $pServ->setPluginUniqueActiveForType("access", $accessType); - - // TRIGGER INIT META - $metaSources = $crtRepository->getOption("META_SOURCES"); - if(isSet($metaSources) && is_array($metaSources) && count($metaSources)){ - $keys = array_keys($metaSources); - foreach ($keys as $plugId){ - if($plugId == "") continue; - $split = explode(".", $plugId); - $instance = $pServ->getPluginById($plugId); - if(!is_object($instance)) { - continue; - } - try{ - $instance->init(AuthService::filterPluginParameters($plugId, $metaSources[$plugId], $crtRepository->getId())); - $instance->initMeta($plugInstance); - }catch(Exception $e){ - AJXP_Logger::logAction('ERROR : Cannot instanciate Meta plugin, reason : '.$e->getMessage()); - $this->errors[] = $e->getMessage(); - } - $pServ->setPluginActive($split[0], $split[1]); - } - } - if(count($this->errors)>0){ - $e = new AJXP_Exception("Error while loading repository feature : ".implode(",",$this->errors)); - // Remove repositories from the lists - unset($this->configs["REPOSITORIES"][$crtRepository->getId()]); - if(isSet($_SESSION["PREVIOUS_REPO_ID"]) && $_SESSION["PREVIOUS_REPO_ID"] !=$crtRepository->getId()){ - $this->switchRootDir($_SESSION["PREVIOUS_REPO_ID"]); - }else{ - $this->switchRootDir(); - } - throw $e; - } - - $this->configs["ACCESS_DRIVER"] = $plugInstance; - return $this->configs["ACCESS_DRIVER"]; - } - - /** - * @static - * @param Repository $repository - * @return AbstractAccessDriver - */ - public static function loadDriverForRepository(&$repository){ - return self::getInstance()->loadRepositoryDriverREST($repository); - } - - /** - * See static method - * @param Repository $repository - * @throws AJXP_Exception|Exception - * @return AbstractAccessDriver - */ - public function loadRepositoryDriverREST(&$repository) - { - if(isset($repository->driverInstance)) { - return $repository->driverInstance; - } - $accessType = $repository->getAccessType(); - $pServ = AJXP_PluginsService::getInstance(); - $plugInstance = $pServ->getPluginByTypeName("access", $accessType); - - // TRIGGER BEFORE INIT META - $metaSources = $repository->getOption("META_SOURCES"); - if(isSet($metaSources) && is_array($metaSources) && count($metaSources)){ - $keys = array_keys($metaSources); - foreach ($keys as $plugId){ - if($plugId == "") continue; - $instance = $pServ->getPluginById($plugId); - if(!is_object($instance)) { - continue; - } - if(!method_exists($instance, "beforeInitMeta")){ - continue; - } - try{ - $instance->init(AuthService::filterPluginParameters($plugId, $metaSources[$plugId], $repository->getId())); - $instance->beforeInitMeta($plugInstance); - }catch(Exception $e){ - AJXP_Logger::logAction('ERROR : Cannot instanciate Meta plugin, reason : '.$e->getMessage()); - $this->errors[] = $e->getMessage(); - } - } - } - - // INIT MAIN DRIVER - $plugInstance->init($repository); - try{ - $plugInstance->initRepository(); - }catch (Exception $e){ - throw $e; - } - $pServ->setPluginUniqueActiveForType("access", $accessType); - - // TRIGGER INIT META - $metaSources = $repository->getOption("META_SOURCES"); - if(isSet($metaSources) && is_array($metaSources) && count($metaSources)){ - $keys = array_keys($metaSources); - foreach ($keys as $plugId){ - if($plugId == "") continue; - $split = explode(".", $plugId); - $instance = $pServ->getPluginById($plugId); - if(!is_object($instance)) { - continue; - } - try{ - $instance->init(AuthService::filterPluginParameters($plugId, $metaSources[$plugId], $repository->getId())); - $instance->initMeta($plugInstance); - }catch(Exception $e){ - AJXP_Logger::logAction('ERROR : Cannot instanciate Meta plugin, reason : '.$e->getMessage()); - $this->errors[] = $e->getMessage(); - } - $pServ->setPluginActive($split[0], $split[1]); - } - } - if(count($this->errors)>0){ - $e = new AJXP_Exception("Error while loading repository feature : ".implode(",",$this->errors)); - throw $e; - } - - $repository->driverInstance = $plugInstance; - if(isSet($_SESSION["REPO_ID"]) && $_SESSION["REPO_ID"] == $repository->getId()){ - $this->configs["REPOSITORY"] = $repository; - $this->configs["REPOSITORIES"][$_SESSION['REPO_ID']] = $repository; - } - return $plugInstance; - } - - /** - * Search the manifests declaring ajxpdriver as their root node. Remove ajxp_conf & ajxp_shared - * @static - * @param string $filterByTagName - * @param string $filterByDriverName - * @param bool $limitToEnabledPlugins - * @return string - */ - public static function availableDriversToXML($filterByTagName = "", $filterByDriverName="", $limitToEnabledPlugins = false){ - $nodeList = AJXP_PluginsService::searchAllManifests("//ajxpdriver", "node", false, $limitToEnabledPlugins); - $xmlBuffer = ""; - foreach($nodeList as $node){ - $dName = $node->getAttribute("name"); - if($filterByDriverName != "" && $dName != $filterByDriverName) continue; - if($dName == "ajxp_conf" || $dName == "ajxp_shared") continue; - if($filterByTagName == ""){ - $xmlBuffer .= $node->ownerDocument->saveXML($node); - continue; - } - $q = new DOMXPath($node->ownerDocument); - $cNodes = $q->query("//".$filterByTagName, $node); - $nodeAttr = $node->attributes; - $xmlBuffer .= "attributes as $attr) $xmlBuffer.= " $attr->name=\"$attr->value\" "; - $xmlBuffer .=">"; - foreach($cNodes as $child){ - $xmlBuffer .= $child->ownerDocument->saveXML($child); - } - $xmlBuffer .= ""; - } - return $xmlBuffer; - } - - /** - * Singleton method - * - * @return ConfService the service instance - */ - public static function getInstance() - { - if(!isSet(self::$instance)){ - $c = __CLASS__; - self::$instance = new $c; - } - return self::$instance; - } - private function __construct(){} - public function __clone(){ - trigger_error("Cannot clone me, i'm a singleton!", E_USER_ERROR); - } - -} \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * Configuration holder. Singleton class accessed statically, encapsulates the confDriver implementation. + * @package AjaXplorer + * @subpackage Core + */ +class ConfService +{ + private static $instance; + private $errors = array(); + private $configs = array(); + + /** + * @param AJXP_PluginsService $ajxpPluginService + * @return AbstractConfDriver + */ + public function confPluginSoftLoad($ajxpPluginService) + { + $booter = $ajxpPluginService->softLoad("boot.conf", array()); + $coreConfigs = $booter->loadPluginConfig("core", "conf"); + $corePlug = $ajxpPluginService->softLoad("core.conf", array()); + $corePlug->loadConfigs($coreConfigs); + return $corePlug->getConfImpl(); + + } + + /** + * @return AbstractConfDriver + */ + public static function getBootConfStorageImpl() + { + $inst = AJXP_PluginsService::getInstance()->findPluginById("boot.conf"); + if (empty($inst)) { + $inst = AJXP_PluginsService::getInstance()->softLoad("boot.conf", array()); + } + return $inst; + } + + /** + * Initialize singleton + * @static + * @return void + */ + public static function init() + { + $inst = self::getInstance(); + $inst->initInst(); + } + /** + * Load the boostrap_* files and their configs + * @return void + */ + public function initInst() + { + // INIT AS GLOBAL + $this->configs["AVAILABLE_LANG"] = self::listAvailableLanguages(); + if (isSet($_SERVER["HTTPS"]) && strtolower($_SERVER["HTTPS"]) == "on") { + $this->configs["USE_HTTPS"] = true; + } + if (isSet($this->configs["USE_HTTPS"])) { + AJXP_Utils::safeIniSet("session.cookie_secure", true); + } + $this->configs["JS_DEBUG"] = AJXP_CLIENT_DEBUG; + $this->configs["SERVER_DEBUG"] = AJXP_SERVER_DEBUG; + + + if (is_file(AJXP_CONF_PATH."/bootstrap_repositories.php")) { + include(AJXP_CONF_PATH."/bootstrap_repositories.php"); + $this->configs["DEFAULT_REPOSITORIES"] = $REPOSITORIES; + } else { + $this->configs["DEFAULT_REPOSITORIES"] = array(); + } + } + /** + * Start the singleton + * @static + * @return void + */ + public static function start() + { + $inst = self::getInstance(); + $inst->startInst(); + } + /** + * Init CONF, AUTH drivers + * Init Repositories + * @return void + */ + public function startInst() + { + AJXP_PluginsService::getInstance()->setPluginUniqueActiveForType("conf", self::getConfStorageImpl()->getName()); + } + /** + * Get errors generated by the boot sequence (init/start) + * @static + * @return array + */ + public static function getErrors() + { + return self::getInstance()->errors; + } + + /** + * @static + * @param $globalsArray + * @param string $interfaceCheck + * @internal param string $bootstrapConfigKey + * @internal param string $bootstrapConfigType + * @return AJXP_Plugin|null + */ + public static function instanciatePluginFromGlobalParams($globalsArray, $interfaceCheck = "") + { + $plugin = false; + + if (is_string($globalsArray)) { + $globalsArray = array("instance_name" => $globalsArray); + } + + if (isSet($globalsArray["instance_name"])) { + $pName = $globalsArray["instance_name"]; + unset($globalsArray["instance_name"]); + $plugin = AJXP_PluginsService::getInstance()->softLoad($pName, $globalsArray); + $plugin->performChecks(); + } + + if ($plugin != false && !empty($interfaceCheck)) { + if (!is_a($plugin, $interfaceCheck)) { + $plugin = false; + } + } + if ($plugin !== false) { + AJXP_PluginsService::getInstance()->setPluginActive($plugin->getType(), $plugin->getName(), true, $plugin); + } + return $plugin; + + } + /** + * Check if the STDIN constant is defined + * @static + * @return bool + */ + public static function currentContextIsCommandLine() + { + return php_sapi_name() === "cli"; + } + /** + * Check the presence of mcrypt and option CMDLINE_ACTIVE + * @static + * @return bool + */ + public static function backgroundActionsSupported() + { + return function_exists("mcrypt_create_iv") && ConfService::getCoreConf("CMDLINE_ACTIVE"); + } + + /** + * @var AbstractConfDriver + */ + private static $tmpConfStorageImpl; + /** + * @var AbstractAuthDriver + */ + private static $tmpAuthStorageImpl; + + /** + * @param $confStorage AbstractConfDriver + * @param $authStorage AbstractAuthDriver + */ + public static function setTmpStorageImplementations($confStorage, $authStorage) + { + self::$tmpConfStorageImpl = $confStorage; + self::$tmpAuthStorageImpl = $authStorage; + } + + /** + * Get conf driver implementation + * + * @return AbstractConfDriver + */ + public static function getConfStorageImpl() + { + if(isSet(self::$tmpConfStorageImpl)) return self::$tmpConfStorageImpl; + return AJXP_PluginsService::getInstance()->getPluginById("core.conf")->getConfImpl(); + } + + /** + * Get auth driver implementation + * + * @return AbstractAuthDriver + */ + public static function getAuthDriverImpl() + { + if(isSet(self::$tmpAuthStorageImpl)) return self::$tmpAuthStorageImpl; + return AJXP_PluginsService::getInstance()->getPluginById("core.auth")->getAuthImpl(); + } + + public static function switchUserToActiveRepository($loggedUser, $parameterId = -1) + { + if (isSet($_SESSION["PENDING_REPOSITORY_ID"]) && isSet($_SESSION["PENDING_FOLDER"])) { + $loggedUser->setArrayPref("history", "last_repository", $_SESSION["PENDING_REPOSITORY_ID"]); + $loggedUser->setPref("pending_folder", $_SESSION["PENDING_FOLDER"]); + $loggedUser->save("user"); + AuthService::updateUser($loggedUser); + unset($_SESSION["PENDING_REPOSITORY_ID"]); + unset($_SESSION["PENDING_FOLDER"]); + } + $currentRepoId = ConfService::getCurrentRepositoryId(); + $lastRepoId = $loggedUser->getArrayPref("history", "last_repository"); + $defaultRepoId = AuthService::getDefaultRootId(); + if ($defaultRepoId == -1) { + return false; + } else { + if ($lastRepoId !== "" && $lastRepoId!==$currentRepoId && $parameterId == -1 && $loggedUser->canSwitchTo($lastRepoId)) { + ConfService::switchRootDir($lastRepoId); + } else if ($parameterId != -1 && $loggedUser->canSwitchTo($parameterId)) { + ConfService::switchRootDir($parameterId); + } else if (!$loggedUser->canSwitchTo($currentRepoId)) { + ConfService::switchRootDir($defaultRepoId); + } + } + return true; + } + + + /** + * See instance method + * @static + * @param $rootDirIndex + * @param bool $temporary + * @return void + */ + public static function switchRootDir($rootDirIndex = -1, $temporary = false) + { + self::getInstance()->switchRootDirInst($rootDirIndex, $temporary); + } + /** + * Switch the current repository + * @param $rootDirIndex + * @param bool $temporary + * @return void + */ + public function switchRootDirInst($rootDirIndex=-1, $temporary=false) + { + $currentRepos = $this->getLoadedRepositories(); + if ($rootDirIndex == -1) { + if (isSet($_SESSION['REPO_ID']) && array_key_exists($_SESSION['REPO_ID'], $currentRepos)) { + $this->configs["REPOSITORY"] = $currentRepos[$_SESSION['REPO_ID']]; + } else { + $keys = array_keys($currentRepos); + $this->configs["REPOSITORY"] = $currentRepos[$keys[0]]; + $_SESSION['REPO_ID'] = $keys[0]; + } + } else { + if ($temporary && isSet($_SESSION['REPO_ID'])) { + $crtId = $_SESSION['REPO_ID']; + if ($crtId != $rootDirIndex && !isSet($_SESSION['SWITCH_BACK_REPO_ID'])) { + $_SESSION['SWITCH_BACK_REPO_ID'] = $crtId; + //AJXP_Logger::debug("switching to $rootDirIndex, registering $crtId"); + } + } else { + $crtId = $_SESSION['REPO_ID']; + $_SESSION['PREVIOUS_REPO_ID'] = $crtId; + //AJXP_Logger::debug("switching back to $rootDirIndex"); + } + $this->configs["REPOSITORY"] = $currentRepos[$rootDirIndex]; + $_SESSION['REPO_ID'] = $rootDirIndex; + if(isSet($this->configs["ACCESS_DRIVER"])) unset($this->configs["ACCESS_DRIVER"]); + } + + if (isSet($this->configs["REPOSITORY"]) && $this->configs["REPOSITORY"]->getOption("CHARSET")!="") { + $_SESSION["AJXP_CHARSET"] = $this->configs["REPOSITORY"]->getOption("CHARSET"); + } else { + if (isSet($_SESSION["AJXP_CHARSET"])) { + unset($_SESSION["AJXP_CHARSET"]); + } + } + + + if ($rootDirIndex!=-1 && AuthService::usersEnabled() && AuthService::getLoggedUser()!=null) { + $loggedUser = AuthService::getLoggedUser(); + $loggedUser->setArrayPref("history", "last_repository", $rootDirIndex); + $loggedUser->save("user"); + } + + } + + /** + * See instance method + * @static + * @param String $scope "user" or "all" + * @return Repository[] + */ + public static function getRepositoriesList($scope = "user") + { + if ($scope == "user") { + return self::getInstance()->getLoadedRepositories(); + } else { + return self::getInstance()->initRepositoriesListInst("all"); + } + } + + /** + * @return Repository[] + */ + private function getLoadedRepositories() + { + if (isSet($this->configs["REPOSITORIES"])) { + return $this->configs["REPOSITORIES"]; + } + $this->configs["REPOSITORIES"] = $this->initRepositoriesListInst(); + return $this->configs["REPOSITORIES"]; + } + + private function invalidateLoadedRepositories() + { + $this->configs["REPOSITORIES"] = null; + } + + /** + * @static + * @param AbstractAjxpUser $userObject + * @param bool $details + * @param bool $labelOnly + * @param bool $skipShared + * @return Repository[] + */ + public static function getAccessibleRepositories($userObject=null, $details=false, $labelOnly = false, $skipShared = false) + { + $result = array(); + $allReps = ConfService::getRepositoriesList("all"); + foreach ($allReps as $repositoryId => $repositoryObject) { + if (!ConfService::repositoryIsAccessible($repositoryId, $repositoryObject, $userObject, $details, $skipShared)) { + continue; + } + + if ($labelOnly) { + $result[$repositoryId] = $repositoryObject->getDisplay(); + } else { + $result[$repositoryId] = $repositoryObject; + } + + } + return $result; + } + + /** + * @param String $repositoryId + * @param Repository $repositoryObject + * @param AbstractAjxpUser $userObject + * @param bool $details + * @param bool $skipShared + * + * @return bool + */ + public static function repositoryIsAccessible($repositoryId, $repositoryObject, $userObject = null, $details=false, $skipShared=false) + { + if($userObject == null) $userObject = AuthService::getLoggedUser(); + if ($userObject == null && AuthService::usersEnabled()) { + return false; + } + if (!AuthService::canAssign($repositoryObject, $userObject)) { + return false; + } + if ($repositoryObject->isTemplate) { + return false; + } + if ($repositoryObject->getAccessType()=="ajxp_conf" && $userObject != null) { + if (AuthService::usersEnabled() && !$userObject->isAdmin()) { + return false; + } + } + if ($repositoryObject->getAccessType() == "ajxp_shared" && !AuthService::usersEnabled()) { + return false; + } + if ($repositoryObject->getUniqueUser() && (!AuthService::usersEnabled() || $userObject == null || $userObject->getId() == "shared" || $userObject->getId() != $repositoryObject->getUniqueUser() )) { + return false; + } + if ( $userObject != null && !($userObject->canRead($repositoryId) || $userObject->canWrite($repositoryId)) && !$details) { + return false; + } + if ($userObject == null || $userObject->canRead($repositoryId) || $userObject->canWrite($repositoryId) || $details) { + // Do not display standard repositories even in details mode for "sub"users + if ($userObject != null && $userObject->hasParent() && !($userObject->canRead($repositoryId) || $userObject->canWrite($repositoryId) )) { + return false; + } + // Do not display shared repositories otherwise. + if ($repositoryObject->hasOwner() && $skipShared) { + return false; + } + if ($userObject != null && $repositoryObject->hasOwner() && !$userObject->hasParent()) { + // Display the repositories if allow_crossusers is ok + if(ConfService::getCoreConf("ALLOW_CROSSUSERS_SHARING", "conf") === false + || ConfService::getCoreConf("ALLOW_CROSSUSERS_SHARING", "conf") === 0) { + return false; + } + // But still do not display its own shared repositories! + if ($repositoryObject->getOwner() == $userObject->getId()) { + return false; + } + } + if ($repositoryObject->hasOwner() && $userObject != null && $details && !($userObject->canRead($repositoryId) || $userObject->canWrite($repositoryId) ) ) { + return false; + } + } + return true; + } + + /** + * Return the full list of repositories, as id => objects + * @return array + */ + public function getRepositoriesListInst() + { + return $this->getLoadedRepositories(); + } + + /** + * See instance method + * @static + * @return string + */ + public static function getCurrentRepositoryId() + { + return self::getInstance()->getCurrentRepositoryIdInst(); + } + /** + * Get the current repository ID; + * @return string + */ + public function getCurrentRepositoryIdInst() + { + $currentRepos = $this->getLoadedRepositories(); + if (isSet($_SESSION['REPO_ID']) && isSet($currentRepos[$_SESSION['REPO_ID']])) { + return $_SESSION['REPO_ID']; + } + return array_shift(array_keys($currentRepos)); + } + /** + * Get the current repo label + * @static + * @return string + */ + public static function getCurrentRootDirDisplay() + { + return self::getInstance()->getCurrentRootDirDisplayInst(); + } + /** + * @return string + */ + public function getCurrentRootDirDisplayInst() + { + $currentRepos = $this->getLoadedRepositories(); + if (isSet($currentRepos[$_SESSION['REPO_ID']])) { + $repo = $currentRepos[$_SESSION['REPO_ID']]; + return $repo->getDisplay(); + } + return ""; + } + + /** + * @param $scope String "user", "all" + * @return array + */ + protected function initRepositoriesListInst($scope = "user") + { + // APPEND CONF FILE REPOSITORIES + + $objList = array(); + foreach ($this->configs["DEFAULT_REPOSITORIES"] as $index=>$repository) { + $repo = self::createRepositoryFromArray($index, $repository); + $repo->setWriteable(false); + $objList[$repo->getId()] = $repo; + } + // LOAD FROM DRIVER + $confDriver = self::getConfStorageImpl(); + $drvList = $confDriver->listRepositories($scope == "user" ? AuthService::getLoggedUser() : null); + if (is_array($drvList)) { + foreach ($drvList as $repoId=>$repoObject) { + $driver = AJXP_PluginsService::getInstance()->getPluginByTypeName("access", $repoObject->getAccessType()); + if (!is_object($driver) || !$driver->isEnabled()) { + unset($drvList[$repoId]); + } else { + $repoObject->setId($repoId); + $drvList[$repoId] = $repoObject; + } + } + $objList = array_merge($objList, $drvList); + } + return $objList; + } + /** + * See instance method + * @static + * @param bool $register + * @return array + */ + public static function detectRepositoryStreams($register = false) + { + return self::getInstance()->detectRepositoryStreamsInst($register); + } + /** + * Call the detectStreamWrapper method + * @param bool $register + * @return array + */ + public function detectRepositoryStreamsInst($register = false) + { + $streams = array(); + $currentRepos = $this->getLoadedRepositories(); + foreach ($currentRepos as $repository) { + $repository->detectStreamWrapper($register, $streams); + } + return $streams; + } + + /** + * Create a repository object from a config options array + * + * @param integer $index + * @param Array $repository + * @return Repository + */ + public static function createRepositoryFromArray($index, $repository) + { + return self::getInstance()->createRepositoryFromArrayInst($index, $repository); + } + /** + * See static method + * @param string $index + * @param array $repository + * @return Repository + */ + public function createRepositoryFromArrayInst($index, $repository) + { + $repo = new Repository($index, $repository["DISPLAY"], $repository["DRIVER"]); + if (isSet($repository["DISPLAY_ID"])) { + $repo->setDisplayStringId($repository["DISPLAY_ID"]); + } + if (isSet($repository["DESCRIPTION_ID"])) { + $repo->setDescription($repository["DESCRIPTION_ID"]); + } + if (isSet($repository["AJXP_SLUG"])) { + $repo->setSlug($repository["AJXP_SLUG"]); + } + if (isSet($repository["IS_TEMPLATE"]) && $repository["IS_TEMPLATE"]) { + $repo->isTemplate = true; + $repo->uuid = $index; + } + if (array_key_exists("DRIVER_OPTIONS", $repository) && is_array($repository["DRIVER_OPTIONS"])) { + foreach ($repository["DRIVER_OPTIONS"] as $oName=>$oValue) { + $repo->addOption($oName, $oValue); + } + } + // BACKWARD COMPATIBILITY! + if (array_key_exists("PATH", $repository)) { + $repo->addOption("PATH", $repository["PATH"]); + $repo->addOption("CREATE", $repository["CREATE"]); + $repo->addOption("RECYCLE_BIN", $repository["RECYCLE_BIN"]); + } + return $repo; + } + + /** + * Add dynamically created repository + * + * @param Repository $oRepository + * @return void|-1 if error + */ + public static function addRepository($oRepository) + { + return self::getInstance()->addRepositoryInst($oRepository); + } + /** + * @param $oRepository + * @return void|-1 on error + */ + public function addRepositoryInst($oRepository) + { + $confStorage = self::getConfStorageImpl(); + $res = $confStorage->saveRepository($oRepository); + if ($res == -1) { + return $res; + } + AJXP_Logger::logAction("Create Repository", array("repo_name"=>$oRepository->getDisplay())); + $this->invalidateLoadedRepositories(); + } + + public static function findRepositoryByIdOrAlias($idOrAlias) + { + $repository = ConfService::getRepositoryById($idOrAlias); + if($repository != null ) return $repository; + $repository = ConfService::getRepositoryByAlias($idOrAlias); + if($repository != null) return $repository; + return null; + } + + /** + * Retrieve a repository object + * + * @param String $repoId + * @return Repository + */ + public static function getRepositoryById($repoId) + { + return self::getInstance()->getRepositoryByIdInst($repoId); + } + /** + * See static method + * @param $repoId + * @return Repository|null + */ + public function getRepositoryByIdInst($repoId) + { + $currentRepos = $this->getLoadedRepositories(); + if (isSet($currentRepos[$repoId])) { + return $currentRepos[$repoId]; + } + return $this->getConfStorageImpl()->getRepositoryById($repoId); + } + + /** + * Retrieve a repository object by its slug + * + * @param String $repoAlias + * @return Repository + */ + public static function getRepositoryByAlias($repoAlias) + { + $repo = self::getConfStorageImpl()->getRepositoryByAlias($repoAlias); + if($repo !== null) return $repo; + // check default repositories + return self::getInstance()->getRepositoryByAliasInstDefaults($repoAlias); + } + /** + * See static method + * @param $repoAlias + * @return Repository|null + */ + public function getRepositoryByAliasInstDefaults($repoAlias) + { + $conf = $this->configs["DEFAULT_REPOSITORIES"]; + foreach ($conf as $repoId => $repoDef) { + if ($repoDef["AJXP_SLUG"] == $repoAlias) { + return $this->getRepositoryByIdInst($repoId); + } + } + return null; + } + + + /** + * Replace a repository by an update one. + * + * @param String $oldId + * @param Repository $oRepositoryObject + * @return mixed + */ + public static function replaceRepository($oldId, $oRepositoryObject) + { + return self::getInstance()->replaceRepositoryInst($oldId, $oRepositoryObject); + } + /** + * See static method + * @param $oldId + * @param $oRepositoryObject + * @return void + */ + public function replaceRepositoryInst($oldId, $oRepositoryObject) + { + $confStorage = self::getConfStorageImpl(); + $res = $confStorage->saveRepository($oRepositoryObject, true); + if ($res == -1) { + return $res; + } + AJXP_Logger::logAction("Edit Repository", array("repo_name"=>$oRepositoryObject->getDisplay())); + $this->invalidateLoadedRepositories(); + } + /** + * Set a temp repository id but not in the session + * @static + * @param $repositoryObject + * @return void + */ + public static function tmpReplaceRepository($repositoryObject) + { + $inst = self::getInstance(); + if (isSet($inst->configs["REPOSITORIES"][$repositoryObject->getUniqueId()])) { + $inst->configs["REPOSITORIES"][$repositoryObject->getUniqueId()] = $repositoryObject; + } + } + /** + * Remove a repository using the conf driver implementation + * @static + * @param $repoId + * @return void + */ + public static function deleteRepository($repoId) + { + return self::getInstance()->deleteRepositoryInst($repoId); + } + /** + * See static method + * @param $repoId + * @return void + */ + public function deleteRepositoryInst($repoId) + { + $confStorage = self::getConfStorageImpl(); + $res = $confStorage->deleteRepository($repoId); + if ($res == -1) { + return $res; + } + AJXP_Logger::logAction("Delete Repository", array("repo_id"=>$repoId)); + $this->invalidateLoadedRepositories(); + } + + /** + * Check if the gzopen function exists + * @static + * @return bool + */ + public static function zipEnabled() + { + if(ConfService::getCoreConf("DISABLE_ZIP_BROWSING") === true) return false; + return (function_exists("gzopen")?true:false); + } + /** + * Get the list of all "conf" messages + * @static + * @param bool $forceRefresh Refresh the list + * @return + */ + public static function getMessagesConf($forceRefresh = false) + { + return self::getInstance()->getMessagesInstConf($forceRefresh); + } + /** + * See static method + * @param bool $forceRefresh + * @return + */ + public function getMessagesInstConf($forceRefresh = false) + { + // make sure they are loaded + $mess = $this->getMessagesInst($forceRefresh); + return $this->configs["CONF_MESSAGES"]; + } + + /** + * Get all i18n message + * @static + * @param bool $forceRefresh + * @return + */ + public static function getMessages($forceRefresh = false) + { + return self::getInstance()->getMessagesInst($forceRefresh); + } + /** + * Get i18n messages + * @param bool $forceRefresh + * @return + */ + public function getMessagesInst($forceRefresh = false) + { + $crtLang = self::getLanguage(); + $messageCacheDir = dirname(AJXP_PLUGINS_MESSAGES_FILE)."/i18n"; + $messageFile = $messageCacheDir."/".$crtLang."_".basename(AJXP_PLUGINS_MESSAGES_FILE); + if (isSet($this->configs["MESSAGES"]) && !$forceRefresh) { + return $this->configs["MESSAGES"]; + } + if (!isset($this->configs["MESSAGES"]) && is_file($messageFile)) { + include($messageFile); + if (isSet($MESSAGES)) { + $this->configs["MESSAGES"] = $MESSAGES; + } + if (isSet($CONF_MESSAGES)) { + $this->configs["CONF_MESSAGES"] = $CONF_MESSAGES; + } + } else { + $this->configs["MESSAGES"] = array(); + $this->configs["CONF_MESSAGES"] = array(); + $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//i18n", "nodes"); + foreach ($nodes as $node) { + $nameSpace = $node->getAttribute("namespace"); + $path = $node->getAttribute("path"); + $lang = $crtLang; + if (!is_file($path."/".$crtLang.".php")) { + $lang = "en"; // Default language, minimum required. + } + if (is_file($path."/".$lang.".php")) { + require($path."/".$lang.".php"); + if (isSet($mess)) { + foreach ($mess as $key => $message) { + $this->configs["MESSAGES"][(empty($nameSpace)?"":$nameSpace.".").$key] = $message; + } + } + } + $lang = $crtLang; + if (!is_file($path."/conf/".$crtLang.".php")) { + $lang = "en"; + } + if (is_file($path."/conf/".$lang.".php")) { + require($path."/conf/".$lang.".php"); + $this->configs["CONF_MESSAGES"] = array_merge($this->configs["CONF_MESSAGES"], $mess); + } + } + if(!is_dir($messageCacheDir)) mkdir($messageCacheDir); + @file_put_contents($messageFile, "configs["MESSAGES"], true) ." ; \$CONF_MESSAGES = ".var_export($this->configs["CONF_MESSAGES"], true) ." ; "); + } + + return $this->configs["MESSAGES"]; + } + + /** + * Get all registered extensions, from both the conf/extensions.conf.php and from the plugins + * @static + * @return + */ + public static function getRegisteredExtensions() + { + return self::getInstance()->getRegisteredExtensionsInst(); + } + /** + * See static method + * @return + */ + public function getRegisteredExtensionsInst() + { + if (!isSet($this->configs["EXTENSIONS"])) { + $EXTENSIONS = array(); + $RESERVED_EXTENSIONS = array(); + include_once(AJXP_CONF_PATH."/extensions.conf.php"); + $EXTENSIONS = array_merge($RESERVED_EXTENSIONS, $EXTENSIONS); + foreach ($EXTENSIONS as $key => $value) { + unset($EXTENSIONS[$key]); + $EXTENSIONS[$value[0]] = $value; + } + $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//extensions/extension", "nodes", true); + $res = array(); + foreach ($nodes as $node) { + $res[$node->getAttribute("mime")] = array($node->getAttribute("mime"), $node->getAttribute("icon"), $node->getAttribute("messageId")); + } + if (count($res)) { + $EXTENSIONS = array_merge($EXTENSIONS, $res); + } + $this->configs["EXTENSIONS"] = $EXTENSIONS; + } + return $this->configs["EXTENSIONS"]; + } + /** + * Get the actions that declare to skip the secure token in the plugins + * @static + * @return array + */ + public static function getDeclaredUnsecureActions() + { + $test = AJXP_PluginsService::getInstance()->loadFromPluginQueriesCache("//action[@skipSecureToken]"); + if (!empty($test) && is_array($test)) { + return $test; + } else { + $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//action[@skipSecureToken]", "nodes"); + $res = array(); + foreach ($nodes as $node) { + $res[] = $node->getAttribute("name"); + } + AJXP_PluginsService::getInstance()->storeToPluginQueriesCache("//action[@skipSecureToken]", $res); + return $res; + } + + } + /** + * Detect available languages from the core i18n library + * @static + * @return array + */ + public static function listAvailableLanguages() + { + // Cache in session! + if (isSet($_SESSION["AJXP_LANGUAGES"]) && !isSet($_GET["refresh_langs"])) { + return $_SESSION["AJXP_LANGUAGES"]; + } + $langDir = AJXP_COREI18N_FOLDER; + $languages = array(); + if (($dh = opendir($langDir))!==FALSE) { + while (($file = readdir($dh)) !== false) { + $matches = array(); + if (preg_match("/(.*)\.php/", $file, $matches) == 1) { + $fRadical = $matches[1]; + include($langDir."/".$fRadical.".php"); + $langName = isSet($mess["languageLabel"])?$mess["languageLabel"]:"Not Found"; + $languages[$fRadical] = $langName; + } + } + closedir($dh); + } + if (count($languages)) { + $_SESSION["AJXP_LANGUAGES"] = $languages; + } + return $languages; + } + + /** + * Get a config by its name + * @static + * @param string $varName + * @return mixed + */ + public static function getConf($varName) + { + return self::getInstance()->getConfInst($varName); + } + /** + * Set a config by its name + * @static + * @param string $varName + * @param mixed $varValue + * @return void + */ + public static function setConf($varName, $varValue) + { + return self::getInstance()->setConfInst($varName, $varValue); + } + /** + * See static method + * @param $varName + * @return mixed + */ + public function getConfInst($varName) + { + if (isSet($this->configs[$varName])) { + return $this->configs[$varName]; + } + if (defined("AJXP_".$varName)) { + return eval("return AJXP_".$varName.";"); + } + return null; + } + /** + * See static method + * @param $varName + * @param $varValue + * @return void + */ + public function setConfInst($varName, $varValue) + { + $this->configs[$varName] = $varValue; + } + /** + * Get config from the core.$coreType plugin + * @static + * @param string $varName + * @param string $coreType + * @return mixed|null|string + */ + public static function getCoreConf($varName, $coreType = "ajaxplorer") + { + $coreP = AJXP_PluginsService::getInstance()->findPlugin("core", $coreType); + if($coreP === false) return null; + $confs = $coreP->getConfigs(); + $confs = AuthService::filterPluginParameters("core.".$coreType, $confs); + return (isSet($confs[$varName]) ? AJXP_VarsFilter::filter($confs[$varName]) : null); + } + + /** + * Set the language in the session + * @static + * @param string $lang + * @return void + */ + public static function setLanguage($lang) + { + return self::getInstance()->setLanguageInst($lang); + } + /** + * See static method + * @param string $lang + * @return void + */ + public function setLanguageInst($lang) + { + if (array_key_exists($lang, $this->configs["AVAILABLE_LANG"])) { + $this->configs["LANGUE"] = $lang; + } + } + /** + * Get the language from the session + * @static + * @return string + */ + public static function getLanguage() + { + $lang = self::getInstance()->getConfInst("LANGUE"); + if ($lang == null) { + $lang = self::getInstance()->getCoreConf("DEFAULT_LANGUAGE"); + } + if(empty($lang)) return "en"; + return $lang; + } + + /** + * The current repository + * @return Repository + */ + public static function getRepository() + { + return self::getInstance()->getRepositoryInst(); + } + /** + * See static method + * @return Repository + */ + public function getRepositoryInst() + { + if (isSet($_SESSION['REPO_ID']) && isSet($this->configs["REPOSITORIES"]) && isSet($this->configs["REPOSITORIES"][$_SESSION['REPO_ID']])) { + return $this->configs["REPOSITORIES"][$_SESSION['REPO_ID']]; + } + return $this->configs["REPOSITORY"]; + } + + /** + * Returns the repository access driver + * @return AJXP_Plugin + */ + public static function loadRepositoryDriver() + { + return self::getInstance()->loadRepositoryDriverInst(); + } + /** + * See static method + * @throws Exception + * @return AJXP_Plugin + */ + public function loadRepositoryDriverInst() + { + if (isSet($this->configs["ACCESS_DRIVER"]) && is_a($this->configs["ACCESS_DRIVER"], "AbstractAccessDriver")) { + return $this->configs["ACCESS_DRIVER"]; + } + $this->switchRootDirInst(); + $crtRepository = $this->getRepositoryInst(); + $accessType = $crtRepository->getAccessType(); + $pServ = AJXP_PluginsService::getInstance(); + $plugInstance = $pServ->getPluginByTypeName("access", $accessType); + + // TRIGGER BEFORE INIT META + $metaSources = $crtRepository->getOption("META_SOURCES"); + if (isSet($metaSources) && is_array($metaSources) && count($metaSources)) { + $keys = array_keys($metaSources); + foreach ($keys as $plugId) { + if($plugId == "") continue; + $split = explode(".", $plugId); + $instance = $pServ->getPluginById($plugId); + if (!is_object($instance)) { + continue; + } + if (!method_exists($instance, "beforeInitMeta")) { + continue; + } + try { + $instance->init(AuthService::filterPluginParameters($plugId, $metaSources[$plugId], $crtRepository->getId())); + $instance->beforeInitMeta($plugInstance); + } catch (Exception $e) { + AJXP_Logger::logAction('ERROR : Cannot instanciate Meta plugin, reason : '.$e->getMessage()); + $this->errors[] = $e->getMessage(); + } + } + } + + // INIT MAIN DRIVER + $plugInstance->init($crtRepository); + try { + $plugInstance->initRepository(); + $crtRepository->driverInstance = $plugInstance; + } catch (Exception $e) { + // Remove repositories from the lists + unset($this->configs["REPOSITORIES"][$crtRepository->getId()]); + if (isSet($_SESSION["PREVIOUS_REPO_ID"]) && $_SESSION["PREVIOUS_REPO_ID"] !=$crtRepository->getId()) { + $this->switchRootDir($_SESSION["PREVIOUS_REPO_ID"]); + } else { + $this->switchRootDir(); + } + throw $e; + } + $pServ->setPluginUniqueActiveForType("access", $accessType); + + // TRIGGER INIT META + $metaSources = $crtRepository->getOption("META_SOURCES"); + if (isSet($metaSources) && is_array($metaSources) && count($metaSources)) { + $keys = array_keys($metaSources); + foreach ($keys as $plugId) { + if($plugId == "") continue; + $split = explode(".", $plugId); + $instance = $pServ->getPluginById($plugId); + if (!is_object($instance)) { + continue; + } + try { + $instance->init(AuthService::filterPluginParameters($plugId, $metaSources[$plugId], $crtRepository->getId())); + $instance->initMeta($plugInstance); + } catch (Exception $e) { + AJXP_Logger::logAction('ERROR : Cannot instanciate Meta plugin, reason : '.$e->getMessage()); + $this->errors[] = $e->getMessage(); + } + $pServ->setPluginActive($split[0], $split[1]); + } + } + if (count($this->errors)>0) { + $e = new AJXP_Exception("Error while loading repository feature : ".implode(",",$this->errors)); + // Remove repositories from the lists + unset($this->configs["REPOSITORIES"][$crtRepository->getId()]); + if (isSet($_SESSION["PREVIOUS_REPO_ID"]) && $_SESSION["PREVIOUS_REPO_ID"] !=$crtRepository->getId()) { + $this->switchRootDir($_SESSION["PREVIOUS_REPO_ID"]); + } else { + $this->switchRootDir(); + } + throw $e; + } + + $this->configs["ACCESS_DRIVER"] = $plugInstance; + return $this->configs["ACCESS_DRIVER"]; + } + + /** + * @static + * @param Repository $repository + * @return AbstractAccessDriver + */ + public static function loadDriverForRepository(&$repository) + { + return self::getInstance()->loadRepositoryDriverREST($repository); + } + + /** + * See static method + * @param Repository $repository + * @throws AJXP_Exception|Exception + * @return AbstractAccessDriver + */ + public function loadRepositoryDriverREST(&$repository) + { + if (isset($repository->driverInstance)) { + return $repository->driverInstance; + } + $accessType = $repository->getAccessType(); + $pServ = AJXP_PluginsService::getInstance(); + $plugInstance = $pServ->getPluginByTypeName("access", $accessType); + + // TRIGGER BEFORE INIT META + $metaSources = $repository->getOption("META_SOURCES"); + if (isSet($metaSources) && is_array($metaSources) && count($metaSources)) { + $keys = array_keys($metaSources); + foreach ($keys as $plugId) { + if($plugId == "") continue; + $instance = $pServ->getPluginById($plugId); + if (!is_object($instance)) { + continue; + } + if (!method_exists($instance, "beforeInitMeta")) { + continue; + } + try { + $instance->init(AuthService::filterPluginParameters($plugId, $metaSources[$plugId], $repository->getId())); + $instance->beforeInitMeta($plugInstance); + } catch (Exception $e) { + AJXP_Logger::logAction('ERROR : Cannot instanciate Meta plugin, reason : '.$e->getMessage()); + $this->errors[] = $e->getMessage(); + } + } + } + + // INIT MAIN DRIVER + $plugInstance->init($repository); + try { + $plugInstance->initRepository(); + } catch (Exception $e) { + throw $e; + } + $pServ->setPluginUniqueActiveForType("access", $accessType); + + // TRIGGER INIT META + $metaSources = $repository->getOption("META_SOURCES"); + if (isSet($metaSources) && is_array($metaSources) && count($metaSources)) { + $keys = array_keys($metaSources); + foreach ($keys as $plugId) { + if($plugId == "") continue; + $split = explode(".", $plugId); + $instance = $pServ->getPluginById($plugId); + if (!is_object($instance)) { + continue; + } + try { + $instance->init(AuthService::filterPluginParameters($plugId, $metaSources[$plugId], $repository->getId())); + $instance->initMeta($plugInstance); + } catch (Exception $e) { + AJXP_Logger::logAction('ERROR : Cannot instanciate Meta plugin, reason : '.$e->getMessage()); + $this->errors[] = $e->getMessage(); + } + $pServ->setPluginActive($split[0], $split[1]); + } + } + if (count($this->errors)>0) { + $e = new AJXP_Exception("Error while loading repository feature : ".implode(",",$this->errors)); + throw $e; + } + + $repository->driverInstance = $plugInstance; + if (isSet($_SESSION["REPO_ID"]) && $_SESSION["REPO_ID"] == $repository->getId()) { + $this->configs["REPOSITORY"] = $repository; + $this->configs["REPOSITORIES"][$_SESSION['REPO_ID']] = $repository; + } + return $plugInstance; + } + + /** + * Search the manifests declaring ajxpdriver as their root node. Remove ajxp_conf & ajxp_shared + * @static + * @param string $filterByTagName + * @param string $filterByDriverName + * @param bool $limitToEnabledPlugins + * @return string + */ + public static function availableDriversToXML($filterByTagName = "", $filterByDriverName="", $limitToEnabledPlugins = false) + { + $nodeList = AJXP_PluginsService::searchAllManifests("//ajxpdriver", "node", false, $limitToEnabledPlugins); + $xmlBuffer = ""; + foreach ($nodeList as $node) { + $dName = $node->getAttribute("name"); + if($filterByDriverName != "" && $dName != $filterByDriverName) continue; + if($dName == "ajxp_conf" || $dName == "ajxp_shared") continue; + if ($filterByTagName == "") { + $xmlBuffer .= $node->ownerDocument->saveXML($node); + continue; + } + $q = new DOMXPath($node->ownerDocument); + $cNodes = $q->query("//".$filterByTagName, $node); + $nodeAttr = $node->attributes; + $xmlBuffer .= "attributes as $attr) $xmlBuffer.= " $attr->name=\"$attr->value\" "; + $xmlBuffer .=">"; + foreach ($cNodes as $child) { + $xmlBuffer .= $child->ownerDocument->saveXML($child); + } + $xmlBuffer .= ""; + } + return $xmlBuffer; + } + + /** + * Singleton method + * + * @return ConfService the service instance + */ + public static function getInstance() + { + if (!isSet(self::$instance)) { + $c = __CLASS__; + self::$instance = new $c; + } + return self::$instance; + } + private function __construct(){} + public function __clone() + { + trigger_error("Cannot clone me, i'm a singleton!", E_USER_ERROR); + } + +} diff --git a/core/src/core/classes/class.HTMLWriter.php b/core/src/core/classes/class.HTMLWriter.php index 3624bf22e2..9653f1b829 100644 --- a/core/src/core/classes/class.HTMLWriter.php +++ b/core/src/core/classes/class.HTMLWriter.php @@ -34,12 +34,12 @@ class HTMLWriter * @param string $errorMessage * @return void */ - static function displayMessage($logMessage, $errorMessage) - { - $mess = ConfService::getMessages(); - echo "
    ".(isset($logMessage)?$logMessage:$errorMessage)."".$mess[98]."
    "; - echo ""; - } + public static function displayMessage($logMessage, $errorMessage) + { + $mess = ConfService::getMessages(); + echo "
    ".(isset($logMessage)?$logMessage:$errorMessage)."".$mess[98]."
    "; + echo ""; + } /** * Replace the doc files keywords @@ -47,31 +47,31 @@ static function displayMessage($logMessage, $errorMessage) * @param string $docFileName * @return string */ - static function getDocFile($docFileName) + public static function getDocFile($docFileName) { - $realName = AJXP_DOCS_FOLDER."/".$docFileName.".txt"; - if(is_file($realName)) - { - $content = implode("
    ", file($realName)); - $content = preg_replace("(http:\/\/[a-z|.|\/|\-|0-9]*)", "$0", $content); - $content = preg_replace("(\[(.*)\])", "
    $1
    ", $content); - $content = preg_replace("(\+\+ (.*) \+\+)", "
    $1
    ", $content); - $content = str_replace("__AJXP_VERSION__", AJXP_VERSION, $content); - $content = str_replace("__AJXP_VERSION_DATE__", AJXP_VERSION_DATE, $content); - return $content; - } - return "File not found : ".$docFileName; + $realName = AJXP_DOCS_FOLDER."/".$docFileName.".txt"; + if (is_file($realName)) { + $content = implode("
    ", file($realName)); + $content = preg_replace("(http:\/\/[a-z|.|\/|\-|0-9]*)", "$0", $content); + $content = preg_replace("(\[(.*)\])", "
    $1
    ", $content); + $content = preg_replace("(\+\+ (.*) \+\+)", "
    $1
    ", $content); + $content = str_replace("__AJXP_VERSION__", AJXP_VERSION, $content); + $content = str_replace("__AJXP_VERSION_DATE__", AJXP_VERSION_DATE, $content); + return $content; + } + return "File not found : ".$docFileName; } /** * Write repository data directly as javascript string * @static * @return mixed|string */ - static function repositoryDataAsJS(){ - if(AuthService::usersEnabled()) return ""; - require_once(AJXP_BIN_FOLDER."/class.SystemTextEncoding.php"); - require_once(AJXP_BIN_FOLDER."/class.AJXP_XMLWriter.php"); - return str_replace("'", "\'", AJXP_XMLWriter::writeRepositoriesData(null)); + public static function repositoryDataAsJS() + { + if(AuthService::usersEnabled()) return ""; + require_once(AJXP_BIN_FOLDER."/class.SystemTextEncoding.php"); + require_once(AJXP_BIN_FOLDER."/class.AJXP_XMLWriter.php"); + return str_replace("'", "\'", AJXP_XMLWriter::writeRepositoriesData(null)); } /** * Write the messages as Javascript @@ -79,26 +79,22 @@ static function repositoryDataAsJS(){ * @param array $mess * @return void */ - static function writeI18nMessagesClass($mess) + public static function writeI18nMessagesClass($mess) { - echo "\n"; + } + echo "MessageHash;"; + echo "\n"; } /** @@ -108,10 +104,11 @@ static function writeI18nMessagesClass($mess) * @param string $charset * @return void */ - static function internetExplorerMainDocumentHeader(){ - if(strstr($_SERVER["HTTP_USER_AGENT"], "MSIE 9.")){ + public static function internetExplorerMainDocumentHeader() + { + if (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE 9.")) { header("X-UA-Compatible: IE=9"); - }else if(strstr($_SERVER["HTTP_USER_AGENT"], "MSIE 10.")){ + } else if (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE 10.")) { header("X-UA-Compatible: IE=Edge,chrome=1"); } } @@ -123,16 +120,18 @@ static function internetExplorerMainDocumentHeader(){ * @param string $charset * @return void */ - static function charsetHeader($type = 'text/html', $charset='UTF-8'){ - header("Content-type:$type; charset=$charset"); + public static function charsetHeader($type = 'text/html', $charset='UTF-8') + { + header("Content-type:$type; charset=$charset"); } /** * Write a closing sequence * @static * @return void */ - static function closeBodyAndPage(){ - print(""); + public static function closeBodyAndPage() + { + print(""); } /** * Write directly an error as a javascript instruction @@ -141,11 +140,12 @@ static function closeBodyAndPage(){ * @param $errorMessage * @return */ - static function javascriptErrorHandler($errorType, $errorMessage){ - // Handle "@" case! - if(error_reporting() == 0) return ; - restore_error_handler(); - die(""); + public static function javascriptErrorHandler($errorType, $errorMessage) + { + // Handle "@" case! + if(error_reporting() == 0) return ; + restore_error_handler(); + die(""); } /** @@ -155,35 +155,32 @@ static function javascriptErrorHandler($errorType, $errorMessage){ * @param bool $isFile * @param bool $gzip If true, make sure the $dataSize is the size of the ENCODED data. */ - static function generateAttachmentsHeader(&$attachmentName, $dataSize, $isFile=true, $gzip=false){ - - if(preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']) || preg_match('/ WebKit /',$_SERVER['HTTP_USER_AGENT'])){ - $attachmentName = str_replace("+", " ", urlencode(SystemTextEncoding::toUTF8($attachmentName))); - } + public static function generateAttachmentsHeader(&$attachmentName, $dataSize, $isFile=true, $gzip=false) + { + if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']) || preg_match('/ WebKit /',$_SERVER['HTTP_USER_AGENT'])) { + $attachmentName = str_replace("+", " ", urlencode(SystemTextEncoding::toUTF8($attachmentName))); + } header("Content-Type: application/force-download; name=\"".$attachmentName."\""); header("Content-Transfer-Encoding: binary"); - if($gzip){ + if ($gzip) { header("Content-Encoding: gzip"); } header("Content-Length: ".$dataSize); - if ($isFile && ($dataSize != 0)) - { + if ($isFile && ($dataSize != 0)) { header("Content-Range: bytes 0-" . ($dataSize- 1) . "/" . $dataSize . ";"); } header("Content-Disposition: attachment; filename=\"".$attachmentName."\""); header("Expires: 0"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); - if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) - { + if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) { header("Cache-Control: max_age=0"); header("Pragma: public"); } // IE8 is dumb - if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) - { + if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) { header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); @@ -192,33 +189,30 @@ static function generateAttachmentsHeader(&$attachmentName, $dataSize, $isFile=t // For SSL websites there is a bug with IE see article KB 323308 // therefore we must reset the Cache-Control and Pragma Header - if (ConfService::getConf("USE_HTTPS")==1 && preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) - { + if (ConfService::getConf("USE_HTTPS")==1 && preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) { header("Cache-Control:"); header("Pragma:"); } } - static function generateInlineHeaders($attachName, $fileSize, $mimeType){ - + public static function generateInlineHeaders($attachName, $fileSize, $mimeType) + { //Send headers header("Content-Type: " . $mimeType . "; name=\"" . $attachName . "\""); header("Content-Disposition: inline; filename=\"" . $attachName . "\""); // changed header for IE 7 & 8 - if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) - { + if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) { header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private",false); - }else{ + } else { header("Cache-Control: public"); } header("Content-Length: " . $fileSize); // Neccessary for IE 8 and xx - if (ConfService::getConf("USE_HTTPS")==1 && preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) - { + if (ConfService::getConf("USE_HTTPS")==1 && preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT'])) { header("Cache-Control:"); header("Pragma:"); } @@ -226,5 +220,3 @@ static function generateInlineHeaders($attachName, $fileSize, $mimeType){ } } - -?> diff --git a/core/src/core/classes/class.HttpClient.php b/core/src/core/classes/class.HttpClient.php index 1f5b6aacc4..0ea2497925 100644 --- a/core/src/core/classes/class.HttpClient.php +++ b/core/src/core/classes/class.HttpClient.php @@ -6,56 +6,59 @@ * @subpackage Core */ -class HttpClient { +class HttpClient +{ // Request vars - var $host; - var $port; - var $path; - var $method; - var $postdata = ''; - var $cookies = array(); - var $referer; - var $accept = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*'; - var $accept_encoding = 'gzip'; - var $accept_language = 'en-us'; - var $user_agent = 'Incutio HttpClient v0.9'; + public $host; + public $port; + public $path; + public $method; + public $postdata = ''; + public $cookies = array(); + public $referer; + public $accept = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*'; + public $accept_encoding = 'gzip'; + public $accept_language = 'en-us'; + public $user_agent = 'Incutio HttpClient v0.9'; // Options - var $timeout = 20; - var $use_gzip = true; - var $persist_cookies = true; // If true, received cookies are placed in the $this->cookies array ready for the next request - // Note: This currently ignores the cookie path (and time) completely. Time is not important, + public $timeout = 20; + public $use_gzip = true; + public $persist_cookies = true; // If true, received cookies are placed in the $this->cookies array ready for the next request + // Note: This currently ignores the cookie path (and time) completely. Time is not important, // but path could possibly lead to security problems. - var $persist_referers = true; // For each request, sends path of last request as referer - var $debug = false; - var $handle_redirects = true; // Auaomtically redirect if Location or URI header is found - var $max_redirects = 5; - var $headers_only = false; // If true, stops receiving once headers have been read. + public $persist_referers = true; // For each request, sends path of last request as referer + public $debug = false; + public $handle_redirects = true; // Auaomtically redirect if Location or URI header is found + public $max_redirects = 5; + public $headers_only = false; // If true, stops receiving once headers have been read. // Basic authorization variables - var $username; - var $password; + public $username; + public $password; // Response vars - var $status; - var $headers = array(); - var $content = ''; - var $errormsg; + public $status; + public $headers = array(); + public $content = ''; + public $errormsg; // Tracker variables - var $redirect_count = 0; - var $cookie_host = ''; - var $postFileName = "userfile"; - var $postFileData = array(); - var $postDataArray = array(); - - var $directForwarding = false; - var $contentDestStream = false; - var $eventListener = false; - - var $collectHeaders; - - function HttpClient($host, $port=80) { + public $redirect_count = 0; + public $cookie_host = ''; + public $postFileName = "userfile"; + public $postFileData = array(); + public $postDataArray = array(); + + public $directForwarding = false; + public $contentDestStream = false; + public $eventListener = false; + + public $collectHeaders; + + public function HttpClient($host, $port=80) + { $this->host = $host; $this->port = $port; } - function get($path, $data = false) { + public function get($path, $data = false) + { $this->path = $path; $this->method = 'GET'; if ($data) { @@ -63,229 +66,238 @@ function get($path, $data = false) { } return $this->doRequest(); } - function post($path, $data) { + public function post($path, $data) + { $this->path = $path; $this->method = 'POST'; $this->postdata = $this->buildQueryString($data); - return $this->doRequest(); + return $this->doRequest(); } - function postFile($path, $postData, $fileVarName, $fileData){ - $this->path = $path; - $this->method = 'POST'; - $this->postFileData = $fileData; - $this->postDataArray = $postData; - $this->postFileName = $fileVarName; - $this->postdata = $this->buildQueryString($postData); - return $this->doRequest(); + public function postFile($path, $postData, $fileVarName, $fileData) + { + $this->path = $path; + $this->method = 'POST'; + $this->postFileData = $fileData; + $this->postDataArray = $postData; + $this->postFileName = $fileVarName; + $this->postdata = $this->buildQueryString($postData); + return $this->doRequest(); } - - function writeContentToStream($destStream){ - $this->contentDestStream = $destStream; + + public function writeContentToStream($destStream) + { + $this->contentDestStream = $destStream; } - - function clearContentDestStream(){ - $this->contentDestStream = false; + + public function clearContentDestStream() + { + $this->contentDestStream = false; } - - function setEventListener($callback){ - $this->eventListener = $callback; + + public function setEventListener($callback) + { + $this->eventListener = $callback; } - - function notify($eventName, $data = null){ - if($this->eventListener == false) return; - call_user_func($this->eventListener, $eventName, $data); + + public function notify($eventName, $data = null) + { + if($this->eventListener == false) return; + call_user_func($this->eventListener, $eventName, $data); } - - function buildQueryString($data) { + + public function buildQueryString($data) + { $querystring = ''; if (is_array($data)) { // Change data in to postable data - foreach ($data as $key => $val) { - if (is_array($val)) { - foreach ($val as $val2) { - $querystring .= urlencode($key).'='.urlencode($val2).'&'; - } - } else { - $querystring .= urlencode($key).'='.urlencode($val).'&'; - } - } - $querystring = substr($querystring, 0, -1); // Eliminate unnecessary & - } else { - $querystring = $data; - } - return $querystring; + foreach ($data as $key => $val) { + if (is_array($val)) { + foreach ($val as $val2) { + $querystring .= urlencode($key).'='.urlencode($val2).'&'; + } + } else { + $querystring .= urlencode($key).'='.urlencode($val).'&'; + } + } + $querystring = substr($querystring, 0, -1); // Eliminate unnecessary & + } else { + $querystring = $data; + } + return $querystring; } - function doRequest() { + public function doRequest() + { // Performs the actual HTTP request, returning true or false depending on outcome $this->notify("open"); - if (!$fp = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout)) { - // Set error message - switch($errno) { - case -3: - $this->errormsg = 'Socket creation failed (-3)'; - case -4: - $this->errormsg = 'DNS lookup failure (-4)'; - case -5: - $this->errormsg = 'Connection refused or timed out (-5)'; - default: - $this->errormsg = 'Connection failed on '.$this->host.'('.$errno.')'; - $this->errormsg .= ' '.$errstr; - $this->debug($this->errormsg); - } - $this->notify("error", $this->errormsg); - $this->notify("close"); - return false; + if (!$fp = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout)) { + // Set error message + switch ($errno) { + case -3: + $this->errormsg = 'Socket creation failed (-3)'; + case -4: + $this->errormsg = 'DNS lookup failure (-4)'; + case -5: + $this->errormsg = 'Connection refused or timed out (-5)'; + default: + $this->errormsg = 'Connection failed on '.$this->host.'('.$errno.')'; + $this->errormsg .= ' '.$errstr; + $this->debug($this->errormsg); + } + $this->notify("error", $this->errormsg); + $this->notify("close"); + return false; } socket_set_timeout($fp, $this->timeout); $request = $this->buildRequest(); $this->debug('Request', $request); @fwrite($fp, $request); - // Reset all the variables that should not persist between requests - $this->headers = array(); - $this->content = ''; - $this->errormsg = ''; - // Set a couple of flags - $inHeaders = true; - $atStart = true; - $parsedHeaders = false; - $totalReadSize = 0; - // Now start reading back the response - while (!feof($fp)) { - @set_time_limit(60); - $line = fgets($fp, 4096); - if ($atStart) { - // Deal with first line of returned data - $atStart = false; - if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', $line, $m)) { - $this->errormsg = "Status code line invalid: ".htmlentities($line); - $this->debug($this->errormsg); - $this->notify("error", $this->errormsg); - $this->notify("close"); - return false; - } - $http_version = $m[1]; // not used - $this->status = $m[2]; - $status_string = $m[3]; // not used - $this->debug(trim($line)); - continue; - } - if ($inHeaders) { - if (trim($line) == '') { - $inHeaders = false; - $this->debug('Received Headers', $this->headers); - if(isSet($this->collectHeaders)){ - foreach ($this->headers as $hKey => $hValue){ - if(isSet($this->collectHeaders[$hKey])){ - if($hKey == "content-length" && $hValue == "0") continue; - $this->collectHeaders[$hKey] = $hValue; - AJXP_Logger::debug("Setting $hKey", $this->collectHeaders); - } - } - } - if ($this->persist_cookies && isset($this->headers['set-cookie']) && $this->host == $this->cookie_host) { - $cookies = $this->headers['set-cookie']; - if (!is_array($cookies)) { - $cookies = array($cookies); - } - foreach ($cookies as $cookie) { - if (preg_match('/([^=]+)=([^;]+);/', $cookie, $m)) { - $this->cookies[$m[1]] = $m[2]; - } - } - // Record domain of cookies for security reasons - $this->cookie_host = $this->host; - } - // If $persist_referers, set the referer ready for the next request - if ($this->persist_referers) { - //$this->debug('Persisting referer: '.$this->getRequestURL()); - $this->referer = $this->getRequestURL(); - } - // Finally, if handle_redirects and a redirect is sent, do that - if ($this->handle_redirects) { - if (++$this->redirect_count >= $this->max_redirects) { - $this->errormsg = 'Number of redirects exceeded maximum ('.$this->max_redirects.')'; - $this->debug($this->errormsg); - $this->redirect_count = 0; - return false; - } - $location = isset($this->headers['location']) ? $this->headers['location'] : ''; - $uri = isset($this->headers['uri']) ? $this->headers['uri'] : ''; - if ($location || $uri) { - $url = parse_url($location.$uri); - // This will FAIL if redirect is to a different site - $this->debug("Should redirect! ", $url); - $data = array(); - if(isSet($url['query'])){ - parse_str($url["query"], $data); - } - $this->host = $url["host"]; - fclose($fp); - if(isSet($this->collectHeaders) && isSet($this->collectHeaders["ajxp-last-redirection"])){ - $this->collectHeaders["ajxp-last-redirection"] = $location.$uri; - } - return $this->get($url['path'], (!empty($data)?$data:false)); - } - } - - if ($this->headers_only) { - break; // Skip the rest of the input - } - continue; - } - if (!preg_match('/([^:]+):\\s*(.*)/', $line, $m)) { - // Skip to the next header - continue; - } - $key = strtolower(trim($m[1])); - $val = trim($m[2]); - if($this->directForwarding){ - header($line, true); - continue; - } + // Reset all the variables that should not persist between requests + $this->headers = array(); + $this->content = ''; + $this->errormsg = ''; + // Set a couple of flags + $inHeaders = true; + $atStart = true; + $parsedHeaders = false; + $totalReadSize = 0; + // Now start reading back the response + while (!feof($fp)) { + @set_time_limit(60); + $line = fgets($fp, 4096); + if ($atStart) { + // Deal with first line of returned data + $atStart = false; + if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', $line, $m)) { + $this->errormsg = "Status code line invalid: ".htmlentities($line); + $this->debug($this->errormsg); + $this->notify("error", $this->errormsg); + $this->notify("close"); + return false; + } + $http_version = $m[1]; // not used + $this->status = $m[2]; + $status_string = $m[3]; // not used + $this->debug(trim($line)); + continue; + } + if ($inHeaders) { + if (trim($line) == '') { + $inHeaders = false; + $this->debug('Received Headers', $this->headers); + if (isSet($this->collectHeaders)) { + foreach ($this->headers as $hKey => $hValue) { + if (isSet($this->collectHeaders[$hKey])) { + if($hKey == "content-length" && $hValue == "0") continue; + $this->collectHeaders[$hKey] = $hValue; + AJXP_Logger::debug("Setting $hKey", $this->collectHeaders); + } + } + } + if ($this->persist_cookies && isset($this->headers['set-cookie']) && $this->host == $this->cookie_host) { + $cookies = $this->headers['set-cookie']; + if (!is_array($cookies)) { + $cookies = array($cookies); + } + foreach ($cookies as $cookie) { + if (preg_match('/([^=]+)=([^;]+);/', $cookie, $m)) { + $this->cookies[$m[1]] = $m[2]; + } + } + // Record domain of cookies for security reasons + $this->cookie_host = $this->host; + } + // If $persist_referers, set the referer ready for the next request + if ($this->persist_referers) { + //$this->debug('Persisting referer: '.$this->getRequestURL()); + $this->referer = $this->getRequestURL(); + } + // Finally, if handle_redirects and a redirect is sent, do that + if ($this->handle_redirects) { + if (++$this->redirect_count >= $this->max_redirects) { + $this->errormsg = 'Number of redirects exceeded maximum ('.$this->max_redirects.')'; + $this->debug($this->errormsg); + $this->redirect_count = 0; + return false; + } + $location = isset($this->headers['location']) ? $this->headers['location'] : ''; + $uri = isset($this->headers['uri']) ? $this->headers['uri'] : ''; + if ($location || $uri) { + $url = parse_url($location.$uri); + // This will FAIL if redirect is to a different site + $this->debug("Should redirect! ", $url); + $data = array(); + if (isSet($url['query'])) { + parse_str($url["query"], $data); + } + $this->host = $url["host"]; + fclose($fp); + if (isSet($this->collectHeaders) && isSet($this->collectHeaders["ajxp-last-redirection"])) { + $this->collectHeaders["ajxp-last-redirection"] = $location.$uri; + } + return $this->get($url['path'], (!empty($data)?$data:false)); + } + } - // Deal with the possibility of multiple headers of same name - if (isset($this->headers[$key])) { - if (is_array($this->headers[$key])) { - $this->headers[$key][] = $val; - } else { - $this->headers[$key] = array($this->headers[$key], $val); - } - } else { - $this->headers[$key] = $val; - } - continue; - } - - // We're not in the headers, so append the line to the contents - if($this->directForwarding){ - print $line; - continue; - } - if($this->contentDestStream===false){ - $this->content .= $line; - }else{ - fwrite($this->contentDestStream, $line); - } - $totalReadSize += strlen($line); - $this->notify("data_read", $totalReadSize); - } - $this->notify("close"); + if ($this->headers_only) { + break; // Skip the rest of the input + } + continue; + } + if (!preg_match('/([^:]+):\\s*(.*)/', $line, $m)) { + // Skip to the next header + continue; + } + $key = strtolower(trim($m[1])); + $val = trim($m[2]); + if ($this->directForwarding) { + header($line, true); + continue; + } + + // Deal with the possibility of multiple headers of same name + if (isset($this->headers[$key])) { + if (is_array($this->headers[$key])) { + $this->headers[$key][] = $val; + } else { + $this->headers[$key] = array($this->headers[$key], $val); + } + } else { + $this->headers[$key] = $val; + } + continue; + } + + // We're not in the headers, so append the line to the contents + if ($this->directForwarding) { + print $line; + continue; + } + if ($this->contentDestStream===false) { + $this->content .= $line; + } else { + fwrite($this->contentDestStream, $line); + } + $totalReadSize += strlen($line); + $this->notify("data_read", $totalReadSize); + } + $this->notify("close"); fclose($fp); - if($this->directForwarding){ - return ; - } + if ($this->directForwarding) { + return ; + } // If data is compressed, uncompress it if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] == 'gzip') { $this->debug('Content is gzip encoded, unzipping it'); - if(!$this->headers_only){ - $this->content = substr($this->content, 10); // See http://www.php.net/manual/en/function.gzencode.php - $this->content = gzinflate($this->content); + if (!$this->headers_only) { + $this->content = substr($this->content, 10); // See http://www.php.net/manual/en/function.gzencode.php + $this->content = gzinflate($this->content); } } // $this->debug("CONTENT : ".htmlentities($this->content)); return true; } - function buildRequest() { + public function buildRequest() + { $headers = array(); $headers[] = "{$this->method} {$this->path} HTTP/1.0"; // Using 1.1 leads to all manner of problems, such as "chunked" encoding $headers[] = "Host: {$this->host}"; @@ -298,64 +310,68 @@ function buildRequest() { if ($this->referer) { $headers[] = "Referer: {$this->referer}"; } - // Cookies - if ($this->cookies) { - $cookie = 'Cookie: '; - foreach ($this->cookies as $key => $value) { - $cookie .= "$key=$value; "; - } - $headers[] = $cookie; - } - // Basic authentication - if ($this->username && $this->password) { - $headers[] = 'Authorization: BASIC '.base64_encode($this->username.':'.$this->password); - } - if(!count($this->postFileData)){ - // If this is a POST, set the content type and length - if ($this->postdata) { - $headers[] = 'Content-Type: application/x-www-form-urlencoded'; - $headers[] = 'Content-Length: '.strlen($this->postdata); - } - $request = implode("\r\n", $headers)."\r\n\r\n".$this->postdata; - }else{ - srand((double)microtime()*1000000); - $boundary = "----".substr(md5(rand(0,32000)),0,10); - $headers[] = "Content-Type: multipart/form-data; boundary=$boundary"; - $data = array(); - // attach post vars - $this->postDataArray["Filename"] = $this->postFileData["name"]; - foreach($this->postDataArray as $index => $value){ - $data[]="--$boundary"; - $data[]= "content-disposition: form-data; name=\"".$index."\""; - $data[]= "\r\n".$value.""; - } - // and attach the file - //$data[]= "--$boundary"; - $content_file = join("", file($this->postFileData["tmp_name"])); - $data[]="--$boundary"; - $data[]="content-disposition: form-data; name=\"".$this->postFileName."\"; filename=\"".$this->postFileData["name"]."\""; - $data[]= "Content-Type: ".$this->postFileData['type']."\r\n"; - $data[]= "".$content_file.""; - $data[]="--$boundary--"; - //$headers[]= "Content-Length: " . strlen(implode("",$data)); - $data = implode("\r\n", $data); - $headers[]= "Content-Length: " . strlen($data); - $headers[] = "Cache-Control: no-cache"; - $headers[] = "Connection: Keep-Alive"; - $request = implode("\r\n", $headers)."\r\n\r\n".$data; - } - return $request; + // Cookies + if ($this->cookies) { + $cookie = 'Cookie: '; + foreach ($this->cookies as $key => $value) { + $cookie .= "$key=$value; "; + } + $headers[] = $cookie; + } + // Basic authentication + if ($this->username && $this->password) { + $headers[] = 'Authorization: BASIC '.base64_encode($this->username.':'.$this->password); + } + if (!count($this->postFileData)) { + // If this is a POST, set the content type and length + if ($this->postdata) { + $headers[] = 'Content-Type: application/x-www-form-urlencoded'; + $headers[] = 'Content-Length: '.strlen($this->postdata); + } + $request = implode("\r\n", $headers)."\r\n\r\n".$this->postdata; + } else { + srand((double) microtime()*1000000); + $boundary = "----".substr(md5(rand(0,32000)),0,10); + $headers[] = "Content-Type: multipart/form-data; boundary=$boundary"; + $data = array(); + // attach post vars + $this->postDataArray["Filename"] = $this->postFileData["name"]; + foreach ($this->postDataArray as $index => $value) { + $data[]="--$boundary"; + $data[]= "content-disposition: form-data; name=\"".$index."\""; + $data[]= "\r\n".$value.""; + } + // and attach the file + //$data[]= "--$boundary"; + $content_file = join("", file($this->postFileData["tmp_name"])); + $data[]="--$boundary"; + $data[]="content-disposition: form-data; name=\"".$this->postFileName."\"; filename=\"".$this->postFileData["name"]."\""; + $data[]= "Content-Type: ".$this->postFileData['type']."\r\n"; + $data[]= "".$content_file.""; + $data[]="--$boundary--"; + //$headers[]= "Content-Length: " . strlen(implode("",$data)); + $data = implode("\r\n", $data); + $headers[]= "Content-Length: " . strlen($data); + $headers[] = "Cache-Control: no-cache"; + $headers[] = "Connection: Keep-Alive"; + $request = implode("\r\n", $headers)."\r\n\r\n".$data; + } + return $request; } - function getStatus() { + public function getStatus() + { return $this->status; } - function getContent() { + public function getContent() + { return $this->content; } - function getHeaders() { + public function getHeaders() + { return $this->headers; } - function getHeader($header) { + public function getHeader($header) + { $header = strtolower($header); if (isset($this->headers[$header])) { return $this->headers[$header]; @@ -363,58 +379,72 @@ function getHeader($header) { return false; } } - function getError() { + public function getError() + { return $this->errormsg; } - function getCookies() { + public function getCookies() + { return $this->cookies; } - function getRequestURL() { + public function getRequestURL() + { $url = 'http://'.$this->host; if ($this->port != 80) { $url .= ':'.$this->port; - } + } $url .= $this->path; return $url; } // Setter methods - function setUserAgent($string) { + public function setUserAgent($string) + { $this->user_agent = $string; } - function setAuthorization($username, $password) { + public function setAuthorization($username, $password) + { $this->username = $username; $this->password = $password; } - function setCookies($array) { + public function setCookies($array) + { $this->cookies = $array; } // Option setting methods - function useGzip($boolean) { + public function useGzip($boolean) + { $this->use_gzip = $boolean; } - function setPersistCookies($boolean) { + public function setPersistCookies($boolean) + { $this->persist_cookies = $boolean; } - function setPersistReferers($boolean) { + public function setPersistReferers($boolean) + { $this->persist_referers = $boolean; } - function setHandleRedirects($boolean) { + public function setHandleRedirects($boolean) + { $this->handle_redirects = $boolean; } - function setMaxRedirects($num) { + public function setMaxRedirects($num) + { $this->max_redirects = $num; } - function setHeadersOnly($boolean, &$collectHeaders = null) { + public function setHeadersOnly($boolean, &$collectHeaders = null) + { $this->headers_only = $boolean; - if($collectHeaders != null){ - $this->collectHeaders = $collectHeaders; + if ($collectHeaders != null) { + $this->collectHeaders = $collectHeaders; } } - function setDebug($boolean) { + public function setDebug($boolean) + { $this->debug = $boolean; } // "Quick" static methods - function quickGet($url) { + public function quickGet($url) + { $bits = parse_url($url); $host = $bits['host']; $port = isset($bits['port']) ? $bits['port'] : 80; @@ -429,7 +459,8 @@ function quickGet($url) { return $client->getContent(); } } - function quickPost($url, $data) { + public function quickPost($url, $data) + { $bits = parse_url($url); $host = $bits['host']; $port = isset($bits['port']) ? $bits['port'] : 80; @@ -441,20 +472,19 @@ function quickPost($url, $data) { return $client->getContent(); } } - function debug($msg, $object = false) { + public function debug($msg, $object = false) + { if ($this->debug) { $st = '
    HttpClient Debug: '.$msg; if ($object) { ob_start(); - print_r($object); - $content = htmlentities(ob_get_contents()); - ob_end_clean(); - $st .= '
    '.$content.'
    '; - } - $st .= '
    '; - AJXP_Logger::debug($msg . ($object!==false?" - ".print_r($object, true):"")); + print_r($object); + $content = htmlentities(ob_get_contents()); + ob_end_clean(); + $st .= '
    '.$content.'
    '; + } + $st .= ''; + AJXP_Logger::debug($msg . ($object!==false?" - ".print_r($object, true):"")); } - } + } } - -?> \ No newline at end of file diff --git a/core/src/core/classes/class.RecycleBinManager.php b/core/src/core/classes/class.RecycleBinManager.php index 5a0e2b0895..a15f9fdb3d 100644 --- a/core/src/core/classes/class.RecycleBinManager.php +++ b/core/src/core/classes/class.RecycleBinManager.php @@ -27,13 +27,14 @@ */ class RecycleBinManager { - private static $rbmRecycle; - private static $rbmRelativeRecycle; - - public static function recycleEnabled(){ - return (isSet(self::$rbmRecycle) && self::$rbmRecycle != null && is_string(self::$rbmRecycle)); - } - + private static $rbmRecycle; + private static $rbmRelativeRecycle; + + public static function recycleEnabled() + { + return (isSet(self::$rbmRecycle) && self::$rbmRecycle != null && is_string(self::$rbmRecycle)); + } + /** * Initialize manager * @static @@ -41,37 +42,40 @@ public static function recycleEnabled(){ * @param $recyclePath * @return void */ - public static function init($repositoryWrapperURL, $recyclePath) - { - self::$rbmRecycle = $repositoryWrapperURL.$recyclePath; - self::$rbmRelativeRecycle = $recyclePath; - } - /** + public static function init($repositoryWrapperURL, $recyclePath) + { + self::$rbmRecycle = $repositoryWrapperURL.$recyclePath; + self::$rbmRelativeRecycle = $recyclePath; + } + /** * Get the recycle bin path (repository URL included) * @static * @return string */ - public static function getRecyclePath(){ - return self::$rbmRecycle ; - } - /** + public static function getRecyclePath() + { + return self::$rbmRecycle ; + } + /** * Get the recycle bin path (from the root of the repository) * @static * @return string */ - public static function getRelativeRecycle(){ - return self::$rbmRelativeRecycle; - } - /** + public static function getRelativeRecycle() + { + return self::$rbmRelativeRecycle; + } + /** * Is the current path the recycle? * @static * @param string $currentLocation PATH from the root of repo * @return bool */ - public static function currentLocationIsRecycle($currentLocation){ - return ($currentLocation == self::$rbmRelativeRecycle); - } - /** + public static function currentLocationIsRecycle($currentLocation) + { + return ($currentLocation == self::$rbmRelativeRecycle); + } + /** * Transform delete/restore actions into move actino * @static * @param string $action @@ -80,50 +84,48 @@ public static function currentLocationIsRecycle($currentLocation){ * @param array $httpVars * @return array */ - public static function filterActions($action, $selection, $currentLocation, $httpVars = array()){ - if(!self::recycleEnabled()) return array(); - $newArgs = array(); + public static function filterActions($action, $selection, $currentLocation, $httpVars = array()) + { + if(!self::recycleEnabled()) return array(); + $newArgs = array(); + + // FILTER ACTION FOR DELETE + if ($action == "delete" && !self::currentLocationIsRecycle($currentLocation) && !isSet($httpVars["force_deletion"])) { + $newArgs["action"] = "move"; + $newArgs["dest"] = self::$rbmRelativeRecycle; + } + // FILTER ACTION FOR RESTORE + if ($action == "restore" && self::currentLocationIsRecycle($currentLocation)) { + $originalRep = self::getFileOrigin($selection->getUniqueFile()); + if ($originalRep != "") { + $newArgs["action"] = "move"; + $newArgs["dest"] = $originalRep; // CHECK UTF8 HANDLING HERE + } + } + return $newArgs; - // FILTER ACTION FOR DELETE - if($action == "delete" && !self::currentLocationIsRecycle($currentLocation) && !isSet($httpVars["force_deletion"])) - { - $newArgs["action"] = "move"; - $newArgs["dest"] = self::$rbmRelativeRecycle; - } - // FILTER ACTION FOR RESTORE - if($action == "restore" && self::currentLocationIsRecycle($currentLocation)) - { - $originalRep = self::getFileOrigin($selection->getUniqueFile()); - if($originalRep != "") - { - $newArgs["action"] = "move"; - $newArgs["dest"] = $originalRep; // CHECK UTF8 HANDLING HERE - } - } - return $newArgs; - - } - /** + } + /** * Get the file for caching recylce metadata * @static * @return string */ - public static function getCacheFileName() - { - return ".ajxp_recycle_cache.ser"; - } - /** + public static function getCacheFileName() + { + return ".ajxp_recycle_cache.ser"; + } + /** * Update metadata * @static * @param string $originalFilePath * @return void */ - public static function fileToRecycle($originalFilePath) - { - $cache = self::loadCache(); - $cache[basename($originalFilePath)] = str_replace("\\", "/", dirname($originalFilePath)); - self::saveCache($cache); - } + public static function fileToRecycle($originalFilePath) + { + $cache = self::loadCache(); + $cache[basename($originalFilePath)] = str_replace("\\", "/", dirname($originalFilePath)); + self::saveCache($cache); + } /** * Update metadata @@ -131,66 +133,65 @@ public static function fileToRecycle($originalFilePath) * @param $filePath * @return void */ - public static function deleteFromRecycle($filePath) - { - $cache = self::loadCache(); - if(array_key_exists(basename($filePath), $cache)) - { - unset($cache[basename($filePath)]); - } - self::saveCache($cache); - } - /** + public static function deleteFromRecycle($filePath) + { + $cache = self::loadCache(); + if (array_key_exists(basename($filePath), $cache)) { + unset($cache[basename($filePath)]); + } + self::saveCache($cache); + } + /** * Use metadata for getting original location * @static * @param $filePath * @return string */ - public static function getFileOrigin($filePath) - { - $cache = self::loadCache(); - if(is_array($cache) && array_key_exists(basename($filePath), $cache)) - { - return $cache[basename($filePath)]; - } - return ""; - } - /** + public static function getFileOrigin($filePath) + { + $cache = self::loadCache(); + if (is_array($cache) && array_key_exists(basename($filePath), $cache)) { + return $cache[basename($filePath)]; + } + return ""; + } + /** * Load the metadata cache * @static * @return array|mixed|null */ - public static function loadCache(){ - $result = array(); - if(!self::recycleEnabled()) return null; - $cachePath = self::getRecyclePath()."/".self::getCacheFileName(); - $fp = @fopen($cachePath, "r"); - if($fp){ - $s = ""; - while(!feof($fp)){ - $s .= fread($fp, 4096); - } - fclose($fp); - $result = unserialize($s); - } - return $result; - } - /** + public static function loadCache() + { + $result = array(); + if(!self::recycleEnabled()) return null; + $cachePath = self::getRecyclePath()."/".self::getCacheFileName(); + $fp = @fopen($cachePath, "r"); + if ($fp) { + $s = ""; + while (!feof($fp)) { + $s .= fread($fp, 4096); + } + fclose($fp); + $result = unserialize($s); + } + return $result; + } + /** * Save the metadata cache * @static * @param $value * @return null */ - public static function saveCache($value){ - if(!self::recycleEnabled()) return null; - $cachePath = self::getRecyclePath()."/".self::getCacheFileName(); - $fp = fopen($cachePath, "w"); - if($fp){ - fwrite($fp, serialize($value)); - fflush($fp); - fclose($fp); - } - } - + public static function saveCache($value) + { + if(!self::recycleEnabled()) return null; + $cachePath = self::getRecyclePath()."/".self::getCacheFileName(); + $fp = fopen($cachePath, "w"); + if ($fp) { + fwrite($fp, serialize($value)); + fflush($fp); + fclose($fp); + } + } + } -?> \ No newline at end of file diff --git a/core/src/core/classes/class.Repository.php b/core/src/core/classes/class.Repository.php index eeb24d2573..852c8a914d 100644 --- a/core/src/core/classes/class.Repository.php +++ b/core/src/core/classes/class.Repository.php @@ -1,540 +1,577 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); -/** - * The basic abstraction of a data store. Can map a FileSystem, but can also map data from a totally - * different source, like the application configurations, a mailbox, etc. - * @package AjaXplorer - * @subpackage Core - */ -class Repository implements AjxpGroupPathProvider { - - /** - * @var string - */ - var $uuid; - /** - * @var string - */ - var $id; - /** - * @var string - */ - var $path; - /** - * @var string - */ - var $display; - /** - * @var string - */ - var $displayStringId; - /** - * @var string - */ - var $accessType = "fs"; - /** - * @var string - */ - var $recycle = ""; - /** - * @var bool - */ - var $create = true; - /** - * @var bool - */ - var $writeable = true; - /** - * @var bool - */ - var $enabled = true; - /** - * @var array - */ - var $options = array(); - /** - * @var string - */ - var $slug; - /** - * @var bool - */ - public $isTemplate = false; - - /** - * @var string - */ - private $owner; - /** - * @var string - */ - private $parentId; - /** - * @var string - */ - private $uniqueUser; - /** - * @var bool - */ - private $inferOptionsFromParent; - /** - * @var Repository - */ - private $parentTemplateObject; - /** - * @var array - */ - public $streamData; - - /** - * @var String the groupPath of the administrator who created that repository. - */ - protected $groupPath; - - - public $driverInstance; - - /** - * @param string $id - * @param string $display - * @param string $driver - * @return void - */ - function Repository($id, $display, $driver){ - $this->setAccessType($driver); - $this->setDisplay($display); - $this->setId($id); - $this->uuid = md5(microtime()); - $this->slug = AJXP_Utils::slugify($display); - $this->inferOptionsFromParent = false; - $this->options["CREATION_TIME"] = time(); - if(AuthService::usersEnabled() && AuthService::getLoggedUser() != null){ - $this->options["CREATION_USER"] = AuthService::getLoggedUser()->getId(); - } - } - - /** - * Create a shared version of this repository - * @param string $newLabel - * @param array $newOptions - * @param string $parentId - * @param string $owner - * @param string $uniqueUser - * @return Repository - */ - function createSharedChild($newLabel, $newOptions, $parentId = null, $owner = null, $uniqueUser = null){ - $repo = new Repository(0, $newLabel, $this->accessType); - $newOptions = array_merge($this->options, $newOptions); - $repo->options = $newOptions; - if($parentId == null){ - $parentId = $this->getId(); - } - $repo->setOwnerData($parentId, $owner, $uniqueUser); - return $repo; - } - /** - * Create a child from this repository if it's a template - * @param string $newLabel - * @param array $newOptions - * @param string $owner - * @param string $uniqueUser - * @return Repository - */ - function createTemplateChild($newLabel, $newOptions, $owner = null, $uniqueUser = null){ - $repo = new Repository(0, $newLabel, $this->accessType); - $repo->options = $newOptions; - $repo->setOwnerData($this->getId(), $owner, $uniqueUser); - $repo->setInferOptionsFromParent(true); - return $repo; - } - /** - * Recompute uuid - * @return bool - */ - function upgradeId(){ - if(!isSet($this->uuid)) { - $this->uuid = md5(serialize($this)); - //$this->uuid = md5(time()); - return true; - } - return false; - } - /** - * Get a uuid - * @param bool $serial - * @return string - */ - function getUniqueId($serial=false){ - if($serial){ - return md5(serialize($this)); - } - return $this->uuid; - } - /** - * Alias for this repository - * @return string - */ - function getSlug(){ - return $this->slug; - } - /** - * Use the slugify function to generate an alias from the label - * @param string $slug - * @return void - */ - function setSlug($slug = null){ - if($slug == null){ - $this->slug = AJXP_Utils::slugify($this->display); - }else{ - $this->slug = $slug; - } - } - /** - * Get the content of the manifest.xml - * @return DOMElement|DOMNodeList|string - */ - function getClientSettings(){ - $plugin = AJXP_PluginsService::findPlugin("access", $this->accessType); - if(!$plugin) return ""; - if(isSet($this->parentId)){ - $parentObject = ConfService::getRepositoryById($this->parentId); - if($parentObject != null && $parentObject->isTemplate){ - $ic = $parentObject->getOption("TPL_ICON_SMALL"); - $settings = $plugin->getManifestRawContent("//client_settings", "node"); - if(!empty($ic) && $settings->length){ - $newAttr = $settings->item(0)->ownerDocument->createAttribute("icon_tpl_id"); - $newAttr->nodeValue = $this->parentId; - $settings->item(0)->appendChild($newAttr); - return $settings->item(0)->ownerDocument->saveXML($settings->item(0)); - } - } - } - return $plugin->getManifestRawContent("//client_settings", "string"); - } - /** - * Find the streamWrapper declared by the access driver - * @param bool $register - * @param array $streams - * @return bool - */ - function detectStreamWrapper($register = false, &$streams=null){ - $plugin = AJXP_PluginsService::findPlugin("access", $this->accessType); - if(!$plugin) return(false); - $streamData = $plugin->detectStreamWrapper($register); - if(!$register && $streamData !== false && is_array($streams)){ - $streams[$this->accessType] = $this->accessType; - } - if($streamData !== false) $this->streamData = $streamData; - return ($streamData !== false); - } - - /** - * Add options - * @param $oName - * @param $oValue - * @return void - */ - function addOption($oName, $oValue){ - if(strpos($oName, "PATH") !== false){ - $oValue = str_replace("\\", "/", $oValue); - } - $this->options[$oName] = $oValue; - } - /** - * Get the repository options, filtered in various maners - * @param string $oName - * @param bool $safe Do not filter - * @return mixed|string - */ - function getOption($oName, $safe=false){ - if(!$safe && $this->inferOptionsFromParent){ - if(!isset($this->parentTemplateObject)){ - $this->parentTemplateObject = ConfService::getRepositoryById($this->parentId); - } - if(isSet($this->parentTemplateObject)){ - $value = $this->parentTemplateObject->getOption($oName, $safe); - if(is_string($value) && strstr($value, "AJXP_ALLOW_SUB_PATH") !== false){ - $val = rtrim(str_replace("AJXP_ALLOW_SUB_PATH", "", $value), "/")."/".$this->options[$oName]; - return AJXP_Utils::securePath($val); - } - } - } - if(isSet($this->options[$oName])){ - $value = $this->options[$oName]; - if(!$safe) $value = AJXP_VarsFilter::filter($value); - return $value; - } - if($this->inferOptionsFromParent){ - if(!isset($this->parentTemplateObject)){ - $this->parentTemplateObject = ConfService::getRepositoryById($this->parentId); - } - if(isSet($this->parentTemplateObject)){ - return $this->parentTemplateObject->getOption($oName, $safe); - } - } - return ""; - } - - function resolveVirtualRoots($path){ - - // Gathered from the current role - $roots = $this->listVirtualRoots(); - if(!count($roots)) return $path; - foreach($roots as $rootKey => $rootValue){ - if(strpos($path, "/".ltrim($rootKey, "/")) === 0){ - return preg_replace("/^\/{$rootKey}/", $rootValue["path"], $path, 1); - } - } - return $path; - - } - - function listVirtualRoots(){ - - return array(); - /* TEST STUB - $roots = array( - "root1" => array( - "right" => "rw", - "path" => "/Test"), - "root2" => array( - "right" => "r", - "path" => "/Retoto/sub" - )); - return $roots; - */ - } - - /** - * Get the options that already have a value - * @return array - */ - function getOptionsDefined(){ - //return array_keys($this->options); - $keys = array(); - foreach($this->options as $key => $value){ - if(is_string($value) && strstr($value, "AJXP_ALLOW_SUB_PATH") !== false) continue; - $keys[] = $key; - } - return $keys; - } - - /** - * Get the DEFAULT_RIGHTS option - * @return string - */ - function getDefaultRight(){ - $opt = $this->getOption("DEFAULT_RIGHTS"); - return (isSet($opt)?$opt:""); - } - - - /** - * The the access driver type - * @return String - */ - function getAccessType() { - return $this->accessType; - } - - /** - * The label of this repository - * @return String - */ - function getDisplay() { - if(isSet($this->displayStringId)){ - $mess = ConfService::getMessages(); - if(isSet($mess[$this->displayStringId])){ - return SystemTextEncoding::fromUTF8($mess[$this->displayStringId]); - } - } - return $this->display; - } - - /** - * @return string - */ - function getId() { - if($this->isWriteable()) return $this->getUniqueId(); - return $this->id; - } - - /** - * @return boolean - */ - function getCreate() { - return $this->getOption("CREATE"); - } - - /** - * @param boolean $create - */ - function setCreate($create) { - $this->options["CREATE"] = $create; - } - - - /** - * @param String $accessType - */ - function setAccessType($accessType) { - $this->accessType = $accessType; - } - - /** - * @param String $display - */ - function setDisplay($display) { - $this->display = $display; - } - - /** - * @param int $id - */ - function setId($id) { - $this->id = $id; - } - - function isWriteable(){ - return $this->writeable; - } - - function setWriteable($w){ - $this->writeable = $w; - } - - function isEnabled(){ - return $this->enabled; - } - - function setEnabled($e){ - $this->enabled = $e; - } - - function setDisplayStringId($id){ - $this->displayStringId = $id; - } - - function setOwnerData($repoParentId, $ownerUserId = null, $childUserId = null){ - $this->owner = $ownerUserId; - $this->uniqueUser = $childUserId; - $this->parentId = $repoParentId; - } - - function getOwner(){ - return $this->owner; - } - - function getParentId(){ - return $this->parentId; - } - - function getUniqueUser(){ - return $this->uniqueUser; - } - - function hasOwner(){ - return isSet($this->owner); - } - - function hasParent(){ - return isSet($this->parentId); - } - - function setInferOptionsFromParent($bool){ - $this->inferOptionsFromParent = $bool; - } - - function getInferOptionsFromParent(){ - return $this->inferOptionsFromParent; - } - - /** - * @param String $groupPath - */ - public function setGroupPath($groupPath) - { - if(strlen($groupPath) > 1) $groupPath = rtrim($groupPath, "/"); - $this->groupPath = $groupPath; - } - - /** - * @return String - */ - public function getGroupPath() - { - return $this->groupPath; - } - - /** - * @param String $descriptionText - */ - public function setDescription( $descriptionText ){ - $this->options["USER_DESCRIPTION"] = $descriptionText; - } - - /** - * @return String - */ - public function getDescription (){ - $m = ConfService::getMessages(); - if(isset($this->options["USER_DESCRIPTION"]) && !empty($this->options["USER_DESCRIPTION"])){ - if(isSet($m[$this->options["USER_DESCRIPTION"]])) { - return $m[$this->options["USER_DESCRIPTION"]]; - } else { - return $this->options["USER_DESCRIPTION"]; - } - }if(isSet($this->parentId) && isset($this->owner)){ - if(isSet($this->options["CREATION_TIME"])){ - $date = AJXP_Utils::relativeDate($this->options["CREATION_TIME"], $m); - return str_replace(array("%date", "%user"), array($date, $this->owner), $m["473"]); - }else{ - return str_replace(array("%user"), array($this->owner), $m["472"]); - } - }else if($this->isWriteable() && isSet($this->options["CREATION_TIME"])){ - $date = AJXP_Utils::relativeDate($this->options["CREATION_TIME"], $m); - if(isSet($this->options["CREATION_USER"])){ - return str_replace(array("%date", "%user"), array($date, $this->options["CREATION_USER"]), $m["471"]); - }else{ - return str_replace(array("%date"), array($date), $m["470"]); - } - }else{ - return $m["474"]; - } - } - - /** - * Infer a security scope for this repository. Will determine to whome the messages - * will be broadcasted. - * @return bool|string - */ - public function securityScope(){ - $path = $this->getOption("PATH", true); - if($this->accessType == "ajxp_conf") return "USER"; - if(empty($path)) return false; - if(strpos($path, "AJXP_USER") !== false) return "USER"; - if(strpos($path, "AJXP_GROUP_PATH") !== false) return "GROUP"; - if(strpos($path, "AJXP_GROUP_PATH_FLAT") !== false) return "GROUP"; - return false; - } - -} \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); +/** + * The basic abstraction of a data store. Can map a FileSystem, but can also map data from a totally + * different source, like the application configurations, a mailbox, etc. + * @package AjaXplorer + * @subpackage Core + */ +class Repository implements AjxpGroupPathProvider +{ + /** + * @var string + */ + public $uuid; + /** + * @var string + */ + public $id; + /** + * @var string + */ + public $path; + /** + * @var string + */ + public $display; + /** + * @var string + */ + public $displayStringId; + /** + * @var string + */ + public $accessType = "fs"; + /** + * @var string + */ + public $recycle = ""; + /** + * @var bool + */ + public $create = true; + /** + * @var bool + */ + public $writeable = true; + /** + * @var bool + */ + public $enabled = true; + /** + * @var array + */ + public $options = array(); + /** + * @var string + */ + public $slug; + /** + * @var bool + */ + public $isTemplate = false; + + /** + * @var string + */ + private $owner; + /** + * @var string + */ + private $parentId; + /** + * @var string + */ + private $uniqueUser; + /** + * @var bool + */ + private $inferOptionsFromParent; + /** + * @var Repository + */ + private $parentTemplateObject; + /** + * @var array + */ + public $streamData; + + /** + * @var String the groupPath of the administrator who created that repository. + */ + protected $groupPath; + + + public $driverInstance; + + /** + * @param string $id + * @param string $display + * @param string $driver + * @return void + */ + public function Repository($id, $display, $driver) + { + $this->setAccessType($driver); + $this->setDisplay($display); + $this->setId($id); + $this->uuid = md5(microtime()); + $this->slug = AJXP_Utils::slugify($display); + $this->inferOptionsFromParent = false; + $this->options["CREATION_TIME"] = time(); + if (AuthService::usersEnabled() && AuthService::getLoggedUser() != null) { + $this->options["CREATION_USER"] = AuthService::getLoggedUser()->getId(); + } + } + + /** + * Create a shared version of this repository + * @param string $newLabel + * @param array $newOptions + * @param string $parentId + * @param string $owner + * @param string $uniqueUser + * @return Repository + */ + public function createSharedChild($newLabel, $newOptions, $parentId = null, $owner = null, $uniqueUser = null) + { + $repo = new Repository(0, $newLabel, $this->accessType); + $newOptions = array_merge($this->options, $newOptions); + $repo->options = $newOptions; + if ($parentId == null) { + $parentId = $this->getId(); + } + $repo->setOwnerData($parentId, $owner, $uniqueUser); + return $repo; + } + /** + * Create a child from this repository if it's a template + * @param string $newLabel + * @param array $newOptions + * @param string $owner + * @param string $uniqueUser + * @return Repository + */ + public function createTemplateChild($newLabel, $newOptions, $owner = null, $uniqueUser = null) + { + $repo = new Repository(0, $newLabel, $this->accessType); + $repo->options = $newOptions; + $repo->setOwnerData($this->getId(), $owner, $uniqueUser); + $repo->setInferOptionsFromParent(true); + return $repo; + } + /** + * Recompute uuid + * @return bool + */ + public function upgradeId() + { + if (!isSet($this->uuid)) { + $this->uuid = md5(serialize($this)); + //$this->uuid = md5(time()); + return true; + } + return false; + } + /** + * Get a uuid + * @param bool $serial + * @return string + */ + public function getUniqueId($serial=false) + { + if ($serial) { + return md5(serialize($this)); + } + return $this->uuid; + } + /** + * Alias for this repository + * @return string + */ + public function getSlug() + { + return $this->slug; + } + /** + * Use the slugify function to generate an alias from the label + * @param string $slug + * @return void + */ + public function setSlug($slug = null) + { + if ($slug == null) { + $this->slug = AJXP_Utils::slugify($this->display); + } else { + $this->slug = $slug; + } + } + /** + * Get the content of the manifest.xml + * @return DOMElement|DOMNodeList|string + */ + public function getClientSettings() + { + $plugin = AJXP_PluginsService::findPlugin("access", $this->accessType); + if(!$plugin) return ""; + if (isSet($this->parentId)) { + $parentObject = ConfService::getRepositoryById($this->parentId); + if ($parentObject != null && $parentObject->isTemplate) { + $ic = $parentObject->getOption("TPL_ICON_SMALL"); + $settings = $plugin->getManifestRawContent("//client_settings", "node"); + if (!empty($ic) && $settings->length) { + $newAttr = $settings->item(0)->ownerDocument->createAttribute("icon_tpl_id"); + $newAttr->nodeValue = $this->parentId; + $settings->item(0)->appendChild($newAttr); + return $settings->item(0)->ownerDocument->saveXML($settings->item(0)); + } + } + } + return $plugin->getManifestRawContent("//client_settings", "string"); + } + /** + * Find the streamWrapper declared by the access driver + * @param bool $register + * @param array $streams + * @return bool + */ + public function detectStreamWrapper($register = false, &$streams=null) + { + $plugin = AJXP_PluginsService::findPlugin("access", $this->accessType); + if(!$plugin) return(false); + $streamData = $plugin->detectStreamWrapper($register); + if (!$register && $streamData !== false && is_array($streams)) { + $streams[$this->accessType] = $this->accessType; + } + if($streamData !== false) $this->streamData = $streamData; + return ($streamData !== false); + } + + /** + * Add options + * @param $oName + * @param $oValue + * @return void + */ + public function addOption($oName, $oValue) + { + if (strpos($oName, "PATH") !== false) { + $oValue = str_replace("\\", "/", $oValue); + } + $this->options[$oName] = $oValue; + } + /** + * Get the repository options, filtered in various maners + * @param string $oName + * @param bool $safe Do not filter + * @return mixed|string + */ + public function getOption($oName, $safe=false) + { + if (!$safe && $this->inferOptionsFromParent) { + if (!isset($this->parentTemplateObject)) { + $this->parentTemplateObject = ConfService::getRepositoryById($this->parentId); + } + if (isSet($this->parentTemplateObject)) { + $value = $this->parentTemplateObject->getOption($oName, $safe); + if (is_string($value) && strstr($value, "AJXP_ALLOW_SUB_PATH") !== false) { + $val = rtrim(str_replace("AJXP_ALLOW_SUB_PATH", "", $value), "/")."/".$this->options[$oName]; + return AJXP_Utils::securePath($val); + } + } + } + if (isSet($this->options[$oName])) { + $value = $this->options[$oName]; + if(!$safe) $value = AJXP_VarsFilter::filter($value); + return $value; + } + if ($this->inferOptionsFromParent) { + if (!isset($this->parentTemplateObject)) { + $this->parentTemplateObject = ConfService::getRepositoryById($this->parentId); + } + if (isSet($this->parentTemplateObject)) { + return $this->parentTemplateObject->getOption($oName, $safe); + } + } + return ""; + } + + public function resolveVirtualRoots($path) + { + // Gathered from the current role + $roots = $this->listVirtualRoots(); + if(!count($roots)) return $path; + foreach ($roots as $rootKey => $rootValue) { + if (strpos($path, "/".ltrim($rootKey, "/")) === 0) { + return preg_replace("/^\/{$rootKey}/", $rootValue["path"], $path, 1); + } + } + return $path; + + } + + public function listVirtualRoots() + { + return array(); + /* TEST STUB + $roots = array( + "root1" => array( + "right" => "rw", + "path" => "/Test"), + "root2" => array( + "right" => "r", + "path" => "/Retoto/sub" + )); + return $roots; + */ + } + + /** + * Get the options that already have a value + * @return array + */ + public function getOptionsDefined() + { + //return array_keys($this->options); + $keys = array(); + foreach ($this->options as $key => $value) { + if(is_string($value) && strstr($value, "AJXP_ALLOW_SUB_PATH") !== false) continue; + $keys[] = $key; + } + return $keys; + } + + /** + * Get the DEFAULT_RIGHTS option + * @return string + */ + public function getDefaultRight() + { + $opt = $this->getOption("DEFAULT_RIGHTS"); + return (isSet($opt)?$opt:""); + } + + + /** + * The the access driver type + * @return String + */ + public function getAccessType() + { + return $this->accessType; + } + + /** + * The label of this repository + * @return String + */ + public function getDisplay() + { + if (isSet($this->displayStringId)) { + $mess = ConfService::getMessages(); + if (isSet($mess[$this->displayStringId])) { + return SystemTextEncoding::fromUTF8($mess[$this->displayStringId]); + } + } + return $this->display; + } + + /** + * @return string + */ + public function getId() + { + if($this->isWriteable()) return $this->getUniqueId(); + return $this->id; + } + + /** + * @return boolean + */ + public function getCreate() + { + return $this->getOption("CREATE"); + } + + /** + * @param boolean $create + */ + public function setCreate($create) + { + $this->options["CREATE"] = $create; + } + + + /** + * @param String $accessType + */ + public function setAccessType($accessType) + { + $this->accessType = $accessType; + } + + /** + * @param String $display + */ + public function setDisplay($display) + { + $this->display = $display; + } + + /** + * @param int $id + */ + public function setId($id) + { + $this->id = $id; + } + + public function isWriteable() + { + return $this->writeable; + } + + public function setWriteable($w) + { + $this->writeable = $w; + } + + public function isEnabled() + { + return $this->enabled; + } + + public function setEnabled($e) + { + $this->enabled = $e; + } + + public function setDisplayStringId($id) + { + $this->displayStringId = $id; + } + + public function setOwnerData($repoParentId, $ownerUserId = null, $childUserId = null) + { + $this->owner = $ownerUserId; + $this->uniqueUser = $childUserId; + $this->parentId = $repoParentId; + } + + public function getOwner() + { + return $this->owner; + } + + public function getParentId() + { + return $this->parentId; + } + + public function getUniqueUser() + { + return $this->uniqueUser; + } + + public function hasOwner() + { + return isSet($this->owner); + } + + public function hasParent() + { + return isSet($this->parentId); + } + + public function setInferOptionsFromParent($bool) + { + $this->inferOptionsFromParent = $bool; + } + + public function getInferOptionsFromParent() + { + return $this->inferOptionsFromParent; + } + + /** + * @param String $groupPath + */ + public function setGroupPath($groupPath) + { + if(strlen($groupPath) > 1) $groupPath = rtrim($groupPath, "/"); + $this->groupPath = $groupPath; + } + + /** + * @return String + */ + public function getGroupPath() + { + return $this->groupPath; + } + + /** + * @param String $descriptionText + */ + public function setDescription( $descriptionText ) + { + $this->options["USER_DESCRIPTION"] = $descriptionText; + } + + /** + * @return String + */ + public function getDescription () + { + $m = ConfService::getMessages(); + if (isset($this->options["USER_DESCRIPTION"]) && !empty($this->options["USER_DESCRIPTION"])) { + if (isSet($m[$this->options["USER_DESCRIPTION"]])) { + return $m[$this->options["USER_DESCRIPTION"]]; + } else { + return $this->options["USER_DESCRIPTION"]; + } + }if (isSet($this->parentId) && isset($this->owner)) { + if (isSet($this->options["CREATION_TIME"])) { + $date = AJXP_Utils::relativeDate($this->options["CREATION_TIME"], $m); + return str_replace(array("%date", "%user"), array($date, $this->owner), $m["473"]); + } else { + return str_replace(array("%user"), array($this->owner), $m["472"]); + } + } else if ($this->isWriteable() && isSet($this->options["CREATION_TIME"])) { + $date = AJXP_Utils::relativeDate($this->options["CREATION_TIME"], $m); + if (isSet($this->options["CREATION_USER"])) { + return str_replace(array("%date", "%user"), array($date, $this->options["CREATION_USER"]), $m["471"]); + } else { + return str_replace(array("%date"), array($date), $m["470"]); + } + } else { + return $m["474"]; + } + } + + /** + * Infer a security scope for this repository. Will determine to whome the messages + * will be broadcasted. + * @return bool|string + */ + public function securityScope() + { + $path = $this->getOption("PATH", true); + if($this->accessType == "ajxp_conf") return "USER"; + if(empty($path)) return false; + if(strpos($path, "AJXP_USER") !== false) return "USER"; + if(strpos($path, "AJXP_GROUP_PATH") !== false) return "GROUP"; + if(strpos($path, "AJXP_GROUP_PATH_FLAT") !== false) return "GROUP"; + return false; + } + +} diff --git a/core/src/core/classes/class.SystemTextEncoding.php b/core/src/core/classes/class.SystemTextEncoding.php index e962b4da4b..c620f168ac 100644 --- a/core/src/core/classes/class.SystemTextEncoding.php +++ b/core/src/core/classes/class.SystemTextEncoding.php @@ -34,90 +34,88 @@ class SystemTextEncoding * @param string $text * @return string */ - static function changeCharset($inputCharset, $outputCharset, $text) - { - if ($inputCharset == $outputCharset) return $text; - // Due to iconv bug when dealing with text with non ASCII encoding for last char, we use this workaround http://fr.php.net/manual/fr/function.iconv.php#81494 - if(function_exists("iconv")) - { - - return iconv($inputCharset, $outputCharset, $text); - }else - { - $content = @htmlentities($text, ENT_QUOTES, $inputCharset); - return @html_entity_decode($content, ENT_QUOTES , $outputCharset); - } - } + public static function changeCharset($inputCharset, $outputCharset, $text) + { + if ($inputCharset == $outputCharset) return $text; + // Due to iconv bug when dealing with text with non ASCII encoding for last char, we use this workaround http://fr.php.net/manual/fr/function.iconv.php#81494 + if (function_exists("iconv")) { + + return iconv($inputCharset, $outputCharset, $text); + } else { + $content = @htmlentities($text, ENT_QUOTES, $inputCharset); + return @html_entity_decode($content, ENT_QUOTES , $outputCharset); + } + } - static $currentCharsetValue; - /** + public static $currentCharsetValue; + /** * Detect the current charset from the current locale * @static * @param string $locale * @return string */ - static function parseCharset($locale) - { - $test = explode("@", $locale); - $locale = $test[0]; - $encoding = substr(strrchr($locale, "."), 1); - if (is_numeric($encoding)) - { - if (substr($encoding, 0, 2) == "12") // CP12xx are changed to Windows-12xx to allow PHP4 conversion - $encoding = "windows-".$encoding; - else $encoding = "CP".$encoding; // In other cases, PHP4 won't work anyway, so use CPxxxx encoding (that iconv supports) - } else if ($locale == "C") - { // Locale not set correctly, most probable error cause is /etc/init.d/apache having "LANG=C" defined - // In any case, "C" is ASCII-7 bit so it's safe to use the extra bit as if it was UTF-8 - $encoding = "UTF-8"; - } - if (!strlen($encoding)) $encoding = "UTF-8"; - return $encoding; - } + public static function parseCharset($locale) + { + $test = explode("@", $locale); + $locale = $test[0]; + $encoding = substr(strrchr($locale, "."), 1); + if (is_numeric($encoding)) { + if (substr($encoding, 0, 2) == "12") // CP12xx are changed to Windows-12xx to allow PHP4 conversion + $encoding = "windows-".$encoding; + else $encoding = "CP".$encoding; // In other cases, PHP4 won't work anyway, so use CPxxxx encoding (that iconv supports) + } else if ($locale == "C") { // Locale not set correctly, most probable error cause is /etc/init.d/apache having "LANG=C" defined + // In any case, "C" is ASCII-7 bit so it's safe to use the extra bit as if it was UTF-8 + $encoding = "UTF-8"; + } + if (!strlen($encoding)) $encoding = "UTF-8"; + return $encoding; + } /** * Try to detect the current encoding (cached in session) * @static * @return string */ - static function getEncoding(){ - if(self::$currentCharsetValue == null){ + public static function getEncoding() + { + if (self::$currentCharsetValue == null) { global $_SESSION; if (isset($_SESSION["AJXP_CHARSET"]) && strlen($_SESSION["AJXP_CHARSET"])) { - // Check if the session get an assigned charset encoding (it's the case for remote SSH for example) + // Check if the session get an assigned charset encoding (it's the case for remote SSH for example) self::$currentCharsetValue = $_SESSION["AJXP_CHARSET"]; - }else{ - // Get the current locale (expecting the filesystem is in the same locale, as the standard says) + } else { + // Get the current locale (expecting the filesystem is in the same locale, as the standard says) self::$currentCharsetValue = self::parseCharset(setlocale(LC_CTYPE, 0)); } } - return self::$currentCharsetValue; - } - /** + return self::$currentCharsetValue; + } + /** * Decode a string from UTF8 to current Charset * @static * @param string $filesystemElement * @param bool $test Try to detect if it's really utf8 or not * @return string */ - static function fromUTF8($filesystemElement, $test = false){ - if($test && !SystemTextEncoding::isUtf8($filesystemElement)){ - return $filesystemElement; - } - $enc = SystemTextEncoding::getEncoding(); - return SystemTextEncoding::changeCharset("UTF-8", $enc, $filesystemElement); - } - - /** + public static function fromUTF8($filesystemElement, $test = false) + { + if ($test && !SystemTextEncoding::isUtf8($filesystemElement)) { + return $filesystemElement; + } + $enc = SystemTextEncoding::getEncoding(); + return SystemTextEncoding::changeCharset("UTF-8", $enc, $filesystemElement); + } + + /** * This function is used when the server's PHP configuration is using magic quote * @param string $text * @return string */ - static function magicDequote($text) + public static function magicDequote($text) { - // If the PHP server enables magic quotes, remove them - if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) - return stripslashes($text); - return $text; + // If the PHP server enables magic quotes, remove them + if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) + return stripslashes($text); + return $text; } /** @@ -126,42 +124,42 @@ static function magicDequote($text) * @param string $filesystemElement * @return string */ - static function fromPostedFileName($filesystemElement) + public static function fromPostedFileName($filesystemElement) { - return SystemTextEncoding::fromUTF8(SystemTextEncoding::magicDequote($filesystemElement)); - } - /** + return SystemTextEncoding::fromUTF8(SystemTextEncoding::magicDequote($filesystemElement)); + } + /** * Transform a string from current charset to utf8 * @static * @param string $filesystemElement * @param bool $test Test if it's already UTF8 or not, to avoid double-encoding * @return string */ - static function toUTF8($filesystemElement, $test = true){ - if($test && SystemTextEncoding::isUtf8($filesystemElement)){ - return $filesystemElement; - } - $enc = SystemTextEncoding::getEncoding(); - return SystemTextEncoding::changeCharset($enc, "UTF-8", $filesystemElement); - } - /** + public static function toUTF8($filesystemElement, $test = true) + { + if ($test && SystemTextEncoding::isUtf8($filesystemElement)) { + return $filesystemElement; + } + $enc = SystemTextEncoding::getEncoding(); + return SystemTextEncoding::changeCharset($enc, "UTF-8", $filesystemElement); + } + /** * Test if a string seem to be already UTF8-encoded * @static * @param string $string * @return bool */ - static function isUtf8($string){ - return preg_match('%^(?: - [\x09\x0A\x0D\x20-\x7E] # ASCII - | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte - | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs - | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte - | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates - | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 - | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 - | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 - )*$%xs', $string); + public static function isUtf8($string) + { + return preg_match('%^(?: + [\x09\x0A\x0D\x20-\x7E] # ASCII + | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 + )*$%xs', $string); } } - -?> diff --git a/core/src/core/classes/class.UnixProcess.php b/core/src/core/classes/class.UnixProcess.php index 6a45125165..dce87af94c 100644 --- a/core/src/core/classes/class.UnixProcess.php +++ b/core/src/core/classes/class.UnixProcess.php @@ -1,112 +1,119 @@ -, Cyril Russo - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); -/** - * Utilitary to launch a process and keep track of it - * @package AjaXplorer - * @subpackage Core - */ -class UnixProcess{ - /** - * @var string - */ - private $pid; - /** - * @var string - */ - private $command; - /** - * @var string - */ - private $output; - - /** - * @param bool|string $cl Command to execute - * @param bool|string $output A file in which to redirect the output. Send to /dev/null if false. - */ - public function __construct($cl=false, $output=false){ - if($output != false) { - $this->output = $output; - }else { - $this->output = "/dev/null"; - } - if ($cl != false){ - $this->command = $cl; - $this->runCom(); - } - } - /** - * Run the command - * @return void - */ - private function runCom(){ - $command = $this->command.' > '.$this->output.' 2>&1 & echo $!'; - exec($command ,$op); - $this->pid = (int)$op[0]; - $this->command = $command; - } - /** - * Processid setter - * @param $pid - * @return void - */ - public function setPid($pid){ - $this->pid = $pid; - } - - /** - * Processid getter - * @return string - */ - public function getPid(){ - return $this->pid; - } - - /** - * Try to get status from command line by running "ps -p PID" - * @return bool - */ - public function status(){ - $command = 'ps -p '.$this->pid; - exec($command,$op); - if (!isset($op[1]))return false; - else return true; - } - /** - * Start the command - * @return bool - */ - public function start(){ - if ($this->command != '')$this->runCom(); - else return true; - } - /** - * Try to kill the process via command line. - * @return bool - */ - public function stop(){ - $command = 'kill '.$this->pid; - exec($command); - if ($this->status() == false)return true; - else return false; - } -} -?> \ No newline at end of file +, Cyril Russo + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); +/** + * Utilitary to launch a process and keep track of it + * @package AjaXplorer + * @subpackage Core + */ +class UnixProcess +{ + /** + * @var string + */ + private $pid; + /** + * @var string + */ + private $command; + /** + * @var string + */ + private $output; + + /** + * @param bool|string $cl Command to execute + * @param bool|string $output A file in which to redirect the output. Send to /dev/null if false. + */ + public function __construct($cl=false, $output=false) + { + if ($output != false) { + $this->output = $output; + } else { + $this->output = "/dev/null"; + } + if ($cl != false) { + $this->command = $cl; + $this->runCom(); + } + } + /** + * Run the command + * @return void + */ + private function runCom() + { + $command = $this->command.' > '.$this->output.' 2>&1 & echo $!'; + exec($command ,$op); + $this->pid = (int) $op[0]; + $this->command = $command; + } + /** + * Processid setter + * @param $pid + * @return void + */ + public function setPid($pid) + { + $this->pid = $pid; + } + + /** + * Processid getter + * @return string + */ + public function getPid() + { + return $this->pid; + } + + /** + * Try to get status from command line by running "ps -p PID" + * @return bool + */ + public function status() + { + $command = 'ps -p '.$this->pid; + exec($command,$op); + if (!isset($op[1]))return false; + else return true; + } + /** + * Start the command + * @return bool + */ + public function start() + { + if ($this->command != '')$this->runCom(); + else return true; + } + /** + * Try to kill the process via command line. + * @return bool + */ + public function stop() + { + $command = 'kill '.$this->pid; + exec($command); + if ($this->status() == false)return true; + else return false; + } +} diff --git a/core/src/core/classes/class.UserSelection.php b/core/src/core/classes/class.UserSelection.php index ca848003f9..f7bd6f2616 100644 --- a/core/src/core/classes/class.UserSelection.php +++ b/core/src/core/classes/class.UserSelection.php @@ -1,236 +1,233 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); -/** - * Abstraction of a user selection passed via http parameters. - * @package AjaXplorer - * @subpackage Core - */ -class UserSelection -{ - var $files; - var $varPrefix = "file"; - var $dirPrefix = "dir"; - var $isUnique = true; - var $dir; - - var $inZip = false; - var $zipFile; - var $localZipPath; - /** - * Construction selector - */ - function UserSelection() - { - $this->files = array(); - } - /** - * Init the selection from the query vars - * @param array $passedArray - * @return void - */ - function initFromHttpVars($passedArray=null) - { - if($passedArray != null){ - $this->initFromArray($passedArray); - }else{ - $this->initFromArray($_GET); - $this->initFromArray($_POST); - } - } - /** - * Init from a simple array - * @param $array - * @return - */ - function initFromArray($array) - { - if(!is_array($array)) - { - return ; - } - if(isSet($array[$this->varPrefix]) && $array[$this->varPrefix] != "") - { - $this->files[] = AJXP_Utils::decodeSecureMagic($array[$this->varPrefix]); - $this->isUnique = true; - //return ; - } - if(isSet($array[$this->varPrefix."_0"])) - { - $index = 0; - while(isSet($array[$this->varPrefix."_".$index])) - { - $this->files[] = AJXP_Utils::decodeSecureMagic($array[$this->varPrefix."_".$index]); - $index ++; - } - $this->isUnique = false; - if(count($this->files) == 1) - { - $this->isUnique = true; - } - //return ; - } - if(isSet($array[$this->dirPrefix])){ - $this->dir = AJXP_Utils::securePath($array[$this->dirPrefix]); - if($test = $this->detectZip($this->dir)){ - $this->inZip = true; - $this->zipFile = $test[0]; - $this->localZipPath = $test[1]; - } - } - } - /** - * Does the selection have one or more items - * @return bool - */ - function isUnique() - { - return $this->isUnique; - } - /** - * Are we currently inside a zip? - * @return bool - */ - function inZip(){ - return $this->inZip; - } - /** - * Returns UTF8 encoded path - * @param bool $decode - * @return String - */ - function getZipPath($decode = false){ - if($decode) return AJXP_Utils::decodeSecureMagic($this->zipFile); - else return $this->zipFile; - } - - /** - * Returns UTF8 encoded path - * @param bool $decode - * @return String - */ - function getZipLocalPath($decode = false){ - if($decode) return AJXP_Utils::decodeSecureMagic($this->localZipPath); - else return $this->localZipPath; - } - /** - * Number of selected items - * @return int - */ - function getCount() - { - return count($this->files); - } - /** - * List of items selected - * @return string[] - */ - function getFiles() - { - return $this->files; - } - /** - * First item of the list - * @return string - */ - function getUniqueFile() - { - return $this->files[0]; - } - - /** - * @param AbstractAccessDriver $accessDriver - * @return AJXP_Node - * @throws Exception - */ - function getUniqueNode(AbstractAccessDriver $accessDriver){ - - $repo = $accessDriver->repository; - $user = AuthService::getLoggedUser(); - if(!AuthService::usersEnabled() && $user!=null && !$user->canWrite($repo->getId())){ - throw new Exception("You have no right on this action."); - } - - $currentFile = $this->getUniqueFile(); - $wrapperData = $accessDriver->detectStreamWrapper(false); - $urlBase = $wrapperData["protocol"]."://".$accessDriver->repository->getId(); - $ajxpNode = new AJXP_Node($urlBase.$currentFile); - return $ajxpNode; - - } - - /** - * @param AbstractAccessDriver $accessDriver - * @return AJXP_Node[] - * @throws Exception - */ - function buildNodes(AbstractAccessDriver $accessDriver){ - - $wrapperData = $accessDriver->detectStreamWrapper(false); - $urlBase = $wrapperData["protocol"]."://".$accessDriver->repository->getId(); - $nodes = array(); - foreach($this->files as $file){ - $nodes[] = new AJXP_Node($urlBase.$file); - } - return $nodes; - - } - - /** - * Is this selection empty? - * @return bool - */ - function isEmpty() - { - if(count($this->files) == 0) - { - return true; - } - return false; - } - /** - * Detect if there is .zip somewhere in the path - * @static - * @param string $dirPath - * @return array|bool - */ - static function detectZip($dirPath){ - if(preg_match("/\.zip\//i", $dirPath) || preg_match("/\.zip$/i", $dirPath)){ - $contExt = strpos(strtolower($dirPath), ".zip"); - $zipPath = substr($dirPath, 0, $contExt+4); - $localPath = substr($dirPath, $contExt+4); - if($localPath == "") $localPath = "/"; - return array($zipPath, $localPath); - } - return false; - } - /** - * Sets the selected items - * @param array $files - * @return void - */ - function setFiles($files){ - $this->files = $files; - } - -} - -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); +/** + * Abstraction of a user selection passed via http parameters. + * @package AjaXplorer + * @subpackage Core + */ +class UserSelection +{ + public $files; + public $varPrefix = "file"; + public $dirPrefix = "dir"; + public $isUnique = true; + public $dir; + + public $inZip = false; + public $zipFile; + public $localZipPath; + /** + * Construction selector + */ + public function UserSelection() + { + $this->files = array(); + } + /** + * Init the selection from the query vars + * @param array $passedArray + * @return void + */ + public function initFromHttpVars($passedArray=null) + { + if ($passedArray != null) { + $this->initFromArray($passedArray); + } else { + $this->initFromArray($_GET); + $this->initFromArray($_POST); + } + } + /** + * Init from a simple array + * @param $array + * @return + */ + public function initFromArray($array) + { + if (!is_array($array)) { + return ; + } + if (isSet($array[$this->varPrefix]) && $array[$this->varPrefix] != "") { + $this->files[] = AJXP_Utils::decodeSecureMagic($array[$this->varPrefix]); + $this->isUnique = true; + //return ; + } + if (isSet($array[$this->varPrefix."_0"])) { + $index = 0; + while (isSet($array[$this->varPrefix."_".$index])) { + $this->files[] = AJXP_Utils::decodeSecureMagic($array[$this->varPrefix."_".$index]); + $index ++; + } + $this->isUnique = false; + if (count($this->files) == 1) { + $this->isUnique = true; + } + //return ; + } + if (isSet($array[$this->dirPrefix])) { + $this->dir = AJXP_Utils::securePath($array[$this->dirPrefix]); + if ($test = $this->detectZip($this->dir)) { + $this->inZip = true; + $this->zipFile = $test[0]; + $this->localZipPath = $test[1]; + } + } + } + /** + * Does the selection have one or more items + * @return bool + */ + public function isUnique() + { + return $this->isUnique; + } + /** + * Are we currently inside a zip? + * @return bool + */ + public function inZip() + { + return $this->inZip; + } + /** + * Returns UTF8 encoded path + * @param bool $decode + * @return String + */ + public function getZipPath($decode = false) + { + if($decode) return AJXP_Utils::decodeSecureMagic($this->zipFile); + else return $this->zipFile; + } + + /** + * Returns UTF8 encoded path + * @param bool $decode + * @return String + */ + public function getZipLocalPath($decode = false) + { + if($decode) return AJXP_Utils::decodeSecureMagic($this->localZipPath); + else return $this->localZipPath; + } + /** + * Number of selected items + * @return int + */ + public function getCount() + { + return count($this->files); + } + /** + * List of items selected + * @return string[] + */ + public function getFiles() + { + return $this->files; + } + /** + * First item of the list + * @return string + */ + public function getUniqueFile() + { + return $this->files[0]; + } + + /** + * @param AbstractAccessDriver $accessDriver + * @return AJXP_Node + * @throws Exception + */ + public function getUniqueNode(AbstractAccessDriver $accessDriver) + { + $repo = $accessDriver->repository; + $user = AuthService::getLoggedUser(); + if (!AuthService::usersEnabled() && $user!=null && !$user->canWrite($repo->getId())) { + throw new Exception("You have no right on this action."); + } + + $currentFile = $this->getUniqueFile(); + $wrapperData = $accessDriver->detectStreamWrapper(false); + $urlBase = $wrapperData["protocol"]."://".$accessDriver->repository->getId(); + $ajxpNode = new AJXP_Node($urlBase.$currentFile); + return $ajxpNode; + + } + + /** + * @param AbstractAccessDriver $accessDriver + * @return AJXP_Node[] + * @throws Exception + */ + public function buildNodes(AbstractAccessDriver $accessDriver) + { + $wrapperData = $accessDriver->detectStreamWrapper(false); + $urlBase = $wrapperData["protocol"]."://".$accessDriver->repository->getId(); + $nodes = array(); + foreach ($this->files as $file) { + $nodes[] = new AJXP_Node($urlBase.$file); + } + return $nodes; + + } + + /** + * Is this selection empty? + * @return bool + */ + public function isEmpty() + { + if (count($this->files) == 0) { + return true; + } + return false; + } + /** + * Detect if there is .zip somewhere in the path + * @static + * @param string $dirPath + * @return array|bool + */ + public static function detectZip($dirPath) + { + if (preg_match("/\.zip\//i", $dirPath) || preg_match("/\.zip$/i", $dirPath)) { + $contExt = strpos(strtolower($dirPath), ".zip"); + $zipPath = substr($dirPath, 0, $contExt+4); + $localPath = substr($dirPath, $contExt+4); + if($localPath == "") $localPath = "/"; + return array($zipPath, $localPath); + } + return false; + } + /** + * Sets the selected items + * @param array $files + * @return void + */ + public function setFiles($files) + { + $this->files = $files; + } + +} diff --git a/core/src/core/classes/compat.php b/core/src/core/classes/compat.php index ec7b67cf90..fb01bca8d5 100644 --- a/core/src/core/classes/compat.php +++ b/core/src/core/classes/compat.php @@ -139,6 +139,4 @@ public function format($format) { return date($format, $this->date); } } -} - -?> \ No newline at end of file +} \ No newline at end of file diff --git a/core/src/core/classes/dibi.compact.php b/core/src/core/classes/dibi.compact.php index 016178833b..d89455fb38 100644 --- a/core/src/core/classes/dibi.compact.php +++ b/core/src/core/classes/dibi.compact.php @@ -9,7 +9,7 @@ * the file license.txt that was distributed with this source code. */ -if(version_compare(PHP_VERSION,'5.2.0','<')){throw +if (version_compare(PHP_VERSION,'5.2.0','<')) {throw new Exception('dibi needs PHP 5.2.0 or newer.');}@set_magic_quotes_runtime(FALSE);interface IDataSource @@ -45,14 +45,14 @@ DibiDateTime extends DateTime{function -__construct($time='now',DateTimeZone$timezone=NULL){if(is_numeric($time)){$time=date('Y-m-d H:i:s',$time);}if($timezone===NULL){parent::__construct($time);}else{parent::__construct($time,$timezone);}}function +__construct($time='now',DateTimeZone$timezone=NULL){if (is_numeric($time)){$time=date('Y-m-d H:i:s',$time);}if ($timezone===NULL) {parent::__construct($time);} else {parent::__construct($time,$timezone);}}function modifyClone($modify=''){$dolly=clone($this);return$modify?$dolly->modify($modify):$dolly;}function modify($modify){parent::modify($modify);return$this;}function __sleep(){$this->fix=array($this->format('Y-m-d H:i:s'),$this->getTimezone()->getName());return array('fix');}function __wakeup(){$this->__construct($this->fix[0],new DateTimeZone($this->fix[1]));unset($this->fix);}function -getTimestamp(){return(int)$this->format('U');}function +getTimestamp(){return(int) $this->format('U');}function setTimestamp($timestamp){return$this->__construct(date('Y-m-d H:i:s',$timestamp),new DateTimeZone($this->getTimezone()->getName()));}function __toString(){return$this->format('Y-m-d H:i:s');}}abstract @@ -66,14 +66,14 @@ function getReflection(){return new ReflectionObject($this);}function -__call($name,$args){$class=get_class($this);if($name===''){throw +__call($name,$args){$class=get_class($this);if ($name==='') {throw new -LogicException("Call to class '$class' method without name.");}if(preg_match('#^on[A-Z]#',$name)){$rp=new -ReflectionProperty($class,$name);if($rp->isPublic()&&!$rp->isStatic()){$list=$this->$name;if(is_array($list)||$list +LogicException("Call to class '$class' method without name.");}if (preg_match('#^on[A-Z]#',$name)) {$rp=new +ReflectionProperty($class,$name);if ($rp->isPublic()&&!$rp->isStatic()) {$list=$this->$name;if(is_array($list)||$list instanceof -Traversable){foreach($list -as$handler){if(is_object($handler)){call_user_func_array(array($handler,'__invoke'),$args);}else{call_user_func_array($handler,$args);}}}return -NULL;}}if($cb=self::extensionMethod("$class::$name")){array_unshift($args,$this);return +Traversable){foreach ($list +as$handler) {if (is_object($handler)) {call_user_func_array(array($handler,'__invoke'),$args);} else {call_user_func_array($handler,$args);}}}return +NULL;}}if ($cb=self::extensionMethod("$class::$name")) {array_unshift($args,$this);return call_user_func_array($cb,$args);}throw new LogicException("Call to undefined method $class::$name().");}static @@ -82,17 +82,17 @@ function new LogicException("Call to undefined static method $class::$name().");}static function -extensionMethod($name,$callback=NULL){if(self::$extMethods===NULL||$name===NULL){$list=get_defined_functions();foreach($list['user']as$fce){$pair=explode('_prototype_',$fce);if(count($pair)===2){self::$extMethods[$pair[1]][$pair[0]]=$fce;self::$extMethods[$pair[1]]['']=NULL;}}if($name===NULL)return -NULL;}$name=strtolower($name);$a=strrpos($name,':');if($a===FALSE){$class=strtolower(get_called_class());$l=&self::$extMethods[$name];}else{$class=substr($name,0,$a-1);$l=&self::$extMethods[substr($name,$a+1)];}if($callback!==NULL){$l[$class]=$callback;$l['']=NULL;return -NULL;}if(empty($l)){return -FALSE;}elseif(isset($l[''][$class])){return$l[''][$class];}$cl=$class;do{$cl=strtolower($cl);if(isset($l[$cl])){return$l[''][$class]=$l[$cl];}}while(($cl=get_parent_class($cl))!==FALSE);foreach(class_implements($class)as$cl){$cl=strtolower($cl);if(isset($l[$cl])){return$l[''][$class]=$l[$cl];}}return$l[''][$class]=FALSE;}function&__get($name){$class=get_class($this);if($name===''){throw +extensionMethod($name,$callback=NULL){if (self::$extMethods===NULL||$name===NULL) {$list=get_defined_functions();foreach ($list['user']as$fce) {$pair=explode('_prototype_',$fce);if(count($pair)===2) {self::$extMethods[$pair[1]][$pair[0]]=$fce;self::$extMethods[$pair[1]]['']=NULL;}}if($name===NULL)return +NULL;}$name=strtolower($name);$a=strrpos($name,':');if ($a===FALSE) {$class=strtolower(get_called_class());$l=&self::$extMethods[$name];} else {$class=substr($name,0,$a-1);$l=&self::$extMethods[substr($name,$a+1)];}if ($callback!==NULL) {$l[$class]=$callback;$l['']=NULL;return +NULL;}if (empty($l)) {return +FALSE;} elseif (isset($l[''][$class])){return$l[''][$class];}$cl=$class;do {$cl=strtolower($cl);if(isset($l[$cl])){return$l[''][$class]=$l[$cl];}} while (($cl=get_parent_class($cl))!==FALSE);foreach(class_implements($class)as$cl){$cl=strtolower($cl);if(isset($l[$cl])){return$l[''][$class]=$l[$cl];}}return$l[''][$class]=FALSE;}function&__get($name){$class=get_class($this);if ($name==='') {throw new -LogicException("Cannot read a class '$class' property without name.");}$name[0]=$name[0]&"\xDF";$m='get'.$name;if(self::hasAccessor($class,$m)){$val=$this->$m();return$val;}$m='is'.$name;if(self::hasAccessor($class,$m)){$val=$this->$m();return$val;}$name=func_get_arg(0);throw +LogicException("Cannot read a class '$class' property without name.");}$name[0]=$name[0]&"\xDF";$m='get'.$name;if (self::hasAccessor($class,$m)){$val=$this->$m();return$val;}$m='is'.$name;if(self::hasAccessor($class,$m)) {$val=$this->$m();return$val;}$name=func_get_arg(0);throw new LogicException("Cannot read an undeclared property $class::\$$name.");}function -__set($name,$value){$class=get_class($this);if($name===''){throw +__set($name,$value){$class=get_class($this);if ($name==='') {throw new -LogicException("Cannot assign to a class '$class' property without name.");}$name[0]=$name[0]&"\xDF";if(self::hasAccessor($class,'get'.$name)||self::hasAccessor($class,'is'.$name)){$m='set'.$name;if(self::hasAccessor($class,$m)){$this->$m($value);return;}else{$name=func_get_arg(0);throw +LogicException("Cannot assign to a class '$class' property without name.");}$name[0]=$name[0]&"\xDF";if (self::hasAccessor($class,'get'.$name)||self::hasAccessor($class,'is'.$name)){$m='set'.$name;if(self::hasAccessor($class,$m)) {$this->$m($value);return;} else {$name=func_get_arg(0);throw new LogicException("Cannot assign to a read-only property $class::\$$name.");}}$name=func_get_arg(0);throw new @@ -103,17 +103,17 @@ function LogicException("Cannot unset the property $class::\$$name.");}private static function -hasAccessor($c,$m){static$cache;if(!isset($cache[$c])){$cache[$c]=array_flip(get_class_methods($c));}return +hasAccessor($c,$m){static$cache;if (!isset($cache[$c])) {$cache[$c]=array_flip(get_class_methods($c));}return isset($cache[$c][$m]);}}class DibiLiteral extends DibiObject{private$value;function -__construct($value){$this->value=(string)$value;}function +__construct($value){$this->value=(string) $value;}function __toString(){return$this->value;}}abstract class DibiHashMapBase{private$callback;function __construct($callback){$this->setCallback($callback);}function -setCallback($callback){if(!is_callable($callback)){$able=is_callable($callback,TRUE,$textual);throw +setCallback($callback){if (!is_callable($callback)) {$able=is_callable($callback,TRUE,$textual);throw new InvalidArgumentException("Handler '$textual' is not ".($able?'callable.':'valid PHP callback.'));}$this->callback=$callback;}function getCallback(){return$this->callback;}}final @@ -121,13 +121,13 @@ class DibiHashMap extends DibiHashMapBase{function -__set($nm,$val){if($nm==''){$nm="\xFF";}$this->$nm=$val;}function -__get($nm){if($nm==''){$nm="\xFF";return -isset($this->$nm)?$this->$nm:$this->$nm=call_user_func($this->getCallback(),'');}else{return$this->$nm=call_user_func($this->getCallback(),$nm);}}}class +__set($nm,$val){if ($nm=='') {$nm="\xFF";}$this->$nm=$val;}function +__get($nm){if ($nm=='') {$nm="\xFF";return +isset($this->$nm)?$this->$nm:$this->$nm=call_user_func($this->getCallback(),'');} else {return$this->$nm=call_user_func($this->getCallback(),$nm);}}}class DibiException extends Exception{private$sql;function -__construct($message=NULL,$code=0,$sql=NULL){parent::__construct($message,(int)$code);$this->sql=$sql;}final +__construct($message=NULL,$code=0,$sql=NULL){parent::__construct($message,(int) $code);$this->sql=$sql;}final function getSql(){return$this->sql;}function __toString(){return @@ -141,7 +141,7 @@ function function catchError(&$message){restore_error_handler();$message=self::$errorMsg;self::$errorMsg=NULL;return$message!==NULL;}static function -_errorHandler($code,$message){restore_error_handler();if(ini_get('html_errors')){$message=strip_tags($message);$message=html_entity_decode($message);}self::$errorMsg=$message;}}class +_errorHandler($code,$message){restore_error_handler();if (ini_get('html_errors')) {$message=strip_tags($message);$message=html_entity_decode($message);}self::$errorMsg=$message;}}class DibiPcreException extends Exception{function @@ -155,33 +155,33 @@ function DibiConnection extends DibiObject{public$onEvent;private$config;private$driver;private$translator;private$connected=FALSE;private$substitutes;function -__construct($config,$name=NULL){class_exists('dibi');if(is_string($config)){parse_str($config,$config);}elseif($config +__construct($config,$name=NULL){class_exists('dibi');if (is_string($config)) {parse_str($config,$config);}elseif ($config instanceof -Traversable){$tmp=array();foreach($config -as$key=>$val){$tmp[$key]=$val +Traversable) {$tmp=array();foreach ($config +as$key=>$val) {$tmp[$key]=$val instanceof -Traversable?iterator_to_array($val):$val;}$config=$tmp;}elseif(!is_array($config)){throw +Traversable?iterator_to_array($val):$val;}$config=$tmp;} elseif (!is_array($config)) {throw new -InvalidArgumentException('Configuration must be array, string or object.');}self::alias($config,'username','user');self::alias($config,'password','pass');self::alias($config,'host','hostname');self::alias($config,'result|formatDate','resultDate');self::alias($config,'result|formatDateTime','resultDateTime');if(!isset($config['driver'])){$config['driver']=dibi::$defaultDriver;}$driver=preg_replace('#[^a-z0-9_]#','_',strtolower($config['driver']));$class="Dibi".$driver."Driver";if(!class_exists($class,FALSE)){ include_once dirname(__FILE__)."/../drivers/$driver.php";if(!class_exists($class,FALSE)){throw +InvalidArgumentException('Configuration must be array, string or object.');}self::alias($config,'username','user');self::alias($config,'password','pass');self::alias($config,'host','hostname');self::alias($config,'result|formatDate','resultDate');self::alias($config,'result|formatDateTime','resultDateTime');if (!isset($config['driver'])){$config['driver']=dibi::$defaultDriver;}$driver=preg_replace('#[^a-z0-9_]#','_',strtolower($config['driver']));$class="Dibi".$driver."Driver";if(!class_exists($class,FALSE)){ include_once dirname(__FILE__)."/../drivers/$driver.php";if(!class_exists($class,FALSE)) {throw new DibiException("Unable to create instance of dibi driver '$class'.");}}$config['name']=$name;$this->config=$config;$this->driver=new$class;$this->translator=new -DibiTranslator($this);$profilerCfg=&$config['profiler'];if(is_scalar($profilerCfg)){$profilerCfg=array('run'=>(bool)$profilerCfg);}if(!empty($profilerCfg['run'])){$filter=isset($profilerCfg['filter'])?$profilerCfg['filter']:DibiEvent::QUERY;if(isset($profilerCfg['file'])){$this->onEvent[]=array(new -DibiFileLogger($profilerCfg['file'],$filter),'logEvent');}if(DibiFirePhpLogger::isAvailable()){$this->onEvent[]=array(new -DibiFirePhpLogger($filter),'logEvent');}if(class_exists('DibiNettePanel',FALSE)){$panel=new +DibiTranslator($this);$profilerCfg=&$config['profiler'];if (is_scalar($profilerCfg)){$profilerCfg=array('run'=>(bool) $profilerCfg);}if(!empty($profilerCfg['run'])){$filter=isset($profilerCfg['filter'])?$profilerCfg['filter']:DibiEvent::QUERY;if(isset($profilerCfg['file'])) {$this->onEvent[]=array(new +DibiFileLogger($profilerCfg['file'],$filter),'logEvent');}if (DibiFirePhpLogger::isAvailable()) {$this->onEvent[]=array(new +DibiFirePhpLogger($filter),'logEvent');}if (class_exists('DibiNettePanel',FALSE)) {$panel=new DibiNettePanel(isset($profilerCfg['explain'])?$profilerCfg['explain']:TRUE,$filter);$panel->register($this);}}$this->substitutes=new -DibiHashMap(create_function('$expr','return ":$expr:";'));if(!empty($config['substitutes'])){foreach($config['substitutes']as$key=>$value){$this->substitutes->$key=$value;}}if(empty($config['lazy'])){$this->connect();}}function +DibiHashMap(create_function('$expr','return ":$expr:";'));if (!empty($config['substitutes'])){foreach ($config['substitutes']as$key=>$value) {$this->substitutes->$key=$value;}}if(empty($config['lazy'])) {$this->connect();}}function __destruct(){$this->connected&&$this->driver->getResource()&&$this->disconnect();}final function connect(){$event=$this->onEvent?new -DibiEvent($this,DibiEvent::CONNECT):NULL;try{$this->driver->connect($this->config);$this->connected=TRUE;$event&&$this->onEvent($event->done());}catch(DibiException$e){$event&&$this->onEvent($event->done($e));throw$e;}}final +DibiEvent($this,DibiEvent::CONNECT):NULL;try {$this->driver->connect($this->config);$this->connected=TRUE;$event&&$this->onEvent($event->done());} catch (DibiException$e) {$event&&$this->onEvent($event->done($e));throw$e;}}final function disconnect(){$this->driver->disconnect();$this->connected=FALSE;}final function isConnected(){return$this->connected;}final function -getConfig($key=NULL,$default=NULL){if($key===NULL){return$this->config;}elseif(isset($this->config[$key])){return$this->config[$key];}else{return$default;}}static +getConfig($key=NULL,$default=NULL){if ($key===NULL) {return$this->config;} elseif (isset($this->config[$key])) {return$this->config[$key];} else {return$default;}}static function -alias(&$config,$key,$alias){$foo=&$config;foreach(explode('|',$key)as$key)$foo=&$foo[$key];if(!isset($foo)&&isset($config[$alias])){$foo=$config[$alias];unset($config[$alias]);}}final +alias(&$config,$key,$alias){$foo=&$config;foreach (explode('|',$key)as$key)$foo=&$foo[$key];if(!isset($foo)&&isset($config[$alias])) {$foo=$config[$alias];unset($config[$alias]);}}final function getDriver(){$this->connected||$this->connect();return$this->driver;}final function @@ -189,8 +189,8 @@ function function translate($args){$args=func_get_args();return$this->translateArgs($args);}final function -test($args){$args=func_get_args();try{dibi::dump($this->translateArgs($args));return -TRUE;}catch(DibiException$e){if($e->getSql()){dibi::dump($e->getSql());}else{echo +test($args){$args=func_get_args();try {dibi::dump($this->translateArgs($args));return +TRUE;} catch (DibiException$e){if ($e->getSql()) {dibi::dump($e->getSql());} else {echo get_class($e).': '.$e->getMessage().(PHP_SAPI==='cli'?"\n":'
    ');}return FALSE;}}final function @@ -201,21 +201,21 @@ function translateArgs($args){$this->connected||$this->connect();return$this->translator->translate($args);}final function nativeQuery($sql){$this->connected||$this->connect();$event=$this->onEvent?new -DibiEvent($this,DibiEvent::QUERY,$sql):NULL;try{$res=$this->driver->query($sql);}catch(DibiException$e){$event&&$this->onEvent($event->done($e));throw$e;}if($res){$res=$this->createResultSet($res);}else{$res=$this->driver->getAffectedRows();}$event&&$this->onEvent($event->done($res));return$res;}function +DibiEvent($this,DibiEvent::QUERY,$sql):NULL;try {$res=$this->driver->query($sql);} catch (DibiException$e){$event&&$this->onEvent($event->done($e));throw$e;}if ($res) {$res=$this->createResultSet($res);} else {$res=$this->driver->getAffectedRows();}$event&&$this->onEvent($event->done($res));return$res;}function getAffectedRows(){$this->connected||$this->connect();$rows=$this->driver->getAffectedRows();if(!is_int($rows)||$rows<0)throw new DibiException('Cannot retrieve number of affected rows.');return$rows;}function affectedRows(){return$this->getAffectedRows();}function getInsertId($sequence=NULL){$this->connected||$this->connect();$id=$this->driver->getInsertId($sequence);if($id<1)throw new -DibiException('Cannot retrieve last generated ID.');return(int)$id;}function +DibiException('Cannot retrieve last generated ID.');return(int) $id;}function insertId($sequence=NULL){return$this->getInsertId($sequence);}function begin($savepoint=NULL){$this->connected||$this->connect();$event=$this->onEvent?new -DibiEvent($this,DibiEvent::BEGIN,$savepoint):NULL;try{$this->driver->begin($savepoint);$event&&$this->onEvent($event->done());}catch(DibiException$e){$event&&$this->onEvent($event->done($e));throw$e;}}function +DibiEvent($this,DibiEvent::BEGIN,$savepoint):NULL;try {$this->driver->begin($savepoint);$event&&$this->onEvent($event->done());} catch (DibiException$e) {$event&&$this->onEvent($event->done($e));throw$e;}}function commit($savepoint=NULL){$this->connected||$this->connect();$event=$this->onEvent?new -DibiEvent($this,DibiEvent::COMMIT,$savepoint):NULL;try{$this->driver->commit($savepoint);$event&&$this->onEvent($event->done());}catch(DibiException$e){$event&&$this->onEvent($event->done($e));throw$e;}}function +DibiEvent($this,DibiEvent::COMMIT,$savepoint):NULL;try {$this->driver->commit($savepoint);$event&&$this->onEvent($event->done());} catch (DibiException$e) {$event&&$this->onEvent($event->done($e));throw$e;}}function rollback($savepoint=NULL){$this->connected||$this->connect();$event=$this->onEvent?new -DibiEvent($this,DibiEvent::ROLLBACK,$savepoint):NULL;try{$this->driver->rollback($savepoint);$event&&$this->onEvent($event->done());}catch(DibiException$e){$event&&$this->onEvent($event->done($e));throw$e;}}function +DibiEvent($this,DibiEvent::ROLLBACK,$savepoint):NULL;try {$this->driver->rollback($savepoint);$event&&$this->onEvent($event->done());} catch (DibiException$e) {$event&&$this->onEvent($event->done($e));throw$e;}}function createResultSet(IDibiResultDriver$resultDriver){$res=new DibiResult($resultDriver);return$res->setFormat(dibi::DATE,$this->config['result']['formatDate'])->setFormat(dibi::DATETIME,$this->config['result']['formatDateTime']);}function command(){return @@ -227,9 +227,9 @@ function Traversable)){throw new InvalidArgumentException('Arguments must be array or Traversable.');}return$this->command()->update('%n',$table)->set($args);}function -insert($table,$args){if($args +insert($table,$args){if ($args instanceof -Traversable){$args=iterator_to_array($args);}elseif(!is_array($args)){throw +Traversable) {$args=iterator_to_array($args);} elseif (!is_array($args)) {throw new InvalidArgumentException('Arguments must be array or Traversable.');}return$this->command()->insert()->into('%n',$table,'(%n)',array_keys($args))->values('%l',$args);}function delete($table){return$this->command()->delete()->from('%n',$table);}function @@ -242,9 +242,9 @@ function fetchAll($args){$args=func_get_args();return$this->query($args)->fetchAll();}function fetchSingle($args){$args=func_get_args();return$this->query($args)->fetchSingle();}function fetchPairs($args){$args=func_get_args();return$this->query($args)->fetchPairs();}function -loadFile($file){$this->connected||$this->connect();@set_time_limit(0);$handle=@fopen($file,'r');if(!$handle){throw +loadFile($file){$this->connected||$this->connect();@set_time_limit(0);$handle=@fopen($file,'r');if (!$handle) {throw new -RuntimeException("Cannot open file '$file'.");}$count=0;$sql='';while(!feof($handle)){$s=fgets($handle);$sql.=$s;if(substr(rtrim($s),-1)===';'){$this->driver->query($sql);$sql='';$count++;}}if(trim($sql)!==''){$this->driver->query($sql);$count++;}fclose($handle);return$count;}function +RuntimeException("Cannot open file '$file'.");}$count=0;$sql='';while (!feof($handle)){$s=fgets($handle);$sql.=$s;if(substr(rtrim($s),-1)===';'){$this->driver->query($sql);$sql='';$count++;}}if(trim($sql)!=='') {$this->driver->query($sql);$count++;}fclose($handle);return$count;}function getDatabaseInfo(){$this->connected||$this->connect();return new DibiDatabaseInfo($this->driver->getReflector(),isset($this->config['database'])?$this->config['database']:NULL);}function @@ -263,13 +263,13 @@ function function getResource(){return$this->getResultDriver()->getResultResource();}final function -free(){if($this->driver!==NULL){$this->driver->free();$this->driver=$this->meta=NULL;}}final +free(){if ($this->driver!==NULL) {$this->driver->free();$this->driver=$this->meta=NULL;}}final function -getResultDriver(){if($this->driver===NULL){throw +getResultDriver(){if ($this->driver===NULL) {throw new RuntimeException('Result-set was released from memory.');}return$this->driver;}final function -seek($row){return($row!==0||$this->fetched)?(bool)$this->getResultDriver()->seek($row):TRUE;}final +seek($row){return($row!==0||$this->fetched)?(bool) $this->getResultDriver()->seek($row):TRUE;}final function count(){return$this->getResultDriver()->getRowCount();}final function @@ -277,49 +277,49 @@ function function rowCount(){trigger_error(__METHOD__.'() is deprecated; use count($res) or $res->getRowCount() instead.',E_USER_WARNING);return$this->getResultDriver()->getRowCount();}final function -getIterator(){if(func_num_args()){trigger_error(__METHOD__.' arguments $offset & $limit have been dropped; use SQL clauses instead.',E_USER_WARNING);}return +getIterator(){if (func_num_args()) {trigger_error(__METHOD__.' arguments $offset & $limit have been dropped; use SQL clauses instead.',E_USER_WARNING);}return new DibiResultIterator($this);}function setRowClass($class){$this->rowClass=$class;return$this;}function getRowClass(){return$this->rowClass;}final function -fetch(){$row=$this->getResultDriver()->fetch(TRUE);if(!is_array($row)){return -FALSE;}$this->fetched=TRUE;$this->normalize($row);if($this->rowClass){$row=new$this->rowClass($row);}return$row;}final +fetch(){$row=$this->getResultDriver()->fetch(TRUE);if (!is_array($row)) {return +FALSE;}$this->fetched=TRUE;$this->normalize($row);if ($this->rowClass) {$row=new$this->rowClass($row);}return$row;}final function -fetchSingle(){$row=$this->getResultDriver()->fetch(TRUE);if(!is_array($row)){return +fetchSingle(){$row=$this->getResultDriver()->fetch(TRUE);if (!is_array($row)) {return FALSE;}$this->fetched=TRUE;$this->normalize($row);return reset($row);}final function -fetchAll($offset=NULL,$limit=NULL){$limit=$limit===NULL?-1:(int)$limit;$this->seek((int)$offset);$row=$this->fetch();if(!$row)return -array();$data=array();do{if($limit===0)break;$limit--;$data[]=$row;}while($row=$this->fetch());return$data;}final +fetchAll($offset=NULL,$limit=NULL){$limit=$limit===NULL?-1:(int) $limit;$this->seek((int) $offset);$row=$this->fetch();if(!$row)return +array();$data=array();do {if($limit===0)break;$limit--;$data[]=$row;} while ($row=$this->fetch());return$data;}final function -fetchAssoc($assoc){if(strpos($assoc,',')!==FALSE){return$this->oldFetchAssoc($assoc);}$this->seek(0);$row=$this->fetch();if(!$row)return -array();$data=NULL;$assoc=preg_split('#(\[\]|->|=|\|)#',$assoc,NULL,PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);foreach($assoc -as$as){if($as!=='[]'&&$as!=='='&&$as!=='->'&&$as!=='|'&&!property_exists($row,$as)){throw +fetchAssoc($assoc){if (strpos($assoc,',')!==FALSE) {return$this->oldFetchAssoc($assoc);}$this->seek(0);$row=$this->fetch();if(!$row)return +array();$data=NULL;$assoc=preg_split('#(\[\]|->|=|\|)#',$assoc,NULL,PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);foreach ($assoc +as$as) {if ($as!=='[]'&&$as!=='='&&$as!=='->'&&$as!=='|'&&!property_exists($row,$as)) {throw new -InvalidArgumentException("Unknown column '$as' in associative descriptor.");}}if($as==='->'){array_pop($assoc);}if(empty($assoc)){$assoc[]='[]';}do{$x=&$data;foreach($assoc -as$i=>$as){if($as==='[]'){$x=&$x[];}elseif($as==='='){$x=$row->{$assoc[$i+1]};continue -2;}elseif($as==='->'){if($x===NULL){$x=clone$row;$x=&$x->{$assoc[$i+1]};$x=NULL;}else{$x=&$x->{$assoc[$i+1]};}}elseif($as!=='|'){$x=&$x[$row->$as];}}if($x===NULL){$x=$row;}}while($row=$this->fetch());unset($x);return$data;}private +InvalidArgumentException("Unknown column '$as' in associative descriptor.");}}if ($as==='->') {array_pop($assoc);}if(empty($assoc)) {$assoc[]='[]';}do {$x=&$data;foreach ($assoc +as$i=>$as) {if ($as==='[]') {$x=&$x[];} elseif ($as==='=') {$x=$row->{$assoc[$i+1]};continue +2;} elseif ($as==='->') {if ($x===NULL) {$x=clone$row;$x=&$x->{$assoc[$i+1]};$x=NULL;} else {$x=&$x->{$assoc[$i+1]};}}elseif ($as!=='|') {$x=&$x[$row->$as];}}if ($x===NULL) {$x=$row;}} while ($row=$this->fetch());unset($x);return$data;}private function oldFetchAssoc($assoc){$this->seek(0);$row=$this->fetch();if(!$row)return -array();$data=NULL;$assoc=explode(',',$assoc);$leaf='@';$last=count($assoc)-1;while($assoc[$last]==='='||$assoc[$last]==='@'){$leaf=$assoc[$last];unset($assoc[$last]);$last--;if($last<0){$assoc[]='#';break;}}do{$x=&$data;foreach($assoc -as$i=>$as){if($as==='#'){$x=&$x[];}elseif($as==='='){if($x===NULL){$x=$row->toArray();$x=&$x[$assoc[$i+1]];$x=NULL;}else{$x=&$x[$assoc[$i+1]];}}elseif($as==='@'){if($x===NULL){$x=clone$row;$x=&$x->{$assoc[$i+1]};$x=NULL;}else{$x=&$x->{$assoc[$i+1]};}}else{$x=&$x[$row->$as];}}if($x===NULL){if($leaf==='='){$x=$row->toArray();}else{$x=$row;}}}while($row=$this->fetch());unset($x);return$data;}final +array();$data=NULL;$assoc=explode(',',$assoc);$leaf='@';$last=count($assoc)-1;while ($assoc[$last]==='='||$assoc[$last]==='@') {$leaf=$assoc[$last];unset($assoc[$last]);$last--;if ($last<0) {$assoc[]='#';break;}}do {$x=&$data;foreach ($assoc +as$i=>$as) {if ($as==='#') {$x=&$x[];} elseif ($as==='=') {if ($x===NULL) {$x=$row->toArray();$x=&$x[$assoc[$i+1]];$x=NULL;} else {$x=&$x[$assoc[$i+1]];}}elseif ($as==='@') {if ($x===NULL) {$x=clone$row;$x=&$x->{$assoc[$i+1]};$x=NULL;} else {$x=&$x->{$assoc[$i+1]};}} else {$x=&$x[$row->$as];}}if ($x===NULL) {if ($leaf==='=') {$x=$row->toArray();} else {$x=$row;}}} while ($row=$this->fetch());unset($x);return$data;}final function fetchPairs($key=NULL,$value=NULL){$this->seek(0);$row=$this->fetch();if(!$row)return -array();$data=array();if($value===NULL){if($key!==NULL){throw +array();$data=array();if ($value===NULL) {if ($key!==NULL) {throw new -InvalidArgumentException("Either none or both columns must be specified.");}$tmp=array_keys($row->toArray());$key=$tmp[0];if(count($row)<2){do{$data[]=$row[$key];}while($row=$this->fetch());return$data;}$value=$tmp[1];}else{if(!property_exists($row,$value)){throw +InvalidArgumentException("Either none or both columns must be specified.");}$tmp=array_keys($row->toArray());$key=$tmp[0];if (count($row)<2){do {$data[]=$row[$key];} while ($row=$this->fetch());return$data;}$value=$tmp[1];} else {if(!property_exists($row,$value)) {throw new -InvalidArgumentException("Unknown value column '$value'.");}if($key===NULL){do{$data[]=$row[$value];}while($row=$this->fetch());return$data;}if(!property_exists($row,$key)){throw +InvalidArgumentException("Unknown value column '$value'.");}if ($key===NULL) {do {$data[]=$row[$value];} while ($row=$this->fetch());return$data;}if(!property_exists($row,$key)) {throw new -InvalidArgumentException("Unknown key column '$key'.");}}do{$data[$row[$key]]=$row[$value];}while($row=$this->fetch());return$data;}private +InvalidArgumentException("Unknown key column '$key'.");}}do {$data[$row[$key]]=$row[$value];} while ($row=$this->fetch());return$data;}private function -detectTypes(){$cache=DibiColumnInfo::getTypeCache();try{foreach($this->getResultDriver()->getResultColumns()as$col){$this->types[$col['name']]=$cache->{$col['nativetype']};}}catch(DibiNotSupportedException$e){}}private +detectTypes(){$cache=DibiColumnInfo::getTypeCache();try {foreach ($this->getResultDriver()->getResultColumns()as$col){$this->types[$col['name']]=$cache->{$col['nativetype']};}} catch (DibiNotSupportedException$e) {}}private function -normalize(array&$row){foreach($this->types -as$key=>$type){if(!isset($row[$key])){continue;}$value=$row[$key];if($value===FALSE||$type===dibi::TEXT){}elseif($type===dibi::INTEGER){$row[$key]=is_float($tmp=$value*1)?$value:$tmp;}elseif($type===dibi::FLOAT){$row[$key]=(string)($tmp=(float)$value)===$value?$tmp:$value;}elseif($type===dibi::BOOL){$row[$key]=((bool)$value)&&$value!=='f'&&$value!=='F';}elseif($type===dibi::DATE||$type===dibi::DATETIME){if((int)$value===0){}elseif(empty($this->formats[$type])){$row[$key]=new -DibiDateTime(is_numeric($value)?date('Y-m-d H:i:s',$value):$value);}elseif($this->formats[$type]==='U'){$row[$key]=is_numeric($value)?(int)$value:strtotime($value);}elseif(is_numeric($value)){$row[$key]=date($this->formats[$type],$value);}else{$value=new -DibiDateTime($value);$row[$key]=$value->format($this->formats[$type]);}}elseif($type===dibi::BINARY){$row[$key]=$this->getResultDriver()->unescape($value,$type);}}}final +normalize(array&$row){foreach ($this->types +as$key=>$type) {if (!isset($row[$key])){continue;}$value=$row[$key];if ($value===FALSE||$type===dibi::TEXT) {} elseif ($type===dibi::INTEGER) {$row[$key]=is_float($tmp=$value*1)?$value:$tmp;}elseif ($type===dibi::FLOAT) {$row[$key]=(string) ($tmp=(float) $value)===$value?$tmp:$value;}elseif ($type===dibi::BOOL) {$row[$key]=((bool) $value)&&$value!=='f'&&$value!=='F';}elseif ($type===dibi::DATE||$type===dibi::DATETIME) {if((int) $value===0){}elseif(empty($this->formats[$type])) {$row[$key]=new +DibiDateTime(is_numeric($value)?date('Y-m-d H:i:s',$value):$value);} elseif ($this->formats[$type]==='U') {$row[$key]=is_numeric($value)?(int) $value:strtotime($value);}elseif(is_numeric($value)) {$row[$key]=date($this->formats[$type],$value);} else {$value=new +DibiDateTime($value);$row[$key]=$value->format($this->formats[$type]);}} elseif ($type===dibi::BINARY) {$row[$key]=$this->getResultDriver()->unescape($value,$type);}}}final function setType($col,$type){$this->types[$col]=$type;return$this;}final function @@ -330,15 +330,15 @@ function function getFormat($type){return isset($this->formats[$type])?$this->formats[$type]:NULL;}function -getInfo(){if($this->meta===NULL){$this->meta=new +getInfo(){if ($this->meta===NULL) {$this->meta=new DibiResultInfo($this->getResultDriver());}return$this->meta;}final function getColumns(){return$this->getInfo()->getColumns();}function getColumnNames($fullNames=FALSE){trigger_error(__METHOD__.'() is deprecated; use $res->getInfo()->getColumnNames() instead.',E_USER_WARNING);return$this->getInfo()->getColumnNames($fullNames);}final function -dump(){$i=0;$this->seek(0);while($row=$this->fetch()){if($i===0){echo"\n\n\n\t\n\t\t\n";foreach($row -as$col=>$foo){echo"\t\t\n";}echo"\t\n\n\n";}echo"\t\n\t\t\n";foreach($row -as$col){echo"\t\t\n";}echo"\t\n";$i++;}if($i===0){echo'

    empty result set

    ';}else{echo"\n
    #row".htmlSpecialChars($col)."
    ",$i,"",htmlSpecialChars($col),"
    \n";}}}class +dump(){$i=0;$this->seek(0);while ($row=$this->fetch()){if ($i===0) {echo"\n\n\n\t\n\t\t\n";foreach ($row +as$col=>$foo) {echo"\t\t\n";}echo"\t\n\n\n";}echo"\t\n\t\t\n";foreach ($row +as$col) {echo"\t\t\n";}echo"\t\n";$i++;}if ($i===0) {echo'

    empty result set

    ';} else {echo"\n
    #row".htmlSpecialChars($col)."
    ",$i,"",htmlSpecialChars($col),"
    \n";}}}class DibiResultIterator implements Iterator,Countable{private$result;private$row;private$pointer;function @@ -354,18 +354,18 @@ function ArrayAccess,IteratorAggregate,Countable{function __construct($arr){foreach($arr as$k=>$v)$this->$k=$v;}function -toArray(){return(array)$this;}function -asDateTime($key,$format=NULL){$time=$this[$key];if(!$time +toArray(){return(array) $this;}function +asDateTime($key,$format=NULL){$time=$this[$key];if (!$time instanceof -DibiDateTime){if((int)$time===0){return +DibiDateTime) {if ((int) $time===0) {return NULL;}$time=new DibiDateTime(is_numeric($time)?date('Y-m-d H:i:s',$time):$time);}return$format===NULL?$time:$time->format($format);}function -asTimestamp($key){trigger_error(__METHOD__.'() is deprecated.',E_USER_WARNING);$time=$this[$key];return(int)$time===0?NULL:(is_numeric($time)?(int)$time:strtotime($time));}function +asTimestamp($key){trigger_error(__METHOD__.'() is deprecated.',E_USER_WARNING);$time=$this[$key];return(int) $time===0?NULL:(is_numeric($time)?(int) $time:strtotime($time));}function asBool($key){trigger_error(__METHOD__.'() is deprecated.',E_USER_WARNING);return$this[$key];}function -asDate($key,$format=NULL){trigger_error(__METHOD__.'() is deprecated.',E_USER_WARNING);if($format===NULL){return$this->asTimestamp($key);}else{return$this->asDateTime($key,$format===TRUE?NULL:$format);}}final +asDate($key,$format=NULL){trigger_error(__METHOD__.'() is deprecated.',E_USER_WARNING);if ($format===NULL) {return$this->asTimestamp($key);} else {return$this->asDateTime($key,$format===TRUE?NULL:$format);}}final function count(){return -count((array)$this);}final +count((array) $this);}final function getIterator(){return new @@ -385,59 +385,59 @@ class DibiObject{private$connection;private$driver;private$cursor;private$args;private$hasError;private$comment;private$ifLevel;private$ifLevelStart;private$limit;private$offset;private$identifiers;function __construct(DibiConnection$connection){$this->connection=$connection;}function translate(array$args){$this->identifiers=new -DibiHashMap(array($this,'delimite'));$this->driver=$this->connection->getDriver();$args=array_values($args);while(count($args)===1&&is_array($args[0])){$args=array_values($args[0]);}$this->args=$args;$this->limit=-1;$this->offset=0;$this->hasError=FALSE;$commandIns=NULL;$lastArr=NULL;$cursor=&$this->cursor;$cursor=0;$this->ifLevel=$this->ifLevelStart=0;$comment=&$this->comment;$comment=FALSE;$sql=array();while($cursorargs)){$arg=$this->args[$cursor];$cursor++;if(is_string($arg)){$toSkip=strcspn($arg,'`[\'":%?');if(strlen($arg)===$toSkip){$sql[]=$arg;}else{$sql[]=substr($arg,0,$toSkip).preg_replace_callback('/(?=[`[\'":%?])(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\S*?:)([a-zA-Z0-9._]?)|%([a-zA-Z~][a-zA-Z0-9~]{0,5})|(\?))/s',array($this,'cb'),substr($arg,$toSkip));if(preg_last_error())throw +DibiHashMap(array($this,'delimite'));$this->driver=$this->connection->getDriver();$args=array_values($args);while (count($args)===1&&is_array($args[0])){$args=array_values($args[0]);}$this->args=$args;$this->limit=-1;$this->offset=0;$this->hasError=FALSE;$commandIns=NULL;$lastArr=NULL;$cursor=&$this->cursor;$cursor=0;$this->ifLevel=$this->ifLevelStart=0;$comment=&$this->comment;$comment=FALSE;$sql=array();while($cursorargs)){$arg=$this->args[$cursor];$cursor++;if(is_string($arg)){$toSkip=strcspn($arg,'`[\'":%?');if(strlen($arg)===$toSkip) {$sql[]=$arg;} else {$sql[]=substr($arg,0,$toSkip).preg_replace_callback('/(?=[`[\'":%?])(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\S*?:)([a-zA-Z0-9._]?)|%([a-zA-Z~][a-zA-Z0-9~]{0,5})|(\?))/s',array($this,'cb'),substr($arg,$toSkip));if(preg_last_error())throw new -DibiPcreException;}continue;}if($comment){$sql[]='...';continue;}if($arg +DibiPcreException;}continue;}if ($comment) {$sql[]='...';continue;}if ($arg instanceof -Traversable){$arg=iterator_to_array($arg);}if(is_array($arg)){if(is_string(key($arg))){if($commandIns===NULL){$commandIns=strtoupper(substr(ltrim($this->args[0]),0,6));$commandIns=$commandIns==='INSERT'||$commandIns==='REPLAC';$sql[]=$this->formatValue($arg,$commandIns?'v':'a');}else{if($lastArr===$cursor-1)$sql[]=',';$sql[]=$this->formatValue($arg,$commandIns?'l':'a');}$lastArr=$cursor;continue;}}$sql[]=$this->formatValue($arg,FALSE);}if($comment)$sql[]="*/";$sql=implode(' ',$sql);if($this->hasError){throw +Traversable) {$arg=iterator_to_array($arg);}if (is_array($arg)){if(is_string(key($arg))){if ($commandIns===NULL) {$commandIns=strtoupper(substr(ltrim($this->args[0]),0,6));$commandIns=$commandIns==='INSERT'||$commandIns==='REPLAC';$sql[]=$this->formatValue($arg,$commandIns?'v':'a');} else {if($lastArr===$cursor-1)$sql[]=',';$sql[]=$this->formatValue($arg,$commandIns?'l':'a');}$lastArr=$cursor;continue;}}$sql[]=$this->formatValue($arg,FALSE);}if($comment)$sql[]="*/";$sql=implode(' ',$sql);if ($this->hasError) {throw new -DibiException('SQL translate error',0,$sql);}if($this->limit>-1||$this->offset>0){$this->driver->applyLimit($sql,$this->limit,$this->offset);}return$sql;}function -formatValue($value,$modifier){if($this->comment){return"...";}if($value +DibiException('SQL translate error',0,$sql);}if ($this->limit>-1||$this->offset>0) {$this->driver->applyLimit($sql,$this->limit,$this->offset);}return$sql;}function +formatValue($value,$modifier){if ($this->comment) {return"...";}if ($value instanceof -Traversable){$value=iterator_to_array($value);}if(is_array($value)){$vx=$kx=array();switch($modifier){case'and':case'or':if(empty($value)){return'1=1';}foreach($value -as$k=>$v){if(is_string($k)){$pair=explode('%',$k,2);$k=$this->identifiers->{$pair[0]}.' ';if(!isset($pair[1])){$v=$this->formatValue($v,FALSE);$vx[]=$k.($v==='NULL'?'IS ':'= ').$v;}elseif($pair[1]==='ex'){$vx[]=$k.$this->formatValue($v,'ex');}else{$v=$this->formatValue($v,$pair[1]);if($pair[1]==='l'||$pair[1]==='in'){$op='IN ';}elseif(strpos($pair[1],'like')!==FALSE){$op='LIKE ';}elseif($v==='NULL'){$op='IS ';}else{$op='= ';}$vx[]=$k.$op.$v;}}else{$vx[]=$this->formatValue($v,'ex');}}return'('.implode(') '.strtoupper($modifier).' (',$vx).')';case'n':foreach($value -as$k=>$v){if(is_string($k)){$vx[]=$this->identifiers->$k.(empty($v)?'':' AS '.$this->identifiers->$v);}else{$pair=explode('%',$v,2);$vx[]=$this->identifiers->{$pair[0]};}}return -implode(', ',$vx);case'a':foreach($value -as$k=>$v){$pair=explode('%',$k,2);$vx[]=$this->identifiers->{$pair[0]}.'='.$this->formatValue($v,isset($pair[1])?$pair[1]:(is_array($v)?'ex':FALSE));}return -implode(', ',$vx);case'in':case'l':foreach($value -as$k=>$v){$pair=explode('%',$k,2);$vx[]=$this->formatValue($v,isset($pair[1])?$pair[1]:(is_array($v)?'ex':FALSE));}return'('.(($vx||$modifier==='l')?implode(', ',$vx):'NULL').')';case'v':foreach($value -as$k=>$v){$pair=explode('%',$k,2);$kx[]=$this->identifiers->{$pair[0]};$vx[]=$this->formatValue($v,isset($pair[1])?$pair[1]:(is_array($v)?'ex':FALSE));}return'('.implode(', ',$kx).') VALUES ('.implode(', ',$vx).')';case'm':foreach($value -as$k=>$v){if(is_array($v)){if(isset($proto)){if($proto!==array_keys($v)){$this->hasError=TRUE;return'**Multi-insert array "'.$k.'" is different.**';}}else{$proto=array_keys($v);}}else{$this->hasError=TRUE;return'**Unexpected type '.gettype($v).'**';}$pair=explode('%',$k,2);$kx[]=$this->identifiers->{$pair[0]};foreach($v -as$k2=>$v2){$vx[$k2][]=$this->formatValue($v2,isset($pair[1])?$pair[1]:(is_array($v2)?'ex':FALSE));}}foreach($vx -as$k=>$v){$vx[$k]='('.implode(', ',$v).')';}return'('.implode(', ',$kx).') VALUES '.implode(', ',$vx);case'by':foreach($value -as$k=>$v){if(is_array($v)){$vx[]=$this->formatValue($v,'ex');}elseif(is_string($k)){$v=(is_string($v)&&strncasecmp($v,'d',1))||$v>0?'ASC':'DESC';$vx[]=$this->identifiers->$k.' '.$v;}else{$vx[]=$this->identifiers->$v;}}return +Traversable) {$value=iterator_to_array($value);}if (is_array($value)){$vx=$kx=array();switch ($modifier) {case'and':case'or':if(empty($value)) {return'1=1';}foreach ($value +as$k=>$v) {if (is_string($k)){$pair=explode('%',$k,2);$k=$this->identifiers->{$pair[0]}.' ';if(!isset($pair[1])){$v=$this->formatValue($v,FALSE);$vx[]=$k.($v==='NULL'?'IS ':'= ').$v;} elseif ($pair[1]==='ex') {$vx[]=$k.$this->formatValue($v,'ex');} else {$v=$this->formatValue($v,$pair[1]);if ($pair[1]==='l'||$pair[1]==='in') {$op='IN ';}elseif(strpos($pair[1],'like')!==FALSE){$op='LIKE ';}elseif ($v==='NULL') {$op='IS ';} else {$op='= ';}$vx[]=$k.$op.$v;}} else {$vx[]=$this->formatValue($v,'ex');}}return'('.implode(') '.strtoupper($modifier).' (',$vx).')';case'n':foreach ($value +as$k=>$v) {if (is_string($k)) {$vx[]=$this->identifiers->$k.(empty($v)?'':' AS '.$this->identifiers->$v);} else {$pair=explode('%',$v,2);$vx[]=$this->identifiers->{$pair[0]};}}return +implode(', ',$vx);case'a':foreach ($value +as$k=>$v) {$pair=explode('%',$k,2);$vx[]=$this->identifiers->{$pair[0]}.'='.$this->formatValue($v,isset($pair[1])?$pair[1]:(is_array($v)?'ex':FALSE));}return +implode(', ',$vx);case'in':case'l':foreach ($value +as$k=>$v) {$pair=explode('%',$k,2);$vx[]=$this->formatValue($v,isset($pair[1])?$pair[1]:(is_array($v)?'ex':FALSE));}return'('.(($vx||$modifier==='l')?implode(', ',$vx):'NULL').')';case'v':foreach ($value +as$k=>$v) {$pair=explode('%',$k,2);$kx[]=$this->identifiers->{$pair[0]};$vx[]=$this->formatValue($v,isset($pair[1])?$pair[1]:(is_array($v)?'ex':FALSE));}return'('.implode(', ',$kx).') VALUES ('.implode(', ',$vx).')';case'm':foreach ($value +as$k=>$v) {if (is_array($v)){if(isset($proto)){if($proto!==array_keys($v)) {$this->hasError=TRUE;return'**Multi-insert array "'.$k.'" is different.**';}} else {$proto=array_keys($v);}} else {$this->hasError=TRUE;return'**Unexpected type '.gettype($v).'**';}$pair=explode('%',$k,2);$kx[]=$this->identifiers->{$pair[0]};foreach ($v +as$k2=>$v2) {$vx[$k2][]=$this->formatValue($v2,isset($pair[1])?$pair[1]:(is_array($v2)?'ex':FALSE));}}foreach ($vx +as$k=>$v) {$vx[$k]='('.implode(', ',$v).')';}return'('.implode(', ',$kx).') VALUES '.implode(', ',$vx);case'by':foreach ($value +as$k=>$v) {if (is_array($v)){$vx[]=$this->formatValue($v,'ex');} elseif (is_string($k)) {$v=(is_string($v)&&strncasecmp($v,'d',1))||$v>0?'ASC':'DESC';$vx[]=$this->identifiers->$k.' '.$v;} else {$vx[]=$this->identifiers->$v;}}return implode(', ',$vx);case'ex':case'sql':$translator=new -self($this->connection);return$translator->translate($value);default:foreach($value -as$v){$vx[]=$this->formatValue($v,$modifier);}return -implode(', ',$vx);}}if($modifier){if($value!==NULL&&!is_scalar($value)&&!($value +self($this->connection);return$translator->translate($value);default:foreach ($value +as$v) {$vx[]=$this->formatValue($v,$modifier);}return +implode(', ',$vx);}}if ($modifier) {if($value!==NULL&&!is_scalar($value)&&!($value instanceof -DateTime)){$this->hasError=TRUE;return'**Unexpected type '.gettype($value).'**';}switch($modifier){case's':case'bin':case'b':return$value===NULL?'NULL':$this->driver->escape($value,$modifier);case'sN':case'sn':return$value==''?'NULL':$this->driver->escape($value,dibi::TEXT);case'iN':case'in':if($value=='')$value=NULL;case'i':case'u':if(is_string($value)&&preg_match('#[+-]?\d++(e\d+)?\z#A',$value)){return$value;}else{return$value===NULL?'NULL':(string)(int)($value+0);}case'f':if(is_string($value)&&is_numeric($value)&&strpos($value,'x')===FALSE){return$value;}else{return$value===NULL?'NULL':rtrim(rtrim(number_format($value+0,10,'.',''),'0'),'.');}case'd':case't':if($value===NULL){return'NULL';}else{if(is_numeric($value)){$value=(int)$value;}elseif(is_string($value)){$value=new -DateTime($value);}return$this->driver->escape($value,$modifier);}case'by':case'n':return$this->identifiers->$value;case'ex':case'sql':$value=(string)$value;$toSkip=strcspn($value,'`[\'":');if(strlen($value)!==$toSkip){$value=substr($value,0,$toSkip).preg_replace_callback('/(?=[`[\'":])(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\S*?:)([a-zA-Z0-9._]?))/s',array($this,'cb'),substr($value,$toSkip));if(preg_last_error())throw +DateTime)){$this->hasError=TRUE;return'**Unexpected type '.gettype($value).'**';}switch ($modifier) {case's':case'bin':case'b':return$value===NULL?'NULL':$this->driver->escape($value,$modifier);case'sN':case'sn':return$value==''?'NULL':$this->driver->escape($value,dibi::TEXT);case'iN':case'in':if($value=='')$value=NULL;case'i':case'u':if(is_string($value)&&preg_match('#[+-]?\d++(e\d+)?\z#A',$value)){return$value;} else {return$value===NULL?'NULL':(string) (int) ($value+0);}case'f':if(is_string($value)&&is_numeric($value)&&strpos($value,'x')===FALSE){return$value;} else {return$value===NULL?'NULL':rtrim(rtrim(number_format($value+0,10,'.',''),'0'),'.');}case'd':case't':if ($value===NULL) {return'NULL';} else {if(is_numeric($value)){$value=(int) $value;} elseif (is_string($value)) {$value=new +DateTime($value);}return$this->driver->escape($value,$modifier);}case'by':case'n':return$this->identifiers->$value;case'ex':case'sql':$value=(string) $value;$toSkip=strcspn($value,'`[\'":');if (strlen($value)!==$toSkip) {$value=substr($value,0,$toSkip).preg_replace_callback('/(?=[`[\'":])(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\S*?:)([a-zA-Z0-9._]?))/s',array($this,'cb'),substr($value,$toSkip));if(preg_last_error())throw new -DibiPcreException;}return$value;case'SQL':return(string)$value;case'like~':return$this->driver->escapeLike($value,1);case'~like':return$this->driver->escapeLike($value,-1);case'~like~':return$this->driver->escapeLike($value,0);case'and':case'or':case'a':case'l':case'v':$this->hasError=TRUE;return'**Unexpected type '.gettype($value).'**';default:$this->hasError=TRUE;return"**Unknown or invalid modifier %$modifier**";}}if(is_string($value)){return$this->driver->escape($value,dibi::TEXT);}elseif(is_int($value)){return(string)$value;}elseif(is_float($value)){return -rtrim(rtrim(number_format($value,10,'.',''),'0'),'.');}elseif(is_bool($value)){return$this->driver->escape($value,dibi::BOOL);}elseif($value===NULL){return'NULL';}elseif($value +DibiPcreException;}return$value;case'SQL':return(string) $value;case'like~':return$this->driver->escapeLike($value,1);case'~like':return$this->driver->escapeLike($value,-1);case'~like~':return$this->driver->escapeLike($value,0);case'and':case'or':case'a':case'l':case'v':$this->hasError=TRUE;return'**Unexpected type '.gettype($value).'**';default:$this->hasError=TRUE;return"**Unknown or invalid modifier %$modifier**";}}if (is_string($value)){return$this->driver->escape($value,dibi::TEXT);} elseif (is_int($value)){return(string) $value;}elseif(is_float($value)) {return +rtrim(rtrim(number_format($value,10,'.',''),'0'),'.');} elseif (is_bool($value)){return$this->driver->escape($value,dibi::BOOL);}elseif ($value===NULL) {return'NULL';}elseif ($value instanceof -DateTime){return$this->driver->escape($value,dibi::DATETIME);}elseif($value +DateTime) {return$this->driver->escape($value,dibi::DATETIME);}elseif ($value instanceof -DibiLiteral){return(string)$value;}else{$this->hasError=TRUE;return'**Unexpected '.gettype($value).'**';}}private +DibiLiteral) {return(string) $value;} else {$this->hasError=TRUE;return'**Unexpected '.gettype($value).'**';}}private function -cb($matches){if(!empty($matches[11])){$cursor=&$this->cursor;if($cursor>=count($this->args)){$this->hasError=TRUE;return"**Extra placeholder**";}$cursor++;return$this->formatValue($this->args[$cursor-1],FALSE);}if(!empty($matches[10])){$mod=$matches[10];$cursor=&$this->cursor;if($cursor>=count($this->args)&&$mod!=='else'&&$mod!=='end'){$this->hasError=TRUE;return"**Extra modifier %$mod**";}if($mod==='if'){$this->ifLevel++;$cursor++;if(!$this->comment&&!$this->args[$cursor-1]){$this->ifLevelStart=$this->ifLevel;$this->comment=TRUE;return"/*";}return'';}elseif($mod==='else'){if($this->ifLevelStart===$this->ifLevel){$this->ifLevelStart=0;$this->comment=FALSE;return"*/";}elseif(!$this->comment){$this->ifLevelStart=$this->ifLevel;$this->comment=TRUE;return"/*";}}elseif($mod==='end'){$this->ifLevel--;if($this->ifLevelStart===$this->ifLevel+1){$this->ifLevelStart=0;$this->comment=FALSE;return"*/";}return'';}elseif($mod==='ex'){array_splice($this->args,$cursor,1,$this->args[$cursor]);return'';}elseif($mod==='lmt'){if($this->args[$cursor]!==NULL)$this->limit=(int)$this->args[$cursor];$cursor++;return'';}elseif($mod==='ofs'){if($this->args[$cursor]!==NULL)$this->offset=(int)$this->args[$cursor];$cursor++;return'';}else{$cursor++;return$this->formatValue($this->args[$cursor-1],$mod);}}if($this->comment)return'...';if($matches[1])return$this->identifiers->{$matches[1]};if($matches[2])return$this->identifiers->{$matches[2]};if($matches[3])return$this->driver->escape(str_replace("''","'",$matches[4]),dibi::TEXT);if($matches[5])return$this->driver->escape(str_replace('""','"',$matches[6]),dibi::TEXT);if($matches[7]){$this->hasError=TRUE;return'**Alone quote**';}if($matches[8]){$m=substr($matches[8],0,-1);$m=$this->connection->getSubstitutes()->$m;return$matches[9]==''?$this->formatValue($m,FALSE):$m.$matches[9];}die('this should be never executed');}function -delimite($value){$value=$this->connection->substitute($value);$parts=explode('.',$value);foreach($parts -as&$v){if($v!=='*')$v=$this->driver->escape($v,dibi::IDENTIFIER);}return +cb($matches){if (!empty($matches[11])){$cursor=&$this->cursor;if($cursor>=count($this->args)){$this->hasError=TRUE;return"**Extra placeholder**";}$cursor++;return$this->formatValue($this->args[$cursor-1],FALSE);}if(!empty($matches[10])){$mod=$matches[10];$cursor=&$this->cursor;if($cursor>=count($this->args)&&$mod!=='else'&&$mod!=='end'){$this->hasError=TRUE;return"**Extra modifier %$mod**";}if ($mod==='if') {$this->ifLevel++;$cursor++;if (!$this->comment&&!$this->args[$cursor-1]) {$this->ifLevelStart=$this->ifLevel;$this->comment=TRUE;return"/*";}return'';} elseif ($mod==='else') {if ($this->ifLevelStart===$this->ifLevel) {$this->ifLevelStart=0;$this->comment=FALSE;return"*/";}elseif (!$this->comment) {$this->ifLevelStart=$this->ifLevel;$this->comment=TRUE;return"/*";}}elseif ($mod==='end') {$this->ifLevel--;if ($this->ifLevelStart===$this->ifLevel+1) {$this->ifLevelStart=0;$this->comment=FALSE;return"*/";}return'';}elseif ($mod==='ex') {array_splice($this->args,$cursor,1,$this->args[$cursor]);return'';}elseif ($mod==='lmt') {if($this->args[$cursor]!==NULL)$this->limit=(int) $this->args[$cursor];$cursor++;return'';}elseif ($mod==='ofs') {if($this->args[$cursor]!==NULL)$this->offset=(int) $this->args[$cursor];$cursor++;return'';} else {$cursor++;return$this->formatValue($this->args[$cursor-1],$mod);}}if($this->comment)return'...';if($matches[1])return$this->identifiers->{$matches[1]};if($matches[2])return$this->identifiers->{$matches[2]};if($matches[3])return$this->driver->escape(str_replace("''","'",$matches[4]),dibi::TEXT);if($matches[5])return$this->driver->escape(str_replace('""','"',$matches[6]),dibi::TEXT);if ($matches[7]) {$this->hasError=TRUE;return'**Alone quote**';}if ($matches[8]) {$m=substr($matches[8],0,-1);$m=$this->connection->getSubstitutes()->$m;return$matches[9]==''?$this->formatValue($m,FALSE):$m.$matches[9];}die('this should be never executed');}function +delimite($value){$value=$this->connection->substitute($value);$parts=explode('.',$value);foreach ($parts +as&$v) {if($v!=='*')$v=$this->driver->escape($v,dibi::IDENTIFIER);}return implode('.',$parts);}}class DibiDataSource extends DibiObject implements IDataSource{private$connection;private$sql;private$result;private$count;private$totalCount;private$cols=array();private$sorting=array();private$conds=array();private$offset;private$limit;function -__construct($sql,DibiConnection$connection){if(strpbrk($sql," \t\r\n")===FALSE){$this->sql=$connection->getDriver()->escape($sql,dibi::IDENTIFIER);}else{$this->sql='('.$sql.') t';}$this->connection=$connection;}function -select($col,$as=NULL){if(is_array($col)){$this->cols=$col;}else{$this->cols[$col]=$as;}$this->result=NULL;return$this;}function -where($cond){if(is_array($cond)){$this->conds[]=$cond;}else{$this->conds[]=func_get_args();}$this->result=$this->count=NULL;return$this;}function -orderBy($row,$sorting='ASC'){if(is_array($row)){$this->sorting=$row;}else{$this->sorting[$row]=$sorting;}$this->result=NULL;return$this;}function +__construct($sql,DibiConnection$connection){if (strpbrk($sql," \t\r\n")===FALSE) {$this->sql=$connection->getDriver()->escape($sql,dibi::IDENTIFIER);} else {$this->sql='('.$sql.') t';}$this->connection=$connection;}function +select($col,$as=NULL){if (is_array($col)) {$this->cols=$col;} else {$this->cols[$col]=$as;}$this->result=NULL;return$this;}function +where($cond){if (is_array($cond)) {$this->conds[]=$cond;} else {$this->conds[]=func_get_args();}$this->result=$this->count=NULL;return$this;}function +orderBy($row,$sorting='ASC'){if (is_array($row)) {$this->sorting=$row;} else {$this->sorting[$row]=$sorting;}$this->result=NULL;return$this;}function applyLimit($limit,$offset=NULL){$this->limit=$limit;$this->offset=$offset;$this->result=$this->count=NULL;return$this;}final function getConnection(){return$this->connection;}function -getResult(){if($this->result===NULL){$this->result=$this->connection->nativeQuery($this->__toString());}return$this->result;}function +getResult(){if ($this->result===NULL) {$this->result=$this->connection->nativeQuery($this->__toString());}return$this->result;}function getIterator(){return$this->getResult()->getIterator();}function fetch(){return$this->getResult()->fetch();}function fetchSingle(){return$this->getResult()->fetchSingle();}function @@ -449,14 +449,14 @@ function toDataSource(){return new self($this->__toString(),$this->connection);}function -__toString(){try{return$this->connection->translate(' +__toString(){try {return$this->connection->translate(' SELECT %n',(empty($this->cols)?'*':$this->cols),' FROM %SQL',$this->sql,' %ex',$this->conds?array('WHERE %and',$this->conds):NULL,' %ex',$this->sorting?array('ORDER BY %by',$this->sorting):NULL,' -%ofs %lmt',$this->offset,$this->limit);}catch(Exception$e){trigger_error($e->getMessage(),E_USER_ERROR);}}function -count(){if($this->count===NULL){$this->count=$this->conds||$this->offset||$this->limit?(int)$this->connection->nativeQuery('SELECT COUNT(*) FROM ('.$this->__toString().') t')->fetchSingle():$this->getTotalCount();}return$this->count;}function -getTotalCount(){if($this->totalCount===NULL){$this->totalCount=(int)$this->connection->nativeQuery('SELECT COUNT(*) FROM '.$this->sql)->fetchSingle();}return$this->totalCount;}}class +%ofs %lmt',$this->offset,$this->limit);} catch (Exception$e) {trigger_error($e->getMessage(),E_USER_ERROR);}}function +count(){if ($this->count===NULL) {$this->count=$this->conds||$this->offset||$this->limit?(int) $this->connection->nativeQuery('SELECT COUNT(*) FROM ('.$this->__toString().') t')->fetchSingle():$this->getTotalCount();}return$this->count;}function +getTotalCount(){if ($this->totalCount===NULL) {$this->totalCount=(int) $this->connection->nativeQuery('SELECT COUNT(*) FROM '.$this->sql)->fetchSingle();}return$this->totalCount;}}class DibiFluent extends DibiObject @@ -468,19 +468,19 @@ function static$separators=array('SELECT'=>',','FROM'=>',','WHERE'=>'AND','GROUP BY'=>',','HAVING'=>'AND','ORDER BY'=>',','LIMIT'=>FALSE,'OFFSET'=>FALSE,'SET'=>',','VALUES'=>',','INTO'=>FALSE);public static$clauseSwitches=array('JOIN'=>'FROM','INNER JOIN'=>'FROM','LEFT JOIN'=>'FROM','RIGHT JOIN'=>'FROM');private$connection;private$setups=array();private$command;private$clauses=array();private$flags=array();private$cursor;private static$normalizer;function -__construct(DibiConnection$connection){$this->connection=$connection;if(self::$normalizer===NULL){self::$normalizer=new +__construct(DibiConnection$connection){$this->connection=$connection;if (self::$normalizer===NULL) {self::$normalizer=new DibiHashMap(array(__CLASS__,'_formatClause'));}}function -__call($clause,$args){$clause=self::$normalizer->$clause;if($this->command===NULL){if(isset(self::$masks[$clause])){$this->clauses=array_fill_keys(self::$masks[$clause],NULL);}$this->cursor=&$this->clauses[$clause];$this->cursor=array();$this->command=$clause;}if(isset(self::$clauseSwitches[$clause])){$this->cursor=&$this->clauses[self::$clauseSwitches[$clause]];}if(array_key_exists($clause,$this->clauses)){$this->cursor=&$this->clauses[$clause];if($args===array(self::REMOVE)){$this->cursor=NULL;return$this;}if(isset(self::$separators[$clause])){$sep=self::$separators[$clause];if($sep===FALSE){$this->cursor=array();}elseif(!empty($this->cursor)){$this->cursor[]=$sep;}}}else{if($args===array(self::REMOVE)){return$this;}$this->cursor[]=$clause;}if($this->cursor===NULL){$this->cursor=array();}if(count($args)===1){$arg=$args[0];if($arg===TRUE){return$this;}elseif(is_string($arg)&&preg_match('#^[a-z:_][a-z0-9_.:]*\z#i',$arg)){$args=array('%n',$arg);}elseif(is_array($arg)||($arg +__call($clause,$args){$clause=self::$normalizer->$clause;if ($this->command===NULL) {if(isset(self::$masks[$clause])){$this->clauses=array_fill_keys(self::$masks[$clause],NULL);}$this->cursor=&$this->clauses[$clause];$this->cursor=array();$this->command=$clause;}if(isset(self::$clauseSwitches[$clause])){$this->cursor=&$this->clauses[self::$clauseSwitches[$clause]];}if(array_key_exists($clause,$this->clauses)){$this->cursor=&$this->clauses[$clause];if($args===array(self::REMOVE)){$this->cursor=NULL;return$this;}if(isset(self::$separators[$clause])){$sep=self::$separators[$clause];if ($sep===FALSE) {$this->cursor=array();} elseif (!empty($this->cursor)){$this->cursor[]=$sep;}}} else {if($args===array(self::REMOVE)){return$this;}$this->cursor[]=$clause;}if ($this->cursor===NULL) {$this->cursor=array();}if(count($args)===1){$arg=$args[0];if ($arg===TRUE) {return$this;}elseif(is_string($arg)&&preg_match('#^[a-z:_][a-z0-9_.:]*\z#i',$arg)) {$args=array('%n',$arg);}elseif(is_array($arg)||($arg instanceof Traversable&&!$arg instanceof -self)){if(isset(self::$modifiers[$clause])){$args=array(self::$modifiers[$clause],$arg);}elseif(is_string(key($arg))){$args=array('%a',$arg);}}}foreach($args -as$arg){if($arg +self)){if (isset(self::$modifiers[$clause])){$args=array(self::$modifiers[$clause],$arg);} elseif (is_string(key($arg))) {$args=array('%a',$arg);}}}foreach ($args +as$arg) {if ($arg instanceof -self){$arg="($arg)";}$this->cursor[]=$arg;}return$this;}function -clause($clause,$remove=FALSE){$this->cursor=&$this->clauses[self::$normalizer->$clause];if($remove){trigger_error(__METHOD__.'(..., TRUE) is deprecated; use removeClause() instead.',E_USER_NOTICE);$this->cursor=NULL;}elseif($this->cursor===NULL){$this->cursor=array();}return$this;}function +self) {$arg="($arg)";}$this->cursor[]=$arg;}return$this;}function +clause($clause,$remove=FALSE){$this->cursor=&$this->clauses[self::$normalizer->$clause];if ($remove) {trigger_error(__METHOD__.'(..., TRUE) is deprecated; use removeClause() instead.',E_USER_NOTICE);$this->cursor=NULL;} elseif ($this->cursor===NULL) {$this->cursor=array();}return$this;}function removeClause($clause){$this->clauses[self::$normalizer->$clause]=NULL;return$this;}function -setFlag($flag,$value=TRUE){$flag=strtoupper($flag);if($value){$this->flags[$flag]=TRUE;}else{unset($this->flags[$flag]);}return$this;}final +setFlag($flag,$value=TRUE){$flag=strtoupper($flag);if ($value) {$this->flags[$flag]=TRUE;} else {unset($this->flags[$flag]);}return$this;}final function getFlag($flag){return isset($this->flags[strtoupper($flag)]);}final @@ -490,32 +490,32 @@ function getConnection(){return$this->connection;}function setupResult($method){$this->setups[]=func_get_args();return$this;}function execute($return=NULL){$res=$this->query($this->_export());return$return===dibi::IDENTIFIER?$this->connection->getInsertId():$res;}function -fetch(){if($this->command==='SELECT'){return$this->query($this->_export(NULL,array('%lmt',1)))->fetch();}else{return$this->query($this->_export())->fetch();}}function -fetchSingle(){if($this->command==='SELECT'){return$this->query($this->_export(NULL,array('%lmt',1)))->fetchSingle();}else{return$this->query($this->_export())->fetchSingle();}}function +fetch(){if ($this->command==='SELECT') {return$this->query($this->_export(NULL,array('%lmt',1)))->fetch();} else {return$this->query($this->_export())->fetch();}}function +fetchSingle(){if ($this->command==='SELECT') {return$this->query($this->_export(NULL,array('%lmt',1)))->fetchSingle();} else {return$this->query($this->_export())->fetchSingle();}}function fetchAll($offset=NULL,$limit=NULL){return$this->query($this->_export(NULL,array('%ofs %lmt',$offset,$limit)))->fetchAll();}function fetchAssoc($assoc){return$this->query($this->_export())->fetchAssoc($assoc);}function fetchPairs($key=NULL,$value=NULL){return$this->query($this->_export())->fetchPairs($key,$value);}function getIterator($offset=NULL,$limit=NULL){return$this->query($this->_export(NULL,array('%ofs %lmt',$offset,$limit)))->getIterator();}function test($clause=NULL){return$this->connection->test($this->_export($clause));}function -count(){return(int)$this->query(array('SELECT COUNT(*) FROM (%ex',$this->_export(),') AS [data]'))->fetchSingle();}private +count(){return(int) $this->query(array('SELECT COUNT(*) FROM (%ex',$this->_export(),') AS [data]'))->fetchSingle();}private function -query($args){$res=$this->connection->query($args);foreach($this->setups -as$setup){call_user_func_array(array($res,array_shift($setup)),$setup);}return$res;}function +query($args){$res=$this->connection->query($args);foreach ($this->setups +as$setup) {call_user_func_array(array($res,array_shift($setup)),$setup);}return$res;}function toDataSource(){return new DibiDataSource($this->connection->translate($this->_export()),$this->connection);}final function -__toString(){try{return$this->connection->translate($this->_export());}catch(Exception$e){trigger_error($e->getMessage(),E_USER_ERROR);}}protected +__toString(){try {return$this->connection->translate($this->_export());} catch (Exception$e) {trigger_error($e->getMessage(),E_USER_ERROR);}}protected function -_export($clause=NULL,$args=array()){if($clause===NULL){$data=$this->clauses;}else{$clause=self::$normalizer->$clause;if(array_key_exists($clause,$this->clauses)){$data=array($clause=>$this->clauses[$clause]);}else{return -array();}}foreach($data -as$clause=>$statement){if($statement!==NULL){$args[]=$clause;if($clause===$this->command&&$this->flags){$args[]=implode(' ',array_keys($this->flags));}foreach($statement +_export($clause=NULL,$args=array()){if ($clause===NULL) {$data=$this->clauses;} else {$clause=self::$normalizer->$clause;if(array_key_exists($clause,$this->clauses)) {$data=array($clause=>$this->clauses[$clause]);} else {return +array();}}foreach ($data +as$clause=>$statement) {if ($statement!==NULL) {$args[]=$clause;if ($clause===$this->command&&$this->flags) {$args[]=implode(' ',array_keys($this->flags));}foreach($statement as$arg)$args[]=$arg;}}return$args;}static function -_formatClause($s){if($s==='order'||$s==='group'){$s.='By';trigger_error("Did you mean '$s'?",E_USER_NOTICE);}return +_formatClause($s){if ($s==='order'||$s==='group') {$s.='By';trigger_error("Did you mean '$s'?",E_USER_NOTICE);}return strtoupper(preg_replace('#[a-z](?=[A-Z])#','$0 ',$s));}function -__clone(){foreach($this->clauses -as$clause=>$val){$this->clauses[$clause]=&$val;unset($val);}$this->cursor=&$foo;}}class +__clone(){foreach ($this->clauses +as$clause=>$val) {$this->clauses[$clause]=&$val;unset($val);}$this->cursor=&$foo;}}class DibiDatabaseInfo extends DibiObject{private$reflector;private$name;private$tables;function @@ -523,15 +523,15 @@ function getName(){return$this->name;}function getTables(){$this->init();return array_values($this->tables);}function -getTableNames(){$this->init();$res=array();foreach($this->tables -as$table){$res[]=$table->getName();}return$res;}function -getTable($name){$this->init();$l=strtolower($name);if(isset($this->tables[$l])){return$this->tables[$l];}else{throw +getTableNames(){$this->init();$res=array();foreach ($this->tables +as$table) {$res[]=$table->getName();}return$res;}function +getTable($name){$this->init();$l=strtolower($name);if (isset($this->tables[$l])) {return$this->tables[$l];} else {throw new DibiException("Database '$this->name' has no table '$name'.");}}function hasTable($name){$this->init();return isset($this->tables[strtolower($name)]);}protected function -init(){if($this->tables===NULL){$this->tables=array();foreach($this->reflector->getTables()as$info){$this->tables[strtolower($info['name'])]=new +init(){if ($this->tables===NULL) {$this->tables=array();foreach($this->reflector->getTables()as$info) {$this->tables[strtolower($info['name'])]=new DibiTableInfo($this->reflector,$info);}}}}class DibiTableInfo extends @@ -541,9 +541,9 @@ function isView(){return$this->view;}function getColumns(){$this->initColumns();return array_values($this->columns);}function -getColumnNames(){$this->initColumns();$res=array();foreach($this->columns -as$column){$res[]=$column->getName();}return$res;}function -getColumn($name){$this->initColumns();$l=strtolower($name);if(isset($this->columns[$l])){return$this->columns[$l];}else{throw +getColumnNames(){$this->initColumns();$res=array();foreach ($this->columns +as$column) {$res[]=$column->getName();}return$res;}function +getColumn($name){$this->initColumns();$l=strtolower($name);if (isset($this->columns[$l])) {return$this->columns[$l];} else {throw new DibiException("Table '$this->name' has no column '$name'.");}}function hasColumn($name){$this->initColumns();return @@ -552,11 +552,11 @@ function getIndexes(){$this->initIndexes();return$this->indexes;}function getPrimaryKey(){$this->initIndexes();return$this->primaryKey;}protected function -initColumns(){if($this->columns===NULL){$this->columns=array();foreach($this->reflector->getColumns($this->name)as$info){$this->columns[strtolower($info['name'])]=new +initColumns(){if ($this->columns===NULL) {$this->columns=array();foreach($this->reflector->getColumns($this->name)as$info) {$this->columns[strtolower($info['name'])]=new DibiColumnInfo($this->reflector,$info);}}}protected function -initIndexes(){if($this->indexes===NULL){$this->initColumns();$this->indexes=array();foreach($this->reflector->getIndexes($this->name)as$info){foreach($info['columns']as$key=>$name){$info['columns'][$key]=$this->columns[strtolower($name)];}$this->indexes[strtolower($info['name'])]=new -DibiIndexInfo($info);if(!empty($info['primary'])){$this->primaryKey=$this->indexes[strtolower($info['name'])];}}}}protected +initIndexes(){if ($this->indexes===NULL) {$this->initColumns();$this->indexes=array();foreach($this->reflector->getIndexes($this->name)as$info){foreach ($info['columns']as$key=>$name) {$info['columns'][$key]=$this->columns[strtolower($name)];}$this->indexes[strtolower($info['name'])]=new +DibiIndexInfo($info);if (!empty($info['primary'])) {$this->primaryKey=$this->indexes[strtolower($info['name'])];}}}}protected function initForeignKeys(){throw new @@ -567,17 +567,17 @@ function __construct(IDibiResultDriver$driver){$this->driver=$driver;}function getColumns(){$this->initColumns();return array_values($this->columns);}function -getColumnNames($fullNames=FALSE){$this->initColumns();$res=array();foreach($this->columns -as$column){$res[]=$fullNames?$column->getFullName():$column->getName();}return$res;}function -getColumn($name){$this->initColumns();$l=strtolower($name);if(isset($this->names[$l])){return$this->names[$l];}else{throw +getColumnNames($fullNames=FALSE){$this->initColumns();$res=array();foreach ($this->columns +as$column) {$res[]=$fullNames?$column->getFullName():$column->getName();}return$res;}function +getColumn($name){$this->initColumns();$l=strtolower($name);if (isset($this->names[$l])) {return$this->names[$l];} else {throw new DibiException("Result set has no column '$name'.");}}function hasColumn($name){$this->initColumns();return isset($this->names[strtolower($name)]);}protected function -initColumns(){if($this->columns===NULL){$this->columns=array();$reflector=$this->driver +initColumns(){if ($this->columns===NULL) {$this->columns=array();$reflector=$this->driver instanceof -IDibiReflector?$this->driver:NULL;foreach($this->driver->getResultColumns()as$info){$this->columns[]=$this->names[$info['name']]=new +IDibiReflector?$this->driver:NULL;foreach ($this->driver->getResultColumns()as$info) {$this->columns[]=$this->names[$info['name']]=new DibiColumnInfo($reflector,$info);}}}}class DibiColumnInfo extends @@ -588,7 +588,7 @@ function getFullName(){return isset($this->info['fullname'])?$this->info['fullname']:NULL;}function hasTable(){return!empty($this->info['table']);}function -getTable(){if(empty($this->info['table'])||!$this->reflector){throw +getTable(){if (empty($this->info['table'])||!$this->reflector) {throw new DibiException("Table is unknown or not available.");}return new @@ -599,23 +599,23 @@ function self::getTypeCache()->{$this->info['nativetype']};}function getNativeType(){return$this->info['nativetype'];}function getSize(){return -isset($this->info['size'])?(int)$this->info['size']:NULL;}function +isset($this->info['size'])?(int) $this->info['size']:NULL;}function isUnsigned(){return -isset($this->info['unsigned'])?(bool)$this->info['unsigned']:NULL;}function +isset($this->info['unsigned'])?(bool) $this->info['unsigned']:NULL;}function isNullable(){return -isset($this->info['nullable'])?(bool)$this->info['nullable']:NULL;}function +isset($this->info['nullable'])?(bool) $this->info['nullable']:NULL;}function isAutoIncrement(){return -isset($this->info['autoincrement'])?(bool)$this->info['autoincrement']:NULL;}function +isset($this->info['autoincrement'])?(bool) $this->info['autoincrement']:NULL;}function getDefault(){return isset($this->info['default'])?$this->info['default']:NULL;}function getVendorInfo($key){return isset($this->info['vendor'][$key])?$this->info['vendor'][$key]:NULL;}static function -detectType($type){static$patterns=array('^_'=>dibi::TEXT,'BYTEA|BLOB|BIN'=>dibi::BINARY,'TEXT|CHAR'=>dibi::TEXT,'YEAR|BYTE|COUNTER|SERIAL|INT|LONG'=>dibi::INTEGER,'CURRENCY|REAL|MONEY|FLOAT|DOUBLE|DECIMAL|NUMERIC|NUMBER'=>dibi::FLOAT,'^TIME$'=>dibi::TIME,'TIME'=>dibi::DATETIME,'DATE'=>dibi::DATE,'BOOL|BIT'=>dibi::BOOL);foreach($patterns -as$s=>$val){if(preg_match("#$s#i",$type)){return$val;}}return +detectType($type){static$patterns=array('^_'=>dibi::TEXT,'BYTEA|BLOB|BIN'=>dibi::BINARY,'TEXT|CHAR'=>dibi::TEXT,'YEAR|BYTE|COUNTER|SERIAL|INT|LONG'=>dibi::INTEGER,'CURRENCY|REAL|MONEY|FLOAT|DOUBLE|DECIMAL|NUMERIC|NUMBER'=>dibi::FLOAT,'^TIME$'=>dibi::TIME,'TIME'=>dibi::DATETIME,'DATE'=>dibi::DATE,'BOOL|BIT'=>dibi::BOOL);foreach ($patterns +as$s=>$val) {if (preg_match("#$s#i",$type)) {return$val;}}return dibi::TEXT;}static function -getTypeCache(){if(self::$types===NULL){self::$types=new +getTypeCache(){if (self::$types===NULL) {self::$types=new DibiHashMap(array(__CLASS__,'detectType'));}return self::$types;}}class DibiForeignKeyInfo @@ -634,18 +634,18 @@ function isPrimary(){return!empty($this->info['primary']);}}class DibiEvent{const CONNECT=1,SELECT=4,INSERT=8,DELETE=16,UPDATE=32,QUERY=60,BEGIN=64,COMMIT=128,ROLLBACK=256,TRANSACTION=448,ALL=1023;public$connection;public$type;public$sql;public$result;public$time;public$count;public$source;function -__construct(DibiConnection$connection,$type,$sql=NULL){$this->connection=$connection;$this->type=$type;$this->sql=trim($sql);$this->time=-microtime(TRUE);if($type===self::QUERY&&preg_match('#\(?\s*(SELECT|UPDATE|INSERT|DELETE)#iA',$this->sql,$matches)){static$types=array('SELECT'=>self::SELECT,'UPDATE'=>self::UPDATE,'INSERT'=>self::INSERT,'DELETE'=>self::DELETE);$this->type=$types[strtoupper($matches[1])];}$rc=new -ReflectionClass('dibi');$dibiDir=dirname($rc->getFileName()).DIRECTORY_SEPARATOR;foreach(debug_backtrace(FALSE)as$row){if(isset($row['file'])&&is_file($row['file'])&&strpos($row['file'],$dibiDir)!==0){$this->source=array($row['file'],(int)$row['line']);break;}}dibi::$elapsedTime=FALSE;dibi::$numOfQueries++;dibi::$sql=$sql;}function -done($result=NULL){$this->result=$result;try{$this->count=$result +__construct(DibiConnection$connection,$type,$sql=NULL){$this->connection=$connection;$this->type=$type;$this->sql=trim($sql);$this->time=-microtime(TRUE);if ($type===self::QUERY&&preg_match('#\(?\s*(SELECT|UPDATE|INSERT|DELETE)#iA',$this->sql,$matches)) {static$types=array('SELECT'=>self::SELECT,'UPDATE'=>self::UPDATE,'INSERT'=>self::INSERT,'DELETE'=>self::DELETE);$this->type=$types[strtoupper($matches[1])];}$rc=new +ReflectionClass('dibi');$dibiDir=dirname($rc->getFileName()).DIRECTORY_SEPARATOR;foreach (debug_backtrace(FALSE)as$row){if(isset($row['file'])&&is_file($row['file'])&&strpos($row['file'],$dibiDir)!==0) {$this->source=array($row['file'],(int) $row['line']);break;}}dibi::$elapsedTime=FALSE;dibi::$numOfQueries++;dibi::$sql=$sql;}function +done($result=NULL){$this->result=$result;try {$this->count=$result instanceof -DibiResult?count($result):NULL;}catch(DibiException$e){$this->count=NULL;}$this->time+=microtime(TRUE);dibi::$elapsedTime=$this->time;dibi::$totalTime+=$this->time;return$this;}}class +DibiResult?count($result):NULL;} catch (DibiException$e) {$this->count=NULL;}$this->time+=microtime(TRUE);dibi::$elapsedTime=$this->time;dibi::$totalTime+=$this->time;return$this;}}class DibiFileLogger extends DibiObject{public$file;public$filter;function -__construct($file,$filter=NULL){$this->file=$file;$this->filter=$filter?(int)$filter:DibiEvent::QUERY;}function -logEvent(DibiEvent$event){if(($event->type&$this->filter)===0){return;}$handle=fopen($this->file,'a');if(!$handle)return;flock($handle,LOCK_EX);if($event->result +__construct($file,$filter=NULL){$this->file=$file;$this->filter=$filter?(int) $filter:DibiEvent::QUERY;}function +logEvent(DibiEvent$event){if (($event->type&$this->filter)===0) {return;}$handle=fopen($this->file,'a');if(!$handle)return;flock($handle,LOCK_EX);if ($event->result instanceof -Exception){$message=$event->result->getMessage();if($code=$event->result->getCode()){$message="[$code] $message";}fwrite($handle,"ERROR: $message"."\n-- SQL: ".$event->sql."\n-- driver: ".$event->connection->getConfig('driver').'/'.$event->connection->getConfig('name').";\n-- ".date('Y-m-d H:i:s')."\n\n");}else{fwrite($handle,"OK: ".$event->sql.($event->count?";\n-- rows: ".$event->count:'')."\n-- takes: ".sprintf('%0.3f',$event->time*1000).' ms'."\n-- source: ".implode(':',$event->source)."\n-- driver: ".$event->connection->getConfig('driver').'/'.$event->connection->getConfig('name')."\n-- ".date('Y-m-d H:i:s')."\n\n");}fclose($handle);}}class +Exception) {$message=$event->result->getMessage();if ($code=$event->result->getCode()) {$message="[$code] $message";}fwrite($handle,"ERROR: $message"."\n-- SQL: ".$event->sql."\n-- driver: ".$event->connection->getConfig('driver').'/'.$event->connection->getConfig('name').";\n-- ".date('Y-m-d H:i:s')."\n\n");} else {fwrite($handle,"OK: ".$event->sql.($event->count?";\n-- rows: ".$event->count:'')."\n-- takes: ".sprintf('%0.3f',$event->time*1000).' ms'."\n-- source: ".implode(':',$event->source)."\n-- driver: ".$event->connection->getConfig('driver').'/'.$event->connection->getConfig('name')."\n-- ".date('Y-m-d H:i:s')."\n\n");}fclose($handle);}}class DibiFirePhpLogger extends DibiObject{static @@ -655,36 +655,36 @@ function function isAvailable(){return isset($_SERVER['HTTP_USER_AGENT'])&&strpos($_SERVER['HTTP_USER_AGENT'],'FirePHP/');}function -__construct($filter=NULL){$this->filter=$filter?(int)$filter:DibiEvent::QUERY;}function -logEvent(DibiEvent$event){if(headers_sent()||($event->type&$this->filter)===0||count(self::$fireTable)>self::$maxQueries){return;}$this->totalTime+=$event->time;$this->numOfQueries++;self::$fireTable[]=array(sprintf('%0.3f',$event->time*1000),strlen($event->sql)>self::$maxLength?substr($event->sql,0,self::$maxLength).'...':$event->sql,$event->result +__construct($filter=NULL){$this->filter=$filter?(int) $filter:DibiEvent::QUERY;}function +logEvent(DibiEvent$event){if (headers_sent()||($event->type&$this->filter)===0||count(self::$fireTable)>self::$maxQueries) {return;}$this->totalTime+=$event->time;$this->numOfQueries++;self::$fireTable[]=array(sprintf('%0.3f',$event->time*1000),strlen($event->sql)>self::$maxLength?substr($event->sql,0,self::$maxLength).'...':$event->sql,$event->result instanceof -Exception?'ERROR':(string)$event->count,$event->connection->getConfig('driver').'/'.$event->connection->getConfig('name'));header('X-Wf-Protocol-dibi: http://meta.wildfirehq.org/Protocol/JsonStream/0.2');header('X-Wf-dibi-Plugin-1: http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.2.0');header('X-Wf-dibi-Structure-1: http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');$payload=json_encode(array(array('Type'=>'TABLE','Label'=>'dibi profiler ('.$this->numOfQueries.' SQL queries took '.sprintf('%0.3f',$this->totalTime*1000).' ms)'),self::$fireTable));foreach(str_split($payload,4990)as$num=>$s){$num++;header("X-Wf-dibi-1-1-d$num: |$s|\\");}header("X-Wf-dibi-1-1-d$num: |$s|");}}if(interface_exists('Nette\Diagnostics\IBarPanel')||interface_exists('IBarPanel')){if(interface_exists('Nette\Diagnostics\IBarPanel')){class_alias('Nette\Diagnostics\IBarPanel','IBarPanel');}class +Exception?'ERROR':(string) $event->count,$event->connection->getConfig('driver').'/'.$event->connection->getConfig('name'));header('X-Wf-Protocol-dibi: http://meta.wildfirehq.org/Protocol/JsonStream/0.2');header('X-Wf-dibi-Plugin-1: http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.2.0');header('X-Wf-dibi-Structure-1: http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');$payload=json_encode(array(array('Type'=>'TABLE','Label'=>'dibi profiler ('.$this->numOfQueries.' SQL queries took '.sprintf('%0.3f',$this->totalTime*1000).' ms)'),self::$fireTable));foreach (str_split($payload,4990)as$num=>$s){$num++;header("X-Wf-dibi-1-1-d$num: |$s|\\");}header("X-Wf-dibi-1-1-d$num: |$s|");}}if(interface_exists('Nette\Diagnostics\IBarPanel')||interface_exists('IBarPanel')){if(interface_exists('Nette\Diagnostics\IBarPanel')) {class_alias('Nette\Diagnostics\IBarPanel','IBarPanel');}class DibiNettePanel extends DibiObject implements IBarPanel{static public$maxLength=1000;public$explain;public$filter;private$events=array();function -__construct($explain=TRUE,$filter=NULL){$this->filter=$filter?(int)$filter:DibiEvent::QUERY;$this->explain=$explain;}function -register(DibiConnection$connection){if(is_callable('Nette\Diagnostics\Debugger::enable')&&!class_exists('NDebugger')){class_alias('Nette\Diagnostics\Debugger','NDebugger');}if(is_callable('NDebugger::enable')){NDebugger::$bar&&NDebugger::$bar->addPanel($this);NDebugger::$blueScreen&&NDebugger::$blueScreen->addPanel(array($this,'renderException'),__CLASS__);$connection->onEvent[]=array($this,'logEvent');}elseif(is_callable('Debugger::enable')){Debugger::$bar&&Debugger::$bar->addPanel($this);Debugger::$blueScreen&&Debugger::$blueScreen->addPanel(array($this,'renderException'),__CLASS__);$connection->onEvent[]=array($this,'logEvent');}}function -logEvent(DibiEvent$event){if(($event->type&$this->filter)===0){return;}$this->events[]=$event;}function +__construct($explain=TRUE,$filter=NULL){$this->filter=$filter?(int) $filter:DibiEvent::QUERY;$this->explain=$explain;}function +register(DibiConnection$connection){if (is_callable('Nette\Diagnostics\Debugger::enable')&&!class_exists('NDebugger')){class_alias('Nette\Diagnostics\Debugger','NDebugger');}if(is_callable('NDebugger::enable')){NDebugger::$bar&&NDebugger::$bar->addPanel($this);NDebugger::$blueScreen&&NDebugger::$blueScreen->addPanel(array($this,'renderException'),__CLASS__);$connection->onEvent[]=array($this,'logEvent');} elseif (is_callable('Debugger::enable')) {Debugger::$bar&&Debugger::$bar->addPanel($this);Debugger::$blueScreen&&Debugger::$blueScreen->addPanel(array($this,'renderException'),__CLASS__);$connection->onEvent[]=array($this,'logEvent');}}function +logEvent(DibiEvent$event){if (($event->type&$this->filter)===0) {return;}$this->events[]=$event;}function renderException($e){if($e instanceof DibiException&&$e->getSql()){return array('tab'=>'SQL','panel'=>dibi::dump($e->getSql(),TRUE));}}function -getTab(){$totalTime=0;foreach($this->events -as$event){$totalTime+=$event->time;}return''.count($this->events).' queries'.($totalTime?' / '.sprintf('%0.1f',$totalTime*1000).'ms':'').'';}function -getPanel(){$totalTime=$s=NULL;$h='htmlSpecialChars';foreach($this->events -as$event){$totalTime+=$event->time;$explain=NULL;if($this->explain&&$event->type===DibiEvent::SELECT){try{$backup=array($event->connection->onEvent,dibi::$numOfQueries,dibi::$totalTime);$event->connection->onEvent=NULL;$cmd=is_string($this->explain)?$this->explain:($event->connection->getConfig('driver')==='oracle'?'EXPLAIN PLAN':'EXPLAIN');$explain=dibi::dump($event->connection->nativeQuery("$cmd $event->sql"),TRUE);}catch(DibiException$e){}list($event->connection->onEvent,dibi::$numOfQueries,dibi::$totalTime)=$backup;}$s.=''.sprintf('%0.3f',$event->time*1000);if($explain){static$counter;$counter++;$s.="
    explain ►";}$s.=''.dibi::dump(strlen($event->sql)>self::$maxLength?substr($event->sql,0,self::$maxLength).'...':$event->sql,TRUE);if($explain){$s.="
    {$explain}
    ";}if($event->source){$helpers='Nette\Diagnostics\Helpers';if(!class_exists($helpers)){$helpers=class_exists('NDebugHelpers')?'NDebugHelpers':'DebugHelpers';}$s.=call_user_func(array($helpers,'editorLink'),$event->source[0],$event->source[1])->class('nette-DibiProfiler-source');}$s.="{$event->count}{$h($event->connection->getConfig('driver').'/'.$event->connection->getConfig('name'))}";}return +getTab(){$totalTime=0;foreach ($this->events +as$event) {$totalTime+=$event->time;}return''.count($this->events).' queries'.($totalTime?' / '.sprintf('%0.1f',$totalTime*1000).'ms':'').'';}function +getPanel(){$totalTime=$s=NULL;$h='htmlSpecialChars';foreach ($this->events +as$event) {$totalTime+=$event->time;$explain=NULL;if ($this->explain&&$event->type===DibiEvent::SELECT) {try {$backup=array($event->connection->onEvent,dibi::$numOfQueries,dibi::$totalTime);$event->connection->onEvent=NULL;$cmd=is_string($this->explain)?$this->explain:($event->connection->getConfig('driver')==='oracle'?'EXPLAIN PLAN':'EXPLAIN');$explain=dibi::dump($event->connection->nativeQuery("$cmd $event->sql"),TRUE);} catch (DibiException$e){}list($event->connection->onEvent,dibi::$numOfQueries,dibi::$totalTime)=$backup;}$s.=''.sprintf('%0.3f',$event->time*1000);if ($explain) {static$counter;$counter++;$s.="
    explain ►";}$s.=''.dibi::dump(strlen($event->sql)>self::$maxLength?substr($event->sql,0,self::$maxLength).'...':$event->sql,TRUE);if ($explain) {$s.="
    {$explain}
    ";}if ($event->source) {$helpers='Nette\Diagnostics\Helpers';if(!class_exists($helpers)) {$helpers=class_exists('NDebugHelpers')?'NDebugHelpers':'DebugHelpers';}$s.=call_user_func(array($helpers,'editorLink'),$event->source[0],$event->source[1])->class('nette-DibiProfiler-source');}$s.="{$event->count}{$h($event->connection->getConfig('driver').'/'.$event->connection->getConfig('name'))}";}return empty($this->events)?'':' -

    Queries: '.count($this->events).($totalTime===NULL?'':', time: '.sprintf('%0.3f',$totalTime*1000).' ms').'

    -
    - - '.$s.' -
    Time msSQL StatementRowsConnection
    -
    ';}}}class + #nette-debug .nette-DibiProfiler-source { color: #999 !important } + #nette-debug nette-DibiProfiler tr table { margin: 8px 0; max-height: 150px; overflow:auto } +

    Queries: '.count($this->events).($totalTime===NULL?'':', time: '.sprintf('%0.3f',$totalTime*1000).' ms').'

    +
    + + '.$s.' +
    Time msSQL StatementRowsConnection
    +
    ';}}}class dibi{const TEXT='s',BINARY='bin',BOOL='b',INTEGER='i',FLOAT='f',DATE='d',DATETIME='t',TIME='t';const IDENTIFIER='n';const @@ -712,10 +712,10 @@ function function isConnected(){return(self::$connection!==NULL)&&self::$connection->isConnected();}static function -getConnection($name=NULL){if($name===NULL){if(self::$connection===NULL){throw +getConnection($name=NULL){if ($name===NULL) {if (self::$connection===NULL) {throw new DibiException('Dibi is not connected to database.');}return -self::$connection;}if(!isset(self::$registry[$name])){throw +self::$connection;}if (!isset(self::$registry[$name])) {throw new DibiException("There is no connection named '$name'.");}return self::$registry[$name];}static @@ -804,16 +804,16 @@ function function addSubst($expr,$subst){trigger_error(__METHOD__.'() is deprecated; use dibi::getSubstitutes()->expr = val; instead.',E_USER_WARNING);self::getSubstitutes()->$expr=$subst;}static function -removeSubst($expr){trigger_error(__METHOD__.'() is deprecated; use unset(dibi::getSubstitutes()->expr) instead.',E_USER_WARNING);$substitutes=self::getSubstitutes();if($expr===TRUE){foreach($substitutes -as$expr=>$foo){unset($substitutes->$expr);}}else{unset($substitutes->$expr);}}static +removeSubst($expr){trigger_error(__METHOD__.'() is deprecated; use unset(dibi::getSubstitutes()->expr) instead.',E_USER_WARNING);$substitutes=self::getSubstitutes();if ($expr===TRUE) {foreach ($substitutes +as$expr=>$foo) {unset($substitutes->$expr);}} else {unset($substitutes->$expr);}}static function setSubstFallback($callback){trigger_error(__METHOD__.'() is deprecated; use dibi::getSubstitutes()->setCallback() instead.',E_USER_WARNING);self::getSubstitutes()->setCallback($callback);}static function -dump($sql=NULL,$return=FALSE){ob_start();if($sql +dump($sql=NULL,$return=FALSE){ob_start();if ($sql instanceof -DibiResult){$sql->dump();}else{if($sql===NULL)$sql=self::$sql;static$keywords1='SELECT|(?:ON\s+DUPLICATE\s+KEY)?UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|CALL|UNION|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE';static$keywords2='ALL|DISTINCT|DISTINCTROW|IGNORE|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|LIKE|RLIKE|REGEXP|TRUE|FALSE';$sql=" $sql ";$sql=preg_replace("#(?<=[\\s,(])($keywords1)(?=[\\s,)])#i","\n\$1",$sql);$sql=preg_replace('#[ \t]{2,}#'," ",$sql);$sql=wordwrap($sql,100);$sql=preg_replace("#([ \t]*\r?\n){2,}#","\n",$sql);if(PHP_SAPI==='cli'){echo -trim($sql)."\n\n";}else{$sql=htmlSpecialChars($sql);$sql=preg_replace_callback("#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|(?<=[\\s,(])($keywords1)(?=[\\s,)])|(?<=[\\s,(=])($keywords2)(?=[\\s,)=])#is",array('dibi','highlightCallback'),$sql);echo'
    ',trim($sql),"
    \n";}}if($return){return -ob_get_clean();}else{ob_end_flush();}}private +DibiResult) {$sql->dump();} else {if ($sql===NULL)$sql=self::$sql;static$keywords1='SELECT|(?:ON\s+DUPLICATE\s+KEY)?UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|CALL|UNION|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE';static$keywords2='ALL|DISTINCT|DISTINCTROW|IGNORE|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|LIKE|RLIKE|REGEXP|TRUE|FALSE';$sql=" $sql ";$sql=preg_replace("#(?<=[\\s,(])($keywords1)(?=[\\s,)])#i","\n\$1",$sql);$sql=preg_replace('#[ \t]{2,}#'," ",$sql);$sql=wordwrap($sql,100);$sql=preg_replace("#([ \t]*\r?\n){2,}#","\n",$sql);if (PHP_SAPI==='cli') {echo +trim($sql)."\n\n";} else {$sql=htmlSpecialChars($sql);$sql=preg_replace_callback("#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|(?<=[\\s,(])($keywords1)(?=[\\s,)])|(?<=[\\s,(=])($keywords2)(?=[\\s,)=])#is",array('dibi','highlightCallback'),$sql);echo'
    ',trim($sql),"
    \n";}}if ($return) {return +ob_get_clean();} else {ob_end_flush();}}private static function highlightCallback($matches){if(!empty($matches[1]))return''.$matches[1].'';if(!empty($matches[2]))return''.$matches[2].'';if(!empty($matches[3]))return''.$matches[3].'';if(!empty($matches[4]))return''.$matches[4].'';}}class @@ -823,9 +823,9 @@ function implements IDibiReflector{private$driver;function __construct(IDibiDriver$driver){$this->driver=$driver;}function -getTables(){$res=$this->driver->query("SHOW FULL TABLES");$tables=array();while($row=$res->fetch(FALSE)){$tables[]=array('name'=>$row[0],'view'=>isset($row[1])&&$row[1]==='VIEW');}return$tables;}function -getColumns($table){$res=$this->driver->query("SHOW FULL COLUMNS FROM {$this->driver->escape($table,dibi::IDENTIFIER)}");$columns=array();while($row=$res->fetch(TRUE)){$type=explode('(',$row['Type']);$columns[]=array('name'=>$row['Field'],'table'=>$table,'nativetype'=>strtoupper($type[0]),'size'=>isset($type[1])?(int)$type[1]:NULL,'unsigned'=>(bool)strstr($row['Type'],'unsigned'),'nullable'=>$row['Null']==='YES','default'=>$row['Default'],'autoincrement'=>$row['Extra']==='auto_increment','vendor'=>$row);}return$columns;}function -getIndexes($table){$res=$this->driver->query("SHOW INDEX FROM {$this->driver->escape($table,dibi::IDENTIFIER)}");$indexes=array();while($row=$res->fetch(TRUE)){$indexes[$row['Key_name']]['name']=$row['Key_name'];$indexes[$row['Key_name']]['unique']=!$row['Non_unique'];$indexes[$row['Key_name']]['primary']=$row['Key_name']==='PRIMARY';$indexes[$row['Key_name']]['columns'][$row['Seq_in_index']-1]=$row['Column_name'];}return +getTables(){$res=$this->driver->query("SHOW FULL TABLES");$tables=array();while ($row=$res->fetch(FALSE)) {$tables[]=array('name'=>$row[0],'view'=>isset($row[1])&&$row[1]==='VIEW');}return$tables;}function +getColumns($table){$res=$this->driver->query("SHOW FULL COLUMNS FROM {$this->driver->escape($table,dibi::IDENTIFIER)}");$columns=array();while ($row=$res->fetch(TRUE)) {$type=explode('(',$row['Type']);$columns[]=array('name'=>$row['Field'],'table'=>$table,'nativetype'=>strtoupper($type[0]),'size'=>isset($type[1])?(int) $type[1]:NULL,'unsigned'=>(bool) strstr($row['Type'],'unsigned'),'nullable'=>$row['Null']==='YES','default'=>$row['Default'],'autoincrement'=>$row['Extra']==='auto_increment','vendor'=>$row);}return$columns;}function +getIndexes($table){$res=$this->driver->query("SHOW INDEX FROM {$this->driver->escape($table,dibi::IDENTIFIER)}");$indexes=array();while ($row=$res->fetch(TRUE)) {$indexes[$row['Key_name']]['name']=$row['Key_name'];$indexes[$row['Key_name']]['unique']=!$row['Non_unique'];$indexes[$row['Key_name']]['primary']=$row['Key_name']==='PRIMARY';$indexes[$row['Key_name']]['columns'][$row['Seq_in_index']-1]=$row['Column_name'];}return array_values($indexes);}function getForeignKeys($table){throw new @@ -838,22 +838,22 @@ function ERROR_ACCESS_DENIED=1045;const ERROR_DUPLICATE_ENTRY=1062;const ERROR_DATA_TRUNCATED=1265;private$connection;private$resultSet;private$autoFree=TRUE;private$buffered;function -__construct(){if(!extension_loaded('mysql')){throw +__construct(){if (!extension_loaded('mysql')) {throw new DibiNotSupportedException("PHP extension 'mysql' is not loaded.");}}function -connect(array&$config){if(isset($config['resource'])){$this->connection=$config['resource'];}else{DibiConnection::alias($config,'flags','options');if(!isset($config['charset']))$config['charset']='utf8';if(!isset($config['username']))$config['username']=ini_get('mysql.default_user');if(!isset($config['password']))$config['password']=ini_get('mysql.default_password');if(!isset($config['host'])){$host=ini_get('mysql.default_host');if($host){$config['host']=$host;$config['port']=ini_get('mysql.default_port');}else{if(!isset($config['socket']))$config['socket']=ini_get('mysql.default_socket');$config['host']=NULL;}}if(empty($config['socket'])){$host=$config['host'].(empty($config['port'])?'':':'.$config['port']);}else{$host=':'.$config['socket'];}if(empty($config['persistent'])){$this->connection=@mysql_connect($host,$config['username'],$config['password'],TRUE,$config['flags']);}else{$this->connection=@mysql_pconnect($host,$config['username'],$config['password'],$config['flags']);}}if(!is_resource($this->connection)){throw +connect(array&$config){if (isset($config['resource'])){$this->connection=$config['resource'];} else {DibiConnection::alias($config,'flags','options');if(!isset($config['charset']))$config['charset']='utf8';if(!isset($config['username']))$config['username']=ini_get('mysql.default_user');if(!isset($config['password']))$config['password']=ini_get('mysql.default_password');if(!isset($config['host'])){$host=ini_get('mysql.default_host');if ($host) {$config['host']=$host;$config['port']=ini_get('mysql.default_port');} else {if(!isset($config['socket']))$config['socket']=ini_get('mysql.default_socket');$config['host']=NULL;}}if(empty($config['socket'])){$host=$config['host'].(empty($config['port'])?'':':'.$config['port']);} else {$host=':'.$config['socket'];}if(empty($config['persistent'])){$this->connection=@mysql_connect($host,$config['username'],$config['password'],TRUE,$config['flags']);} else {$this->connection=@mysql_pconnect($host,$config['username'],$config['password'],$config['flags']);}}if(!is_resource($this->connection)) {throw new -DibiDriverException(mysql_error(),mysql_errno());}if(isset($config['charset'])){$ok=FALSE;if(function_exists('mysql_set_charset')){$ok=@mysql_set_charset($config['charset'],$this->connection);}if(!$ok){$this->query("SET NAMES '$config[charset]'");}}if(isset($config['database'])){if(!@mysql_select_db($config['database'],$this->connection)){throw +DibiDriverException(mysql_error(),mysql_errno());}if (isset($config['charset'])){$ok=FALSE;if(function_exists('mysql_set_charset')){$ok=@mysql_set_charset($config['charset'],$this->connection);}if (!$ok) {$this->query("SET NAMES '$config[charset]'");}}if(isset($config['database'])){if(!@mysql_select_db($config['database'],$this->connection)) {throw new -DibiDriverException(mysql_error($this->connection),mysql_errno($this->connection));}}if(isset($config['sqlmode'])){$this->query("SET sql_mode='$config[sqlmode]'");}$this->query("SET time_zone='".date('P')."'");$this->buffered=empty($config['unbuffered']);}function +DibiDriverException(mysql_error($this->connection),mysql_errno($this->connection));}}if (isset($config['sqlmode'])) {$this->query("SET sql_mode='$config[sqlmode]'");}$this->query("SET time_zone='".date('P')."'");$this->buffered=empty($config['unbuffered']);}function disconnect(){mysql_close($this->connection);}function -query($sql){if($this->buffered){$res=@mysql_query($sql,$this->connection);}else{$res=@mysql_unbuffered_query($sql,$this->connection);}if(mysql_errno($this->connection)){throw +query($sql){if ($this->buffered) {$res=@mysql_query($sql,$this->connection);} else {$res=@mysql_unbuffered_query($sql,$this->connection);}if(mysql_errno($this->connection)) {throw new -DibiDriverException(mysql_error($this->connection),mysql_errno($this->connection),$sql);}elseif(is_resource($res)){return$this->createResultDriver($res);}}function +DibiDriverException(mysql_error($this->connection),mysql_errno($this->connection),$sql);} elseif (is_resource($res)) {return$this->createResultDriver($res);}}function getInfo(){$res=array();preg_match_all('#(.+?): +(\d+) *#',mysql_info($this->connection),$matches,PREG_SET_ORDER);if(preg_last_error())throw new -DibiPcreException;foreach($matches -as$m){$res[$m[1]]=(int)$m[2];}return$res;}function +DibiPcreException;foreach ($matches +as$m) {$res[$m[1]]=(int) $m[2];}return$res;}function getAffectedRows(){return mysql_affected_rows($this->connection);}function getInsertId($sequence){return @@ -867,11 +867,11 @@ function new DibiMySqlReflector($this);}function createResultDriver($resource){$res=clone$this;$res->resultSet=$resource;return$res;}function -escape($value,$type){switch($type){case -dibi::TEXT:if(!is_resource($this->connection)){throw +escape($value,$type){switch ($type) {case +dibi::TEXT:if (!is_resource($this->connection)) {throw new DibiException('Lost connection to server.');}return"'".mysql_real_escape_string($value,$this->connection)."'";case -dibi::BINARY:if(!is_resource($this->connection)){throw +dibi::BINARY:if (!is_resource($this->connection)) {throw new DibiException('Lost connection to server.');}return"_binary'".mysql_real_escape_string($value,$this->connection)."'";case dibi::IDENTIFIER:return'`'.str_replace('`','``',$value).'`';case @@ -885,23 +885,23 @@ function new InvalidArgumentException('Unsupported type.');}}function escapeLike($value,$pos){$value=addcslashes(str_replace('\\','\\\\',$value),"\x00\n\r\\'%_");return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}function -unescape($value,$type){if($type===dibi::BINARY){return$value;}throw +unescape($value,$type){if ($type===dibi::BINARY) {return$value;}throw new InvalidArgumentException('Unsupported type.');}function -applyLimit(&$sql,$limit,$offset){if($limit<0&&$offset<1)return;$sql.=' LIMIT '.($limit<0?'18446744073709551615':(int)$limit).($offset>0?' OFFSET '.(int)$offset:'');}function +applyLimit(&$sql,$limit,$offset){if($limit<0&&$offset<1)return;$sql.=' LIMIT '.($limit<0?'18446744073709551615':(int) $limit).($offset>0?' OFFSET '.(int) $offset:'');}function __destruct(){$this->autoFree&&$this->getResultResource()&&$this->free();}function -getRowCount(){if(!$this->buffered){throw +getRowCount(){if (!$this->buffered) {throw new DibiNotSupportedException('Row count is not available for unbuffered queries.');}return mysql_num_rows($this->resultSet);}function fetch($assoc){return mysql_fetch_array($this->resultSet,$assoc?MYSQL_ASSOC:MYSQL_NUM);}function -seek($row){if(!$this->buffered){throw +seek($row){if (!$this->buffered) {throw new DibiNotSupportedException('Cannot seek an unbuffered result set.');}return mysql_data_seek($this->resultSet,$row);}function free(){mysql_free_result($this->resultSet);$this->resultSet=NULL;}function -getResultColumns(){$count=mysql_num_fields($this->resultSet);$columns=array();for($i=0;$i<$count;$i++){$row=(array)mysql_fetch_field($this->resultSet,$i);$columns[]=array('name'=>$row['name'],'table'=>$row['table'],'fullname'=>$row['table']?$row['table'].'.'.$row['name']:$row['name'],'nativetype'=>strtoupper($row['type']),'vendor'=>$row);}return$columns;}function +getResultColumns(){$count=mysql_num_fields($this->resultSet);$columns=array();for ($i=0;$i<$count;$i++) {$row=(array) mysql_fetch_field($this->resultSet,$i);$columns[]=array('name'=>$row['name'],'table'=>$row['table'],'fullname'=>$row['table']?$row['table'].'.'.$row['name']:$row['name'],'nativetype'=>strtoupper($row['type']),'vendor'=>$row);}return$columns;}function getResultResource(){$this->autoFree=FALSE;return is_resource($this->resultSet)?$this->resultSet:NULL;}}class DibiMySqliDriver @@ -912,20 +912,20 @@ function ERROR_ACCESS_DENIED=1045;const ERROR_DUPLICATE_ENTRY=1062;const ERROR_DATA_TRUNCATED=1265;private$connection;private$resultSet;private$autoFree=TRUE;private$buffered;function -__construct(){if(!extension_loaded('mysqli')){throw +__construct(){if (!extension_loaded('mysqli')) {throw new DibiNotSupportedException("PHP extension 'mysqli' is not loaded.");}}function -connect(array&$config){mysqli_report(MYSQLI_REPORT_OFF);if(isset($config['resource'])){$this->connection=$config['resource'];}else{if(!isset($config['charset']))$config['charset']='utf8';if(!isset($config['username']))$config['username']=ini_get('mysqli.default_user');if(!isset($config['password']))$config['password']=ini_get('mysqli.default_pw');if(!isset($config['socket']))$config['socket']=ini_get('mysqli.default_socket');if(!isset($config['port']))$config['port']=NULL;if(!isset($config['host'])){$host=ini_get('mysqli.default_host');if($host){$config['host']=$host;$config['port']=ini_get('mysqli.default_port');}else{$config['host']=NULL;$config['port']=NULL;}}$foo=&$config['flags'];$foo=&$config['database'];$this->connection=mysqli_init();if(isset($config['options'])){if(is_scalar($config['options'])){$config['flags']=$config['options'];trigger_error(__CLASS__.": configuration item 'options' must be array; for constants MYSQLI_CLIENT_* use 'flags'.",E_USER_NOTICE);}else{foreach((array)$config['options']as$key=>$value){mysqli_options($this->connection,$key,$value);}}}@mysqli_real_connect($this->connection,(empty($config['persistent'])?'':'p:').$config['host'],$config['username'],$config['password'],$config['database'],$config['port'],$config['socket'],$config['flags']);if($errno=mysqli_connect_errno()){throw +connect(array&$config){mysqli_report(MYSQLI_REPORT_OFF);if (isset($config['resource'])){$this->connection=$config['resource'];} else {if(!isset($config['charset']))$config['charset']='utf8';if(!isset($config['username']))$config['username']=ini_get('mysqli.default_user');if(!isset($config['password']))$config['password']=ini_get('mysqli.default_pw');if(!isset($config['socket']))$config['socket']=ini_get('mysqli.default_socket');if(!isset($config['port']))$config['port']=NULL;if(!isset($config['host'])){$host=ini_get('mysqli.default_host');if ($host) {$config['host']=$host;$config['port']=ini_get('mysqli.default_port');} else {$config['host']=NULL;$config['port']=NULL;}}$foo=&$config['flags'];$foo=&$config['database'];$this->connection=mysqli_init();if(isset($config['options'])){if(is_scalar($config['options'])){$config['flags']=$config['options'];trigger_error(__CLASS__.": configuration item 'options' must be array; for constants MYSQLI_CLIENT_* use 'flags'.",E_USER_NOTICE);} else {foreach((array) $config['options']as$key=>$value){mysqli_options($this->connection,$key,$value);}}}@mysqli_real_connect($this->connection,(empty($config['persistent'])?'':'p:').$config['host'],$config['username'],$config['password'],$config['database'],$config['port'],$config['socket'],$config['flags']);if($errno=mysqli_connect_errno()) {throw new -DibiDriverException(mysqli_connect_error(),$errno);}}if(isset($config['charset'])){$ok=FALSE;if(version_compare(PHP_VERSION,'5.1.5','>=')){$ok=@mysqli_set_charset($this->connection,$config['charset']);}if(!$ok){$this->query("SET NAMES '$config[charset]'");}}if(isset($config['sqlmode'])){$this->query("SET sql_mode='$config[sqlmode]'");}$this->query("SET time_zone='".date('P')."'");$this->buffered=empty($config['unbuffered']);}function +DibiDriverException(mysqli_connect_error(),$errno);}}if (isset($config['charset'])){$ok=FALSE;if(version_compare(PHP_VERSION,'5.1.5','>=')){$ok=@mysqli_set_charset($this->connection,$config['charset']);}if (!$ok) {$this->query("SET NAMES '$config[charset]'");}}if(isset($config['sqlmode'])) {$this->query("SET sql_mode='$config[sqlmode]'");}$this->query("SET time_zone='".date('P')."'");$this->buffered=empty($config['unbuffered']);}function disconnect(){mysqli_close($this->connection);}function -query($sql){$res=@mysqli_query($this->connection,$sql,$this->buffered?MYSQLI_STORE_RESULT:MYSQLI_USE_RESULT);if(mysqli_errno($this->connection)){throw +query($sql){$res=@mysqli_query($this->connection,$sql,$this->buffered?MYSQLI_STORE_RESULT:MYSQLI_USE_RESULT);if (mysqli_errno($this->connection)) {throw new -DibiDriverException(mysqli_error($this->connection),mysqli_errno($this->connection),$sql);}elseif(is_object($res)){return$this->createResultDriver($res);}}function +DibiDriverException(mysqli_error($this->connection),mysqli_errno($this->connection),$sql);} elseif (is_object($res)) {return$this->createResultDriver($res);}}function getInfo(){$res=array();preg_match_all('#(.+?): +(\d+) *#',mysqli_info($this->connection),$matches,PREG_SET_ORDER);if(preg_last_error())throw new -DibiPcreException;foreach($matches -as$m){$res[$m[1]]=(int)$m[2];}return$res;}function +DibiPcreException;foreach ($matches +as$m) {$res[$m[1]]=(int) $m[2];}return$res;}function getAffectedRows(){return mysqli_affected_rows($this->connection);}function getInsertId($sequence){return @@ -938,7 +938,7 @@ function new DibiMySqlReflector($this);}function createResultDriver(mysqli_result$resource){$res=clone$this;$res->resultSet=$resource;return$res;}function -escape($value,$type){switch($type){case +escape($value,$type){switch ($type) {case dibi::TEXT:return"'".mysqli_real_escape_string($this->connection,$value)."'";case dibi::BINARY:return"_binary'".mysqli_real_escape_string($this->connection,$value)."'";case dibi::IDENTIFIER:return'`'.str_replace('`','``',$value).'`';case @@ -952,50 +952,50 @@ function new InvalidArgumentException('Unsupported type.');}}function escapeLike($value,$pos){$value=addcslashes(str_replace('\\','\\\\',$value),"\x00\n\r\\'%_");return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}function -unescape($value,$type){if($type===dibi::BINARY){return$value;}throw +unescape($value,$type){if ($type===dibi::BINARY) {return$value;}throw new InvalidArgumentException('Unsupported type.');}function -applyLimit(&$sql,$limit,$offset){if($limit<0&&$offset<1)return;$sql.=' LIMIT '.($limit<0?'18446744073709551615':(int)$limit).($offset>0?' OFFSET '.(int)$offset:'');}function +applyLimit(&$sql,$limit,$offset){if($limit<0&&$offset<1)return;$sql.=' LIMIT '.($limit<0?'18446744073709551615':(int) $limit).($offset>0?' OFFSET '.(int) $offset:'');}function __destruct(){$this->autoFree&&$this->getResultResource()&&@$this->free();}function -getRowCount(){if(!$this->buffered){throw +getRowCount(){if (!$this->buffered) {throw new DibiNotSupportedException('Row count is not available for unbuffered queries.');}return mysqli_num_rows($this->resultSet);}function fetch($assoc){return mysqli_fetch_array($this->resultSet,$assoc?MYSQLI_ASSOC:MYSQLI_NUM);}function -seek($row){if(!$this->buffered){throw +seek($row){if (!$this->buffered) {throw new DibiNotSupportedException('Cannot seek an unbuffered result set.');}return mysqli_data_seek($this->resultSet,$row);}function free(){mysqli_free_result($this->resultSet);$this->resultSet=NULL;}function -getResultColumns(){static$types;if(empty($types)){$consts=get_defined_constants(TRUE);foreach($consts['mysqli']as$key=>$value){if(strncmp($key,'MYSQLI_TYPE_',12)===0){$types[$value]=substr($key,12);}}$types[MYSQLI_TYPE_TINY]=$types[MYSQLI_TYPE_SHORT]=$types[MYSQLI_TYPE_LONG]='INT';}$count=mysqli_num_fields($this->resultSet);$columns=array();for($i=0;$i<$count;$i++){$row=(array)mysqli_fetch_field_direct($this->resultSet,$i);$columns[]=array('name'=>$row['name'],'table'=>$row['orgtable'],'fullname'=>$row['table']?$row['table'].'.'.$row['name']:$row['name'],'nativetype'=>$types[$row['type']],'vendor'=>$row);}return$columns;}function +getResultColumns(){static$types;if (empty($types)){$consts=get_defined_constants(TRUE);foreach ($consts['mysqli']as$key=>$value) {if(strncmp($key,'MYSQLI_TYPE_',12)===0){$types[$value]=substr($key,12);}}$types[MYSQLI_TYPE_TINY]=$types[MYSQLI_TYPE_SHORT]=$types[MYSQLI_TYPE_LONG]='INT';}$count=mysqli_num_fields($this->resultSet);$columns=array();for ($i=0;$i<$count;$i++) {$row=(array) mysqli_fetch_field_direct($this->resultSet,$i);$columns[]=array('name'=>$row['name'],'table'=>$row['orgtable'],'fullname'=>$row['table']?$row['table'].'.'.$row['name']:$row['name'],'nativetype'=>$types[$row['type']],'vendor'=>$row);}return$columns;}function getResultResource(){$this->autoFree=FALSE;return@$this->resultSet->type===NULL?NULL:$this->resultSet;}}class DibiOdbcDriver extends DibiObject implements IDibiDriver,IDibiResultDriver,IDibiReflector{private$connection;private$resultSet;private$autoFree=TRUE;private$affectedRows=FALSE;private$row=0;function -__construct(){if(!extension_loaded('odbc')){throw +__construct(){if (!extension_loaded('odbc')) {throw new DibiNotSupportedException("PHP extension 'odbc' is not loaded.");}}function -connect(array&$config){if(isset($config['resource'])){$this->connection=$config['resource'];}else{if(!isset($config['username']))$config['username']=ini_get('odbc.default_user');if(!isset($config['password']))$config['password']=ini_get('odbc.default_pw');if(!isset($config['dsn']))$config['dsn']=ini_get('odbc.default_db');if(empty($config['persistent'])){$this->connection=@odbc_connect($config['dsn'],$config['username'],$config['password']);}else{$this->connection=@odbc_pconnect($config['dsn'],$config['username'],$config['password']);}}if(!is_resource($this->connection)){throw +connect(array&$config){if (isset($config['resource'])){$this->connection=$config['resource'];} else {if(!isset($config['username']))$config['username']=ini_get('odbc.default_user');if(!isset($config['password']))$config['password']=ini_get('odbc.default_pw');if(!isset($config['dsn']))$config['dsn']=ini_get('odbc.default_db');if(empty($config['persistent'])){$this->connection=@odbc_connect($config['dsn'],$config['username'],$config['password']);} else {$this->connection=@odbc_pconnect($config['dsn'],$config['username'],$config['password']);}}if(!is_resource($this->connection)) {throw new DibiDriverException(odbc_errormsg().' '.odbc_error());}}function disconnect(){odbc_close($this->connection);}function -query($sql){$this->affectedRows=FALSE;$res=@odbc_exec($this->connection,$sql);if($res===FALSE){throw +query($sql){$this->affectedRows=FALSE;$res=@odbc_exec($this->connection,$sql);if ($res===FALSE) {throw new -DibiDriverException(odbc_errormsg($this->connection).' '.odbc_error($this->connection),0,$sql);}elseif(is_resource($res)){$this->affectedRows=odbc_num_rows($res);return$this->createResultDriver($res);}}function +DibiDriverException(odbc_errormsg($this->connection).' '.odbc_error($this->connection),0,$sql);} elseif (is_resource($res)) {$this->affectedRows=odbc_num_rows($res);return$this->createResultDriver($res);}}function getAffectedRows(){return$this->affectedRows;}function getInsertId($sequence){throw new DibiNotSupportedException('ODBC does not support autoincrementing.');}function -begin($savepoint=NULL){if(!odbc_autocommit($this->connection,FALSE)){throw +begin($savepoint=NULL){if (!odbc_autocommit($this->connection,FALSE)) {throw new DibiDriverException(odbc_errormsg($this->connection).' '.odbc_error($this->connection));}}function -commit($savepoint=NULL){if(!odbc_commit($this->connection)){throw +commit($savepoint=NULL){if (!odbc_commit($this->connection)) {throw new DibiDriverException(odbc_errormsg($this->connection).' '.odbc_error($this->connection));}odbc_autocommit($this->connection,TRUE);}function -rollback($savepoint=NULL){if(!odbc_rollback($this->connection)){throw +rollback($savepoint=NULL){if (!odbc_rollback($this->connection)) {throw new DibiDriverException(odbc_errormsg($this->connection).' '.odbc_error($this->connection));}odbc_autocommit($this->connection,TRUE);}function inTransaction(){return!odbc_autocommit($this->connection);}function @@ -1003,7 +1003,7 @@ function is_resource($this->connection)?$this->connection:NULL;}function getReflector(){return$this;}function createResultDriver($resource){$res=clone$this;$res->resultSet=$resource;return$res;}function -escape($value,$type){switch($type){case +escape($value,$type){switch ($type) {case dibi::TEXT:case dibi::BINARY:return"'".str_replace("'","''",$value)."'";case dibi::IDENTIFIER:return'['.str_replace(array('[',']'),array('[[',']]'),$value).']';case @@ -1017,26 +1017,26 @@ function new InvalidArgumentException('Unsupported type.');}}function escapeLike($value,$pos){$value=strtr($value,array("'"=>"''",'%'=>'[%]','_'=>'[_]','['=>'[[]'));return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}function -unescape($value,$type){if($type===dibi::BINARY){return$value;}throw +unescape($value,$type){if ($type===dibi::BINARY) {return$value;}throw new InvalidArgumentException('Unsupported type.');}function -applyLimit(&$sql,$limit,$offset){if($limit>=0){$sql='SELECT TOP '.(int)$limit.' * FROM ('.$sql.')';}if($offset)throw +applyLimit(&$sql,$limit,$offset){if ($limit>=0) {$sql='SELECT TOP '.(int) $limit.' * FROM ('.$sql.')';}if($offset)throw new DibiNotSupportedException('Offset is not implemented in driver odbc.');}function __destruct(){$this->autoFree&&$this->getResultResource()&&$this->free();}function getRowCount(){return odbc_num_rows($this->resultSet);}function -fetch($assoc){if($assoc){return -odbc_fetch_array($this->resultSet,++$this->row);}else{$set=$this->resultSet;if(!odbc_fetch_row($set,++$this->row))return +fetch($assoc){if ($assoc) {return +odbc_fetch_array($this->resultSet,++$this->row);} else {$set=$this->resultSet;if(!odbc_fetch_row($set,++$this->row))return FALSE;$count=odbc_num_fields($set);$cols=array();for($i=1;$i<=$count;$i++)$cols[]=odbc_result($set,$i);return$cols;}}function seek($row){$this->row=$row;return TRUE;}function free(){odbc_free_result($this->resultSet);$this->resultSet=NULL;}function -getResultColumns(){$count=odbc_num_fields($this->resultSet);$columns=array();for($i=1;$i<=$count;$i++){$columns[]=array('name'=>odbc_field_name($this->resultSet,$i),'table'=>NULL,'fullname'=>odbc_field_name($this->resultSet,$i),'nativetype'=>odbc_field_type($this->resultSet,$i));}return$columns;}function +getResultColumns(){$count=odbc_num_fields($this->resultSet);$columns=array();for ($i=1;$i<=$count;$i++) {$columns[]=array('name'=>odbc_field_name($this->resultSet,$i),'table'=>NULL,'fullname'=>odbc_field_name($this->resultSet,$i),'nativetype'=>odbc_field_type($this->resultSet,$i));}return$columns;}function getResultResource(){$this->autoFree=FALSE;return is_resource($this->resultSet)?$this->resultSet:NULL;}function -getTables(){$res=odbc_tables($this->connection);$tables=array();while($row=odbc_fetch_array($res)){if($row['TABLE_TYPE']==='TABLE'||$row['TABLE_TYPE']==='VIEW'){$tables[]=array('name'=>$row['TABLE_NAME'],'view'=>$row['TABLE_TYPE']==='VIEW');}}odbc_free_result($res);return$tables;}function -getColumns($table){$res=odbc_columns($this->connection);$columns=array();while($row=odbc_fetch_array($res)){if($row['TABLE_NAME']===$table){$columns[]=array('name'=>$row['COLUMN_NAME'],'table'=>$table,'nativetype'=>$row['TYPE_NAME'],'size'=>$row['COLUMN_SIZE'],'nullable'=>(bool)$row['NULLABLE'],'default'=>$row['COLUMN_DEF']);}}odbc_free_result($res);return$columns;}function +getTables(){$res=odbc_tables($this->connection);$tables=array();while ($row=odbc_fetch_array($res)){if ($row['TABLE_TYPE']==='TABLE'||$row['TABLE_TYPE']==='VIEW') {$tables[]=array('name'=>$row['TABLE_NAME'],'view'=>$row['TABLE_TYPE']==='VIEW');}}odbc_free_result($res);return$tables;}function +getColumns($table){$res=odbc_columns($this->connection);$columns=array();while ($row=odbc_fetch_array($res)){if ($row['TABLE_NAME']===$table) {$columns[]=array('name'=>$row['COLUMN_NAME'],'table'=>$table,'nativetype'=>$row['TYPE_NAME'],'size'=>$row['COLUMN_SIZE'],'nullable'=>(bool) $row['NULLABLE'],'default'=>$row['COLUMN_DEF']);}}odbc_free_result($res);return$columns;}function getIndexes($table){throw new DibiNotImplementedException;}function @@ -1050,61 +1050,61 @@ function IDibiReflector{private$driver;function __construct(IDibiDriver$driver){$this->driver=$driver;}function getTables(){$res=$this->driver->query(" - SELECT name, type = 'view' as view FROM sqlite_master WHERE type IN ('table', 'view') - UNION ALL - SELECT name, type = 'view' as view FROM sqlite_temp_master WHERE type IN ('table', 'view') - ORDER BY name - ");$tables=array();while($row=$res->fetch(TRUE)){$tables[]=$row;}return$tables;}function + SELECT name, type = 'view' as view FROM sqlite_master WHERE type IN ('table', 'view') + UNION ALL + SELECT name, type = 'view' as view FROM sqlite_temp_master WHERE type IN ('table', 'view') + ORDER BY name + ");$tables=array();while ($row=$res->fetch(TRUE)) {$tables[]=$row;}return$tables;}function getColumns($table){$meta=$this->driver->query(" - SELECT sql FROM sqlite_master WHERE type = 'table' AND name = {$this->driver->escape($table,dibi::TEXT)} - UNION ALL - SELECT sql FROM sqlite_temp_master WHERE type = 'table' AND name = {$this->driver->escape($table,dibi::TEXT)} - ")->fetch(TRUE);$res=$this->driver->query("PRAGMA table_info({$this->driver->escape($table,dibi::IDENTIFIER)})");$columns=array();while($row=$res->fetch(TRUE)){$column=$row['name'];$pattern="/(\"$column\"|\[$column\]|$column)\\s+[^,]+\\s+PRIMARY\\s+KEY\\s+AUTOINCREMENT/Ui";$type=explode('(',$row['type']);$columns[]=array('name'=>$column,'table'=>$table,'fullname'=>"$table.$column",'nativetype'=>strtoupper($type[0]),'size'=>isset($type[1])?(int)$type[1]:NULL,'nullable'=>$row['notnull']=='0','default'=>$row['dflt_value'],'autoincrement'=>(bool)preg_match($pattern,$meta['sql']),'vendor'=>$row);}return$columns;}function -getIndexes($table){$res=$this->driver->query("PRAGMA index_list({$this->driver->escape($table,dibi::IDENTIFIER)})");$indexes=array();while($row=$res->fetch(TRUE)){$indexes[$row['name']]['name']=$row['name'];$indexes[$row['name']]['unique']=(bool)$row['unique'];}foreach($indexes -as$index=>$values){$res=$this->driver->query("PRAGMA index_info({$this->driver->escape($index,dibi::IDENTIFIER)})");while($row=$res->fetch(TRUE)){$indexes[$index]['columns'][$row['seqno']]=$row['name'];}}$columns=$this->getColumns($table);foreach($indexes -as$index=>$values){$column=$indexes[$index]['columns'][0];$primary=FALSE;foreach($columns -as$info){if($column==$info['name']){$primary=$info['vendor']['pk'];break;}}$indexes[$index]['primary']=(bool)$primary;}if(!$indexes){foreach($columns -as$column){if($column['vendor']['pk']){$indexes[]=array('name'=>'ROWID','unique'=>TRUE,'primary'=>TRUE,'columns'=>array($column['name']));break;}}}return + SELECT sql FROM sqlite_master WHERE type = 'table' AND name = {$this->driver->escape($table,dibi::TEXT)} + UNION ALL + SELECT sql FROM sqlite_temp_master WHERE type = 'table' AND name = {$this->driver->escape($table,dibi::TEXT)} + ")->fetch(TRUE);$res=$this->driver->query("PRAGMA table_info({$this->driver->escape($table,dibi::IDENTIFIER)})");$columns=array();while ($row=$res->fetch(TRUE)) {$column=$row['name'];$pattern="/(\"$column\"|\[$column\]|$column)\\s+[^,]+\\s+PRIMARY\\s+KEY\\s+AUTOINCREMENT/Ui";$type=explode('(',$row['type']);$columns[]=array('name'=>$column,'table'=>$table,'fullname'=>"$table.$column",'nativetype'=>strtoupper($type[0]),'size'=>isset($type[1])?(int) $type[1]:NULL,'nullable'=>$row['notnull']=='0','default'=>$row['dflt_value'],'autoincrement'=>(bool) preg_match($pattern,$meta['sql']),'vendor'=>$row);}return$columns;}function +getIndexes($table){$res=$this->driver->query("PRAGMA index_list({$this->driver->escape($table,dibi::IDENTIFIER)})");$indexes=array();while ($row=$res->fetch(TRUE)) {$indexes[$row['name']]['name']=$row['name'];$indexes[$row['name']]['unique']=(bool) $row['unique'];}foreach ($indexes +as$index=>$values) {$res=$this->driver->query("PRAGMA index_info({$this->driver->escape($index,dibi::IDENTIFIER)})");while ($row=$res->fetch(TRUE)) {$indexes[$index]['columns'][$row['seqno']]=$row['name'];}}$columns=$this->getColumns($table);foreach ($indexes +as$index=>$values) {$column=$indexes[$index]['columns'][0];$primary=FALSE;foreach ($columns +as$info) {if ($column==$info['name']) {$primary=$info['vendor']['pk'];break;}}$indexes[$index]['primary']=(bool) $primary;}if (!$indexes) {foreach ($columns +as$column) {if ($column['vendor']['pk']) {$indexes[]=array('name'=>'ROWID','unique'=>TRUE,'primary'=>TRUE,'columns'=>array($column['name']));break;}}}return array_values($indexes);}function getForeignKeys($table){if(!($this->driver instanceof -DibiSqlite3Driver)){}$res=$this->driver->query("PRAGMA foreign_key_list({$this->driver->escape($table,dibi::IDENTIFIER)})");$keys=array();while($row=$res->fetch(TRUE)){$keys[$row['id']]['name']=$row['id'];$keys[$row['id']]['local'][$row['seq']]=$row['from'];$keys[$row['id']]['table']=$row['table'];$keys[$row['id']]['foreign'][$row['seq']]=$row['to'];$keys[$row['id']]['onDelete']=$row['on_delete'];$keys[$row['id']]['onUpdate']=$row['on_update'];if($keys[$row['id']]['foreign'][0]==NULL){$keys[$row['id']]['foreign']=NULL;}}return +DibiSqlite3Driver)){}$res=$this->driver->query("PRAGMA foreign_key_list({$this->driver->escape($table,dibi::IDENTIFIER)})");$keys=array();while ($row=$res->fetch(TRUE)){$keys[$row['id']]['name']=$row['id'];$keys[$row['id']]['local'][$row['seq']]=$row['from'];$keys[$row['id']]['table']=$row['table'];$keys[$row['id']]['foreign'][$row['seq']]=$row['to'];$keys[$row['id']]['onDelete']=$row['on_delete'];$keys[$row['id']]['onUpdate']=$row['on_update'];if ($keys[$row['id']]['foreign'][0]==NULL) {$keys[$row['id']]['foreign']=NULL;}}return array_values($keys);}}class DibiPdoDriver extends DibiObject implements IDibiDriver,IDibiResultDriver{private$connection;private$resultSet;private$affectedRows=FALSE;private$driverName;function -__construct(){if(!extension_loaded('pdo')){throw +__construct(){if (!extension_loaded('pdo')) {throw new DibiNotSupportedException("PHP extension 'pdo' is not loaded.");}}function -connect(array&$config){$foo=&$config['dsn'];$foo=&$config['options'];DibiConnection::alias($config,'resource','pdo');if($config['resource']instanceof -PDO){$this->connection=$config['resource'];}else -try{$this->connection=new -PDO($config['dsn'],$config['username'],$config['password'],$config['options']);}catch(PDOException$e){throw +connect(array&$config){$foo=&$config['dsn'];$foo=&$config['options'];DibiConnection::alias($config,'resource','pdo');if ($config['resource']instanceof +PDO) {$this->connection=$config['resource'];}else +try {$this->connection=new +PDO($config['dsn'],$config['username'],$config['password'],$config['options']);} catch (PDOException$e) {throw new -DibiDriverException($e->getMessage(),$e->getCode());}if(!$this->connection){throw +DibiDriverException($e->getMessage(),$e->getCode());}if (!$this->connection) {throw new DibiDriverException('Connecting error.');}$this->driverName=$this->connection->getAttribute(PDO::ATTR_DRIVER_NAME);}function disconnect(){$this->connection=NULL;}function -query($sql){$cmd=strtoupper(substr(ltrim($sql),0,6));static$list=array('UPDATE'=>1,'DELETE'=>1,'INSERT'=>1,'REPLAC'=>1);$this->affectedRows=FALSE;if(isset($list[$cmd])){$this->affectedRows=$this->connection->exec($sql);if($this->affectedRows===FALSE){$err=$this->connection->errorInfo();throw +query($sql){$cmd=strtoupper(substr(ltrim($sql),0,6));static$list=array('UPDATE'=>1,'DELETE'=>1,'INSERT'=>1,'REPLAC'=>1);$this->affectedRows=FALSE;if (isset($list[$cmd])){$this->affectedRows=$this->connection->exec($sql);if ($this->affectedRows===FALSE) {$err=$this->connection->errorInfo();throw new -DibiDriverException("SQLSTATE[$err[0]]: $err[2]",$err[1],$sql);}}else{$res=$this->connection->query($sql);if($res===FALSE){$err=$this->connection->errorInfo();throw +DibiDriverException("SQLSTATE[$err[0]]: $err[2]",$err[1],$sql);}} else {$res=$this->connection->query($sql);if ($res===FALSE) {$err=$this->connection->errorInfo();throw new -DibiDriverException("SQLSTATE[$err[0]]: $err[2]",$err[1],$sql);}else{return$this->createResultDriver($res);}}}function +DibiDriverException("SQLSTATE[$err[0]]: $err[2]",$err[1],$sql);} else {return$this->createResultDriver($res);}}}function getAffectedRows(){return$this->affectedRows;}function getInsertId($sequence){return$this->connection->lastInsertId();}function -begin($savepoint=NULL){if(!$this->connection->beginTransaction()){$err=$this->connection->errorInfo();throw +begin($savepoint=NULL){if (!$this->connection->beginTransaction()) {$err=$this->connection->errorInfo();throw new DibiDriverException("SQLSTATE[$err[0]]: $err[2]",$err[1]);}}function -commit($savepoint=NULL){if(!$this->connection->commit()){$err=$this->connection->errorInfo();throw +commit($savepoint=NULL){if (!$this->connection->commit()) {$err=$this->connection->errorInfo();throw new DibiDriverException("SQLSTATE[$err[0]]: $err[2]",$err[1]);}}function -rollback($savepoint=NULL){if(!$this->connection->rollBack()){$err=$this->connection->errorInfo();throw +rollback($savepoint=NULL){if (!$this->connection->rollBack()) {$err=$this->connection->errorInfo();throw new DibiDriverException("SQLSTATE[$err[0]]: $err[2]",$err[1]);}}function getResource(){return$this->connection;}function -getReflector(){switch($this->driverName){case'mysql':return +getReflector(){switch ($this->driverName) {case'mysql':return new DibiMySqlReflector($this);case'sqlite':case'sqlite2':return new @@ -1112,10 +1112,10 @@ function new DibiNotSupportedException;}}function createResultDriver(PDOStatement$resource){$res=clone$this;$res->resultSet=$resource;return$res;}function -escape($value,$type){switch($type){case +escape($value,$type){switch ($type) {case dibi::TEXT:return$this->connection->quote($value,PDO::PARAM_STR);case dibi::BINARY:return$this->connection->quote($value,PDO::PARAM_LOB);case -dibi::IDENTIFIER:switch($this->driverName){case'mysql':return'`'.str_replace('`','``',$value).'`';case'pgsql':return'"'.str_replace('"','""',$value).'"';case'sqlite':case'sqlite2':return'['.strtr($value,'[]',' ').']';case'odbc':case'oci':case'mssql':return'['.str_replace(array('[',']'),array('[[',']]'),$value).']';default:return$value;}case +dibi::IDENTIFIER:switch ($this->driverName) {case'mysql':return'`'.str_replace('`','``',$value).'`';case'pgsql':return'"'.str_replace('"','""',$value).'"';case'sqlite':case'sqlite2':return'['.strtr($value,'[]',' ').']';case'odbc':case'oci':case'mssql':return'['.str_replace(array('[',']'),array('[[',']]'),$value).']';default:return$value;}case dibi::BOOL:return$this->connection->quote($value,PDO::PARAM_BOOL);case dibi::DATE:return$value instanceof @@ -1128,10 +1128,10 @@ function escapeLike($value,$pos){throw new DibiNotImplementedException;}function -unescape($value,$type){if($type===dibi::BINARY){return$value;}throw +unescape($value,$type){if ($type===dibi::BINARY) {return$value;}throw new InvalidArgumentException('Unsupported type.');}function -applyLimit(&$sql,$limit,$offset){if($limit<0&&$offset<1)return;switch($this->driverName){case'mysql':$sql.=' LIMIT '.($limit<0?'18446744073709551615':(int)$limit).($offset>0?' OFFSET '.(int)$offset:'');break;case'pgsql':if($limit>=0)$sql.=' LIMIT '.(int)$limit;if($offset>0)$sql.=' OFFSET '.(int)$offset;break;case'sqlite':case'sqlite2':$sql.=' LIMIT '.$limit.($offset>0?' OFFSET '.(int)$offset:'');break;case'oci':if($offset>0){$sql='SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM ('.$sql.') t '.($limit>=0?'WHERE ROWNUM <= '.((int)$offset+(int)$limit):'').') WHERE "__rnum" > '.(int)$offset;}elseif($limit>=0){$sql='SELECT * FROM ('.$sql.') WHERE ROWNUM <= '.(int)$limit;}break;case'odbc':case'mssql':if($offset<1){$sql='SELECT TOP '.(int)$limit.' * FROM ('.$sql.')';break;}default:throw +applyLimit(&$sql,$limit,$offset){if ($limit<0&&$offset<1)return;switch ($this->driverName) {case'mysql':$sql.=' LIMIT '.($limit<0?'18446744073709551615':(int) $limit).($offset>0?' OFFSET '.(int) $offset:'');break;case'pgsql':if($limit>=0)$sql.=' LIMIT '.(int) $limit;if($offset>0)$sql.=' OFFSET '.(int) $offset;break;case'sqlite':case'sqlite2':$sql.=' LIMIT '.$limit.($offset>0?' OFFSET '.(int) $offset:'');break;case'oci':if ($offset>0) {$sql='SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM ('.$sql.') t '.($limit>=0?'WHERE ROWNUM <= '.((int) $offset+(int) $limit):'').') WHERE "__rnum" > '.(int) $offset;} elseif ($limit>=0) {$sql='SELECT * FROM ('.$sql.') WHERE ROWNUM <= '.(int) $limit;}break;case'odbc':case'mssql':if ($offset<1) {$sql='SELECT TOP '.(int) $limit.' * FROM ('.$sql.')';break;}default:throw new DibiNotSupportedException('PDO or driver does not support applying limit or offset.');}}function getRowCount(){return$this->resultSet->rowCount();}function @@ -1140,7 +1140,7 @@ function new DibiNotSupportedException('Cannot seek an unbuffered result set.');}function free(){$this->resultSet=NULL;}function -getResultColumns(){$count=$this->resultSet->columnCount();$columns=array();for($i=0;$i<$count;$i++){$row=@$this->resultSet->getColumnMeta($i);if($row===FALSE){throw +getResultColumns(){$count=$this->resultSet->columnCount();$columns=array();for ($i=0;$i<$count;$i++) {$row=@$this->resultSet->getColumnMeta($i);if ($row===FALSE) {throw new DibiNotSupportedException('Driver does not support meta data.');}$row['table']=isset($row['table'])?$row['table']:NULL;$columns[]=array('name'=>$row['name'],'table'=>$row['table'],'nativetype'=>$row['native_type'],'fullname'=>$row['table']?$row['table'].'.'.$row['name']:$row['name'],'vendor'=>$row);}return$columns;}function getResultResource(){return$this->resultSet;}}class @@ -1149,22 +1149,22 @@ function DibiObject implements IDibiDriver,IDibiResultDriver,IDibiReflector{private$connection;private$resultSet;private$autoFree=TRUE;private$affectedRows=FALSE;private$escMethod=FALSE;function -__construct(){if(!extension_loaded('pgsql')){throw +__construct(){if (!extension_loaded('pgsql')) {throw new DibiNotSupportedException("PHP extension 'pgsql' is not loaded.");}}function -connect(array&$config){if(isset($config['resource'])){$this->connection=$config['resource'];}else{if(!isset($config['charset']))$config['charset']='utf8';if(isset($config['string'])){$string=$config['string'];}else{$string='';DibiConnection::alias($config,'user','username');DibiConnection::alias($config,'dbname','database');foreach(array('host','hostaddr','port','dbname','user','password','connect_timeout','options','sslmode','service')as$key){if(isset($config[$key]))$string.=$key.'='.$config[$key].' ';}}DibiDriverException::tryError();if(empty($config['persistent'])){$this->connection=pg_connect($string,PGSQL_CONNECT_FORCE_NEW);}else{$this->connection=pg_pconnect($string,PGSQL_CONNECT_FORCE_NEW);}if(DibiDriverException::catchError($msg)){throw +connect(array&$config){if (isset($config['resource'])){$this->connection=$config['resource'];} else {if(!isset($config['charset']))$config['charset']='utf8';if(isset($config['string'])){$string=$config['string'];} else {$string='';DibiConnection::alias($config,'user','username');DibiConnection::alias($config,'dbname','database');foreach(array('host','hostaddr','port','dbname','user','password','connect_timeout','options','sslmode','service')as$key){if(isset($config[$key]))$string.=$key.'='.$config[$key].' ';}}DibiDriverException::tryError();if(empty($config['persistent'])){$this->connection=pg_connect($string,PGSQL_CONNECT_FORCE_NEW);} else {$this->connection=pg_pconnect($string,PGSQL_CONNECT_FORCE_NEW);}if(DibiDriverException::catchError($msg)) {throw new -DibiDriverException($msg,0);}}if(!is_resource($this->connection)){throw +DibiDriverException($msg,0);}}if (!is_resource($this->connection)) {throw new -DibiDriverException('Connecting error.');}if(isset($config['charset'])){DibiDriverException::tryError();pg_set_client_encoding($this->connection,$config['charset']);if(DibiDriverException::catchError($msg)){throw +DibiDriverException('Connecting error.');}if (isset($config['charset'])){DibiDriverException::tryError();pg_set_client_encoding($this->connection,$config['charset']);if(DibiDriverException::catchError($msg)) {throw new -DibiDriverException($msg,0);}}if(isset($config['schema'])){$this->query('SET search_path TO "'.$config['schema'].'"');}$this->escMethod=version_compare(PHP_VERSION,'5.2.0','>=');}function +DibiDriverException($msg,0);}}if (isset($config['schema'])) {$this->query('SET search_path TO "'.$config['schema'].'"');}$this->escMethod=version_compare(PHP_VERSION,'5.2.0','>=');}function disconnect(){pg_close($this->connection);}function -query($sql){$this->affectedRows=FALSE;$res=@pg_query($this->connection,$sql);if($res===FALSE){throw +query($sql){$this->affectedRows=FALSE;$res=@pg_query($this->connection,$sql);if ($res===FALSE) {throw new -DibiDriverException(pg_last_error($this->connection),0,$sql);}elseif(is_resource($res)){$this->affectedRows=pg_affected_rows($res);if(pg_num_fields($res)){return$this->createResultDriver($res);}}}function +DibiDriverException(pg_last_error($this->connection),0,$sql);} elseif (is_resource($res)){$this->affectedRows=pg_affected_rows($res);if(pg_num_fields($res)) {return$this->createResultDriver($res);}}}function getAffectedRows(){return$this->affectedRows;}function -getInsertId($sequence){if($sequence===NULL){$res=$this->query("SELECT LASTVAL()");}else{$res=$this->query("SELECT CURRVAL('$sequence')");}if(!$res)return +getInsertId($sequence){if ($sequence===NULL) {$res=$this->query("SELECT LASTVAL()");} else {$res=$this->query("SELECT CURRVAL('$sequence')");}if(!$res)return FALSE;$row=$res->fetch(FALSE);return is_array($row)?$row[0]:FALSE;}function begin($savepoint=NULL){$this->query($savepoint?"SAVEPOINT $savepoint":'START TRANSACTION');}function @@ -1175,13 +1175,13 @@ function is_resource($this->connection)?$this->connection:NULL;}function getReflector(){return$this;}function createResultDriver($resource){$res=clone$this;$res->resultSet=$resource;return$res;}function -escape($value,$type){switch($type){case -dibi::TEXT:if($this->escMethod){if(!is_resource($this->connection)){throw +escape($value,$type){switch ($type) {case +dibi::TEXT:if ($this->escMethod) {if(!is_resource($this->connection)) {throw new -DibiException('Lost connection to server.');}return"'".pg_escape_string($this->connection,$value)."'";}else{return"'".pg_escape_string($value)."'";}case -dibi::BINARY:if($this->escMethod){if(!is_resource($this->connection)){throw +DibiException('Lost connection to server.');}return"'".pg_escape_string($this->connection,$value)."'";} else {return"'".pg_escape_string($value)."'";}case +dibi::BINARY:if ($this->escMethod) {if(!is_resource($this->connection)) {throw new -DibiException('Lost connection to server.');}return"'".pg_escape_bytea($this->connection,$value)."'";}else{return"'".pg_escape_bytea($value)."'";}case +DibiException('Lost connection to server.');}return"'".pg_escape_bytea($this->connection,$value)."'";} else {return"'".pg_escape_bytea($value)."'";}case dibi::IDENTIFIER:return'"'.str_replace('"','""',$value).'"';case dibi::BOOL:return$value?'TRUE':'FALSE';case dibi::DATE:return$value @@ -1192,12 +1192,12 @@ function DateTime?$value->format("'Y-m-d H:i:s'"):date("'Y-m-d H:i:s'",$value);default:throw new InvalidArgumentException('Unsupported type.');}}function -escapeLike($value,$pos){if($this->escMethod){$value=pg_escape_string($this->connection,$value);}else{$value=pg_escape_string($value);}$value=strtr($value,array('%'=>'\\\\%','_'=>'\\\\_'));return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}function -unescape($value,$type){if($type===dibi::BINARY){return +escapeLike($value,$pos){if ($this->escMethod) {$value=pg_escape_string($this->connection,$value);} else {$value=pg_escape_string($value);}$value=strtr($value,array('%'=>'\\\\%','_'=>'\\\\_'));return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'");}function +unescape($value,$type){if ($type===dibi::BINARY) {return pg_unescape_bytea($value);}throw new InvalidArgumentException('Unsupported type.');}function -applyLimit(&$sql,$limit,$offset){if($limit>=0)$sql.=' LIMIT '.(int)$limit;if($offset>0)$sql.=' OFFSET '.(int)$offset;}function +applyLimit(&$sql,$limit,$offset){if($limit>=0)$sql.=' LIMIT '.(int) $limit;if($offset>0)$sql.=' OFFSET '.(int) $offset;}function __destruct(){$this->autoFree&&$this->getResultResource()&&$this->free();}function getRowCount(){return pg_num_rows($this->resultSet);}function @@ -1206,100 +1206,100 @@ function seek($row){return pg_result_seek($this->resultSet,$row);}function free(){pg_free_result($this->resultSet);$this->resultSet=NULL;}function -getResultColumns(){$hasTable=version_compare(PHP_VERSION,'5.2.0','>=');$count=pg_num_fields($this->resultSet);$columns=array();for($i=0;$i<$count;$i++){$row=array('name'=>pg_field_name($this->resultSet,$i),'table'=>$hasTable?pg_field_table($this->resultSet,$i):NULL,'nativetype'=>pg_field_type($this->resultSet,$i));$row['fullname']=$row['table']?$row['table'].'.'.$row['name']:$row['name'];$columns[]=$row;}return$columns;}function +getResultColumns(){$hasTable=version_compare(PHP_VERSION,'5.2.0','>=');$count=pg_num_fields($this->resultSet);$columns=array();for ($i=0;$i<$count;$i++) {$row=array('name'=>pg_field_name($this->resultSet,$i),'table'=>$hasTable?pg_field_table($this->resultSet,$i):NULL,'nativetype'=>pg_field_type($this->resultSet,$i));$row['fullname']=$row['table']?$row['table'].'.'.$row['name']:$row['name'];$columns[]=$row;}return$columns;}function getResultResource(){$this->autoFree=FALSE;return is_resource($this->resultSet)?$this->resultSet:NULL;}function -getTables(){$version=pg_parameter_status($this->resource,'server_version');if($version<7.4){throw +getTables(){$version=pg_parameter_status($this->resource,'server_version');if ($version<7.4) {throw new DibiDriverException('Reflection requires PostgreSQL 7.4 and newer.');}$res=$this->query(" - SELECT - table_name AS name, - CASE table_type - WHEN 'VIEW' THEN 1 - ELSE 0 - END AS view - FROM - information_schema.tables - WHERE - table_schema = current_schema() - ");$tables=pg_fetch_all($res->resultSet);return$tables?$tables:array();}function + SELECT + table_name AS name, + CASE table_type + WHEN 'VIEW' THEN 1 + ELSE 0 + END AS view + FROM + information_schema.tables + WHERE + table_schema = current_schema() + ");$tables=pg_fetch_all($res->resultSet);return$tables?$tables:array();}function getColumns($table){$_table=$this->escape($table,dibi::TEXT);$res=$this->query(" - SELECT indkey - FROM pg_class - LEFT JOIN pg_index on pg_class.oid = pg_index.indrelid AND pg_index.indisprimary - WHERE pg_class.relname = $_table - ");$primary=(int)pg_fetch_object($res->resultSet)->indkey;$res=$this->query(" - SELECT * - FROM information_schema.columns - WHERE table_name = $_table AND table_schema = current_schema() - ORDER BY ordinal_position - ");$columns=array();while($row=$res->fetch(TRUE)){$size=(int)max($row['character_maximum_length'],$row['numeric_precision']);$columns[]=array('name'=>$row['column_name'],'table'=>$table,'nativetype'=>strtoupper($row['udt_name']),'size'=>$size?$size:NULL,'nullable'=>$row['is_nullable']==='YES','default'=>$row['column_default'],'autoincrement'=>(int)$row['ordinal_position']===$primary&&substr($row['column_default'],0,7)==='nextval','vendor'=>$row);}return$columns;}function + SELECT indkey + FROM pg_class + LEFT JOIN pg_index on pg_class.oid = pg_index.indrelid AND pg_index.indisprimary + WHERE pg_class.relname = $_table + ");$primary=(int) pg_fetch_object($res->resultSet)->indkey;$res=$this->query(" + SELECT * + FROM information_schema.columns + WHERE table_name = $_table AND table_schema = current_schema() + ORDER BY ordinal_position + ");$columns=array();while ($row=$res->fetch(TRUE)) {$size=(int) max($row['character_maximum_length'],$row['numeric_precision']);$columns[]=array('name'=>$row['column_name'],'table'=>$table,'nativetype'=>strtoupper($row['udt_name']),'size'=>$size?$size:NULL,'nullable'=>$row['is_nullable']==='YES','default'=>$row['column_default'],'autoincrement'=>(int) $row['ordinal_position']===$primary&&substr($row['column_default'],0,7)==='nextval','vendor'=>$row);}return$columns;}function getIndexes($table){$_table=$this->escape($table,dibi::TEXT);$res=$this->query(" - SELECT ordinal_position, column_name - FROM information_schema.columns - WHERE table_name = $_table AND table_schema = current_schema() - ORDER BY ordinal_position - ");$columns=array();while($row=$res->fetch(TRUE)){$columns[$row['ordinal_position']]=$row['column_name'];}$res=$this->query(" - SELECT pg_class2.relname, indisunique, indisprimary, indkey - FROM pg_class - LEFT JOIN pg_index on pg_class.oid = pg_index.indrelid - INNER JOIN pg_class as pg_class2 on pg_class2.oid = pg_index.indexrelid - WHERE pg_class.relname = $_table - ");$indexes=array();while($row=$res->fetch(TRUE)){$indexes[$row['relname']]['name']=$row['relname'];$indexes[$row['relname']]['unique']=$row['indisunique']==='t';$indexes[$row['relname']]['primary']=$row['indisprimary']==='t';foreach(explode(' ',$row['indkey'])as$index){$indexes[$row['relname']]['columns'][]=$columns[$index];}}return + SELECT ordinal_position, column_name + FROM information_schema.columns + WHERE table_name = $_table AND table_schema = current_schema() + ORDER BY ordinal_position + ");$columns=array();while ($row=$res->fetch(TRUE)) {$columns[$row['ordinal_position']]=$row['column_name'];}$res=$this->query(" + SELECT pg_class2.relname, indisunique, indisprimary, indkey + FROM pg_class + LEFT JOIN pg_index on pg_class.oid = pg_index.indrelid + INNER JOIN pg_class as pg_class2 on pg_class2.oid = pg_index.indexrelid + WHERE pg_class.relname = $_table + ");$indexes=array();while ($row=$res->fetch(TRUE)){$indexes[$row['relname']]['name']=$row['relname'];$indexes[$row['relname']]['unique']=$row['indisunique']==='t';$indexes[$row['relname']]['primary']=$row['indisprimary']==='t';foreach(explode(' ',$row['indkey'])as$index) {$indexes[$row['relname']]['columns'][]=$columns[$index];}}return array_values($indexes);}function getForeignKeys($table){$_table=$this->escape($table,dibi::TEXT);$res=$this->query(" - SELECT - c.conname AS name, - lt.attname AS local, - c.confrelid::regclass AS table, - ft.attname AS foreign, + SELECT + c.conname AS name, + lt.attname AS local, + c.confrelid::regclass AS table, + ft.attname AS foreign, - CASE c.confupdtype - WHEN 'a' THEN 'NO ACTION' - WHEN 'r' THEN 'RESTRICT' - WHEN 'c' THEN 'CASCADE' - WHEN 'n' THEN 'SET NULL' - WHEN 'd' THEN 'SET DEFAULT' - ELSE 'UNKNOWN' - END AS \"onUpdate\", + CASE c.confupdtype + WHEN 'a' THEN 'NO ACTION' + WHEN 'r' THEN 'RESTRICT' + WHEN 'c' THEN 'CASCADE' + WHEN 'n' THEN 'SET NULL' + WHEN 'd' THEN 'SET DEFAULT' + ELSE 'UNKNOWN' + END AS \"onUpdate\", - CASE c.confdeltype - WHEN 'a' THEN 'NO ACTION' - WHEN 'r' THEN 'RESTRICT' - WHEN 'c' THEN 'CASCADE' - WHEN 'n' THEN 'SET NULL' - WHEN 'd' THEN 'SET DEFAULT' - ELSE 'UNKNOWN' - END AS \"onDelete\", + CASE c.confdeltype + WHEN 'a' THEN 'NO ACTION' + WHEN 'r' THEN 'RESTRICT' + WHEN 'c' THEN 'CASCADE' + WHEN 'n' THEN 'SET NULL' + WHEN 'd' THEN 'SET DEFAULT' + ELSE 'UNKNOWN' + END AS \"onDelete\", - c.conkey, - lt.attnum AS lnum, - c.confkey, - ft.attnum AS fnum - FROM - pg_constraint c - JOIN pg_attribute lt ON c.conrelid = lt.attrelid AND lt.attnum = ANY (c.conkey) - JOIN pg_attribute ft ON c.confrelid = ft.attrelid AND ft.attnum = ANY (c.confkey) - WHERE - c.contype = 'f' - AND - c.conrelid = $_table::regclass - ");$fKeys=$references=array();while($row=$res->fetch(TRUE)){if(!isset($fKeys[$row['name']])){$fKeys[$row['name']]=array('name'=>$row['name'],'table'=>$row['table'],'local'=>array(),'foreign'=>array(),'onUpdate'=>$row['onUpdate'],'onDelete'=>$row['onDelete']);$l=explode(',',trim($row['conkey'],'{}'));$f=explode(',',trim($row['confkey'],'{}'));$references[$row['name']]=array_combine($l,$f);}if(isset($references[$row['name']][$row['lnum']])&&$references[$row['name']][$row['lnum']]===$row['fnum']){$fKeys[$row['name']]['local'][]=$row['local'];$fKeys[$row['name']]['foreign'][]=$row['foreign'];}}return$fKeys;}}class + c.conkey, + lt.attnum AS lnum, + c.confkey, + ft.attnum AS fnum + FROM + pg_constraint c + JOIN pg_attribute lt ON c.conrelid = lt.attrelid AND lt.attnum = ANY (c.conkey) + JOIN pg_attribute ft ON c.confrelid = ft.attrelid AND ft.attnum = ANY (c.confkey) + WHERE + c.contype = 'f' + AND + c.conrelid = $_table::regclass + ");$fKeys=$references=array();while ($row=$res->fetch(TRUE)){if(!isset($fKeys[$row['name']])){$fKeys[$row['name']]=array('name'=>$row['name'],'table'=>$row['table'],'local'=>array(),'foreign'=>array(),'onUpdate'=>$row['onUpdate'],'onDelete'=>$row['onDelete']);$l=explode(',',trim($row['conkey'],'{}'));$f=explode(',',trim($row['confkey'],'{}'));$references[$row['name']]=array_combine($l,$f);}if(isset($references[$row['name']][$row['lnum']])&&$references[$row['name']][$row['lnum']]===$row['fnum']) {$fKeys[$row['name']]['local'][]=$row['local'];$fKeys[$row['name']]['foreign'][]=$row['foreign'];}}return$fKeys;}}class DibiSqliteDriver extends DibiObject implements IDibiDriver,IDibiResultDriver{private$connection;private$resultSet;private$buffered;private$fmtDate,$fmtDateTime;private$dbcharset,$charset;function -__construct(){if(!extension_loaded('sqlite')){throw +__construct(){if (!extension_loaded('sqlite')) {throw new DibiNotSupportedException("PHP extension 'sqlite' is not loaded.");}}function -connect(array&$config){DibiConnection::alias($config,'database','file');$this->fmtDate=isset($config['formatDate'])?$config['formatDate']:'U';$this->fmtDateTime=isset($config['formatDateTime'])?$config['formatDateTime']:'U';$errorMsg='';if(isset($config['resource'])){$this->connection=$config['resource'];}elseif(empty($config['persistent'])){$this->connection=@sqlite_open($config['database'],0666,$errorMsg);}else{$this->connection=@sqlite_popen($config['database'],0666,$errorMsg);}if(!$this->connection){throw +connect(array&$config){DibiConnection::alias($config,'database','file');$this->fmtDate=isset($config['formatDate'])?$config['formatDate']:'U';$this->fmtDateTime=isset($config['formatDateTime'])?$config['formatDateTime']:'U';$errorMsg='';if (isset($config['resource'])){$this->connection=$config['resource'];} elseif (empty($config['persistent'])){$this->connection=@sqlite_open($config['database'],0666,$errorMsg);} else {$this->connection=@sqlite_popen($config['database'],0666,$errorMsg);}if (!$this->connection) {throw new -DibiDriverException($errorMsg);}$this->buffered=empty($config['unbuffered']);$this->dbcharset=empty($config['dbcharset'])?'UTF-8':$config['dbcharset'];$this->charset=empty($config['charset'])?'UTF-8':$config['charset'];if(strcasecmp($this->dbcharset,$this->charset)===0){$this->dbcharset=$this->charset=NULL;}}function +DibiDriverException($errorMsg);}$this->buffered=empty($config['unbuffered']);$this->dbcharset=empty($config['dbcharset'])?'UTF-8':$config['dbcharset'];$this->charset=empty($config['charset'])?'UTF-8':$config['charset'];if (strcasecmp($this->dbcharset,$this->charset)===0) {$this->dbcharset=$this->charset=NULL;}}function disconnect(){sqlite_close($this->connection);}function -query($sql){if($this->dbcharset!==NULL){$sql=iconv($this->charset,$this->dbcharset.'//IGNORE',$sql);}DibiDriverException::tryError();if($this->buffered){$res=sqlite_query($this->connection,$sql);}else{$res=sqlite_unbuffered_query($this->connection,$sql);}if(DibiDriverException::catchError($msg)){throw +query($sql){if ($this->dbcharset!==NULL) {$sql=iconv($this->charset,$this->dbcharset.'//IGNORE',$sql);}DibiDriverException::tryError();if ($this->buffered) {$res=sqlite_query($this->connection,$sql);} else {$res=sqlite_unbuffered_query($this->connection,$sql);}if(DibiDriverException::catchError($msg)) {throw new -DibiDriverException($msg,sqlite_last_error($this->connection),$sql);}elseif(is_resource($res)){return$this->createResultDriver($res);}}function +DibiDriverException($msg,sqlite_last_error($this->connection),$sql);} elseif (is_resource($res)) {return$this->createResultDriver($res);}}function getAffectedRows(){return sqlite_changes($this->connection);}function getInsertId($sequence){return @@ -1313,7 +1313,7 @@ function new DibiSqliteReflector($this);}function createResultDriver($resource){$res=clone$this;$res->resultSet=$resource;return$res;}function -escape($value,$type){switch($type){case +escape($value,$type){switch ($type) {case dibi::TEXT:case dibi::BINARY:return"'".sqlite_escape_string($value)."'";case dibi::IDENTIFIER:return'['.strtr($value,'[]',' ').']';case @@ -1329,22 +1329,22 @@ function escapeLike($value,$pos){throw new DibiNotSupportedException;}function -unescape($value,$type){if($type===dibi::BINARY){return$value;}throw +unescape($value,$type){if ($type===dibi::BINARY) {return$value;}throw new InvalidArgumentException('Unsupported type.');}function -applyLimit(&$sql,$limit,$offset){if($limit<0&&$offset<1)return;$sql.=' LIMIT '.$limit.($offset>0?' OFFSET '.(int)$offset:'');}function -getRowCount(){if(!$this->buffered){throw +applyLimit(&$sql,$limit,$offset){if($limit<0&&$offset<1)return;$sql.=' LIMIT '.$limit.($offset>0?' OFFSET '.(int) $offset:'');}function +getRowCount(){if (!$this->buffered) {throw new DibiNotSupportedException('Row count is not available for unbuffered queries.');}return sqlite_num_rows($this->resultSet);}function -fetch($assoc){$row=sqlite_fetch_array($this->resultSet,$assoc?SQLITE_ASSOC:SQLITE_NUM);$charset=$this->charset===NULL?NULL:$this->charset.'//TRANSLIT';if($row&&($assoc||$charset)){$tmp=array();foreach($row -as$k=>$v){if($charset!==NULL&&is_string($v)){$v=iconv($this->dbcharset,$charset,$v);}$tmp[str_replace(array('[',']'),'',$k)]=$v;}return$tmp;}return$row;}function -seek($row){if(!$this->buffered){throw +fetch($assoc){$row=sqlite_fetch_array($this->resultSet,$assoc?SQLITE_ASSOC:SQLITE_NUM);$charset=$this->charset===NULL?NULL:$this->charset.'//TRANSLIT';if ($row&&($assoc||$charset)) {$tmp=array();foreach ($row +as$k=>$v) {if ($charset!==NULL&&is_string($v)) {$v=iconv($this->dbcharset,$charset,$v);}$tmp[str_replace(array('[',']'),'',$k)]=$v;}return$tmp;}return$row;}function +seek($row){if (!$this->buffered) {throw new DibiNotSupportedException('Cannot seek an unbuffered result set.');}return sqlite_seek($this->resultSet,$row);}function free(){$this->resultSet=NULL;}function -getResultColumns(){$count=sqlite_num_fields($this->resultSet);$columns=array();for($i=0;$i<$count;$i++){$name=str_replace(array('[',']'),'',sqlite_field_name($this->resultSet,$i));$pair=explode('.',$name);$columns[]=array('name'=>isset($pair[1])?$pair[1]:$pair[0],'table'=>isset($pair[1])?$pair[0]:NULL,'fullname'=>$name,'nativetype'=>NULL);}return$columns;}function +getResultColumns(){$count=sqlite_num_fields($this->resultSet);$columns=array();for ($i=0;$i<$count;$i++) {$name=str_replace(array('[',']'),'',sqlite_field_name($this->resultSet,$i));$pair=explode('.',$name);$columns[]=array('name'=>isset($pair[1])?$pair[1]:$pair[0],'table'=>isset($pair[1])?$pair[0]:NULL,'fullname'=>$name,'nativetype'=>NULL);}return$columns;}function getResultResource(){return is_resource($this->resultSet)?$this->resultSet:NULL;}function registerFunction($name,$callback,$numArgs=-1){sqlite_create_function($this->connection,$name,$callback,$numArgs);}function @@ -1354,21 +1354,21 @@ function DibiObject implements IDibiDriver,IDibiResultDriver{private$connection;private$resultSet;private$autoFree=TRUE;private$fmtDate,$fmtDateTime;private$dbcharset,$charset;function -__construct(){if(!extension_loaded('sqlite3')){throw +__construct(){if (!extension_loaded('sqlite3')) {throw new DibiNotSupportedException("PHP extension 'sqlite3' is not loaded.");}}function connect(array&$config){DibiConnection::alias($config,'database','file');$this->fmtDate=isset($config['formatDate'])?$config['formatDate']:'U';$this->fmtDateTime=isset($config['formatDateTime'])?$config['formatDateTime']:'U';if(isset($config['resource'])&&$config['resource']instanceof SQLite3){$this->connection=$config['resource'];}else -try{$this->connection=new -SQLite3($config['database']);}catch(Exception$e){throw +try {$this->connection=new +SQLite3($config['database']);} catch (Exception$e) {throw new -DibiDriverException($e->getMessage(),$e->getCode());}$this->dbcharset=empty($config['dbcharset'])?'UTF-8':$config['dbcharset'];$this->charset=empty($config['charset'])?'UTF-8':$config['charset'];if(strcasecmp($this->dbcharset,$this->charset)===0){$this->dbcharset=$this->charset=NULL;}$version=SQLite3::version();if($version['versionNumber']>='3006019'){$this->query("PRAGMA foreign_keys = ON");}}function +DibiDriverException($e->getMessage(),$e->getCode());}$this->dbcharset=empty($config['dbcharset'])?'UTF-8':$config['dbcharset'];$this->charset=empty($config['charset'])?'UTF-8':$config['charset'];if (strcasecmp($this->dbcharset,$this->charset)===0){$this->dbcharset=$this->charset=NULL;}$version=SQLite3::version();if ($version['versionNumber']>='3006019') {$this->query("PRAGMA foreign_keys = ON");}}function disconnect(){$this->connection->close();}function -query($sql){if($this->dbcharset!==NULL){$sql=iconv($this->charset,$this->dbcharset.'//IGNORE',$sql);}$res=@$this->connection->query($sql);if($this->connection->lastErrorCode()){throw +query($sql){if ($this->dbcharset!==NULL) {$sql=iconv($this->charset,$this->dbcharset.'//IGNORE',$sql);}$res=@$this->connection->query($sql);if($this->connection->lastErrorCode()) {throw new -DibiDriverException($this->connection->lastErrorMsg(),$this->connection->lastErrorCode(),$sql);}elseif($res +DibiDriverException($this->connection->lastErrorMsg(),$this->connection->lastErrorCode(),$sql);}elseif ($res instanceof -SQLite3Result){return$this->createResultDriver($res);}}function +SQLite3Result) {return$this->createResultDriver($res);}}function getAffectedRows(){return$this->connection->changes();}function getInsertId($sequence){return$this->connection->lastInsertRowID();}function begin($savepoint=NULL){$this->query($savepoint?"SAVEPOINT $savepoint":'BEGIN');}function @@ -1379,9 +1379,9 @@ function new DibiSqliteReflector($this);}function createResultDriver(SQLite3Result$resource){$res=clone$this;$res->resultSet=$resource;return$res;}function -escape($value,$type){switch($type){case +escape($value,$type){switch ($type) {case dibi::TEXT:return"'".$this->connection->escapeString($value)."'";case -dibi::BINARY:return"X'".bin2hex((string)$value)."'";case +dibi::BINARY:return"X'".bin2hex((string) $value)."'";case dibi::IDENTIFIER:return'['.strtr($value,'[]',' ').']';case dibi::BOOL:return$value?1:0;case dibi::DATE:return$value @@ -1393,21 +1393,21 @@ function new InvalidArgumentException('Unsupported type.');}}function escapeLike($value,$pos){$value=addcslashes($this->connection->escapeString($value),'%_\\');return($pos<=0?"'%":"'").$value.($pos>=0?"%'":"'")." ESCAPE '\\'";}function -unescape($value,$type){if($type===dibi::BINARY){return$value;}throw +unescape($value,$type){if ($type===dibi::BINARY) {return$value;}throw new InvalidArgumentException('Unsupported type.');}function -applyLimit(&$sql,$limit,$offset){if($limit<0&&$offset<1)return;$sql.=' LIMIT '.$limit.($offset>0?' OFFSET '.(int)$offset:'');}function +applyLimit(&$sql,$limit,$offset){if($limit<0&&$offset<1)return;$sql.=' LIMIT '.$limit.($offset>0?' OFFSET '.(int) $offset:'');}function __destruct(){$this->autoFree&&$this->resultSet&&@$this->free();}function getRowCount(){throw new DibiNotSupportedException('Row count is not available for unbuffered queries.');}function -fetch($assoc){$row=$this->resultSet->fetchArray($assoc?SQLITE3_ASSOC:SQLITE3_NUM);$charset=$this->charset===NULL?NULL:$this->charset.'//TRANSLIT';if($row&&($assoc||$charset)){$tmp=array();foreach($row -as$k=>$v){if($charset!==NULL&&is_string($v)){$v=iconv($this->dbcharset,$charset,$v);}$tmp[str_replace(array('[',']'),'',$k)]=$v;}return$tmp;}return$row;}function +fetch($assoc){$row=$this->resultSet->fetchArray($assoc?SQLITE3_ASSOC:SQLITE3_NUM);$charset=$this->charset===NULL?NULL:$this->charset.'//TRANSLIT';if ($row&&($assoc||$charset)) {$tmp=array();foreach ($row +as$k=>$v) {if ($charset!==NULL&&is_string($v)) {$v=iconv($this->dbcharset,$charset,$v);}$tmp[str_replace(array('[',']'),'',$k)]=$v;}return$tmp;}return$row;}function seek($row){throw new DibiNotSupportedException('Cannot seek an unbuffered result set.');}function free(){$this->resultSet->finalize();$this->resultSet=NULL;}function -getResultColumns(){$count=$this->resultSet->numColumns();$columns=array();static$types=array(SQLITE3_INTEGER=>'int',SQLITE3_FLOAT=>'float',SQLITE3_TEXT=>'text',SQLITE3_BLOB=>'blob',SQLITE3_NULL=>'null');for($i=0;$i<$count;$i++){$columns[]=array('name'=>$this->resultSet->columnName($i),'table'=>NULL,'fullname'=>$this->resultSet->columnName($i),'nativetype'=>$types[$this->resultSet->columnType($i)]);}return$columns;}function +getResultColumns(){$count=$this->resultSet->numColumns();$columns=array();static$types=array(SQLITE3_INTEGER=>'int',SQLITE3_FLOAT=>'float',SQLITE3_TEXT=>'text',SQLITE3_BLOB=>'blob',SQLITE3_NULL=>'null');for ($i=0;$i<$count;$i++) {$columns[]=array('name'=>$this->resultSet->columnName($i),'table'=>NULL,'fullname'=>$this->resultSet->columnName($i),'nativetype'=>$types[$this->resultSet->columnType($i)]);}return$columns;}function getResultResource(){$this->autoFree=FALSE;return$this->resultSet;}function registerFunction($name,$callback,$numArgs=-1){$this->connection->createFunction($name,$callback,$numArgs);}function -registerAggregateFunction($name,$rowCallback,$agrCallback,$numArgs=-1){$this->connection->createAggregate($name,$rowCallback,$agrCallback,$numArgs);}} \ No newline at end of file +registerAggregateFunction($name,$rowCallback,$agrCallback,$numArgs=-1){$this->connection->createAggregate($name,$rowCallback,$agrCallback,$numArgs);}} diff --git a/core/src/core/classes/http_class/http_class.php b/core/src/core/classes/http_class/http_class.php index 08f2d5eeea..f9bd16ba67 100644 --- a/core/src/core/classes/http_class/http_class.php +++ b/core/src/core/classes/http_class/http_class.php @@ -17,2073 +17,1868 @@ class http_class { - var $host_name=""; - var $host_port=0; - var $proxy_host_name=""; - var $proxy_host_port=80; - var $socks_host_name = ''; - var $socks_host_port = 1080; - var $socks_version = '5'; + public $host_name=""; + public $host_port=0; + public $proxy_host_name=""; + public $proxy_host_port=80; + public $socks_host_name = ''; + public $socks_host_port = 1080; + public $socks_version = '5'; - var $protocol="http"; - var $request_method="GET"; - var $user_agent='httpclient (http://www.phpclasses.org/httpclient $Revision: 1.88 $)'; - var $accept=''; - var $authentication_mechanism=""; - var $user; - var $password; - var $realm; - var $workstation; - var $proxy_authentication_mechanism=""; - var $proxy_user; - var $proxy_password; - var $proxy_realm; - var $proxy_workstation; - var $request_uri=""; - var $request=""; - var $request_headers=array(); - var $request_user; - var $request_password; - var $request_realm; - var $request_workstation; - var $proxy_request_user; - var $proxy_request_password; - var $proxy_request_realm; - var $proxy_request_workstation; - var $request_body=""; - var $request_arguments=array(); - var $protocol_version="1.1"; - var $timeout=0; - var $data_timeout=0; - var $debug=0; - var $log_debug=0; - var $debug_response_body=1; - var $html_debug=0; - var $support_cookies=1; - var $cookies=array(); - var $error=""; - var $error_code = HTTP_CLIENT_ERROR_NO_ERROR; - var $exclude_address=""; - var $follow_redirect=0; - var $redirection_limit=5; - var $response_status=""; - var $response_message=""; - var $file_buffer_length=8000; - var $force_multipart_form_post=0; - var $prefer_curl = 0; - var $keep_alive = 1; + public $protocol="http"; + public $request_method="GET"; + public $user_agent='httpclient (http://www.phpclasses.org/httpclient $Revision: 1.88 $)'; + public $accept=''; + public $authentication_mechanism=""; + public $user; + public $password; + public $realm; + public $workstation; + public $proxy_authentication_mechanism=""; + public $proxy_user; + public $proxy_password; + public $proxy_realm; + public $proxy_workstation; + public $request_uri=""; + public $request=""; + public $request_headers=array(); + public $request_user; + public $request_password; + public $request_realm; + public $request_workstation; + public $proxy_request_user; + public $proxy_request_password; + public $proxy_request_realm; + public $proxy_request_workstation; + public $request_body=""; + public $request_arguments=array(); + public $protocol_version="1.1"; + public $timeout=0; + public $data_timeout=0; + public $debug=0; + public $log_debug=0; + public $debug_response_body=1; + public $html_debug=0; + public $support_cookies=1; + public $cookies=array(); + public $error=""; + public $error_code = HTTP_CLIENT_ERROR_NO_ERROR; + public $exclude_address=""; + public $follow_redirect=0; + public $redirection_limit=5; + public $response_status=""; + public $response_message=""; + public $file_buffer_length=8000; + public $force_multipart_form_post=0; + public $prefer_curl = 0; + public $keep_alive = 1; - /* private variables - DO NOT ACCESS */ + /* private variables - DO NOT ACCESS */ - var $state="Disconnected"; - var $use_curl=0; - var $connection=0; - var $content_length=0; - var $response=""; - var $read_response=0; - var $read_length=0; - var $request_host=""; - var $next_token=""; - var $redirection_level=0; - var $chunked=0; - var $remaining_chunk=0; - var $last_chunk_read=0; - var $months=array( - "Jan"=>"01", - "Feb"=>"02", - "Mar"=>"03", - "Apr"=>"04", - "May"=>"05", - "Jun"=>"06", - "Jul"=>"07", - "Aug"=>"08", - "Sep"=>"09", - "Oct"=>"10", - "Nov"=>"11", - "Dec"=>"12"); - var $session=''; - var $connection_close=0; - var $force_close = 0; - var $connected_host = ''; - var $connected_port = -1; - var $connected_ssl = 0; + public $state="Disconnected"; + public $use_curl=0; + public $connection=0; + public $content_length=0; + public $response=""; + public $read_response=0; + public $read_length=0; + public $request_host=""; + public $next_token=""; + public $redirection_level=0; + public $chunked=0; + public $remaining_chunk=0; + public $last_chunk_read=0; + public $months=array( + "Jan"=>"01", + "Feb"=>"02", + "Mar"=>"03", + "Apr"=>"04", + "May"=>"05", + "Jun"=>"06", + "Jul"=>"07", + "Aug"=>"08", + "Sep"=>"09", + "Oct"=>"10", + "Nov"=>"11", + "Dec"=>"12"); + public $session=''; + public $connection_close=0; + public $force_close = 0; + public $connected_host = ''; + public $connected_port = -1; + public $connected_ssl = 0; - /* Private methods - DO NOT CALL */ + /* Private methods - DO NOT CALL */ - Function Tokenize($string,$separator="") - { - if(!strcmp($separator,"")) - { - $separator=$string; - $string=$this->next_token; - } - for($character=0;$characternext_token=substr($string,$found+1); - return(substr($string,0,$found)); - } - else - { - $this->next_token=""; - return($string); - } - } + public Function Tokenize($string,$separator="") + { + if (!strcmp($separator,"")) { + $separator=$string; + $string=$this->next_token; + } + for ($character=0;$characternext_token=substr($string,$found+1); + return(substr($string,0,$found)); + } else { + $this->next_token=""; + return($string); + } + } - Function CookieEncode($value, $name) - { - return($name ? str_replace("=", "%25", $value) : str_replace(";", "%3B", $value)); - } + public Function CookieEncode($value, $name) + { + return($name ? str_replace("=", "%25", $value) : str_replace(";", "%3B", $value)); + } - Function SetError($error, $error_code = HTTP_CLIENT_ERROR_UNSPECIFIED_ERROR) - { - $this->error_code = $error_code; - return($this->error=$error); - } + public Function SetError($error, $error_code = HTTP_CLIENT_ERROR_UNSPECIFIED_ERROR) + { + $this->error_code = $error_code; + return($this->error=$error); + } - Function SetPHPError($error, &$php_error_message, $error_code = HTTP_CLIENT_ERROR_UNSPECIFIED_ERROR) - { - if(IsSet($php_error_message) - && strlen($php_error_message)) - $error.=": ".$php_error_message; - return($this->SetError($error, $error_code)); - } + public Function SetPHPError($error, &$php_error_message, $error_code = HTTP_CLIENT_ERROR_UNSPECIFIED_ERROR) + { + if(IsSet($php_error_message) + && strlen($php_error_message)) + $error.=": ".$php_error_message; + return($this->SetError($error, $error_code)); + } - Function SetDataAccessError($error,$check_connection=0) - { - $this->error=$error; - $this->error_code = HTTP_CLIENT_ERROR_COMMUNICATION_FAILURE; - if(!$this->use_curl - && function_exists("socket_get_status")) - { - $status=socket_get_status($this->connection); - if($status["timed_out"]) - $this->error.=": data access time out"; - elseif($status["eof"]) - { - if($check_connection) - $this->error=""; - else - $this->error.=": the server disconnected"; - } - } - } + public Function SetDataAccessError($error,$check_connection=0) + { + $this->error=$error; + $this->error_code = HTTP_CLIENT_ERROR_COMMUNICATION_FAILURE; + if(!$this->use_curl + && function_exists("socket_get_status")) + { + $status=socket_get_status($this->connection); + if($status["timed_out"]) + $this->error.=": data access time out"; + elseif ($status["eof"]) { + if($check_connection) + $this->error=""; + else + $this->error.=": the server disconnected"; + } + } + } - Function OutputDebug($message) - { - if($this->log_debug) - error_log($message); - else - { - $message.="\n"; - if($this->html_debug) - $message=str_replace("\n","
    \n",HtmlEntities($message)); - echo $message; - flush(); - } - } + public Function OutputDebug($message) + { + if($this->log_debug) + error_log($message); + else { + $message.="\n"; + if($this->html_debug) + $message=str_replace("\n","
    \n",HtmlEntities($message)); + echo $message; + flush(); + } + } - Function GetLine() - { - for($line="";;) - { - if($this->use_curl) - { - $eol=strpos($this->response,"\n",$this->read_response); - $data=($eol ? substr($this->response,$this->read_response,$eol+1-$this->read_response) : ""); - $this->read_response+=strlen($data); - } - else - { - if(feof($this->connection)) - { - $this->SetDataAccessError("reached the end of data while reading from the HTTP server connection"); - return(0); - } - $data=fgets($this->connection,100); - } - if(GetType($data)!="string" - || strlen($data)==0) - { - $this->SetDataAccessError("it was not possible to read line from the HTTP server"); - return(0); - } - $line.=$data; - $length=strlen($line); - if($length - && !strcmp(substr($line,$length-1,1),"\n")) - { - $length-=(($length>=2 && !strcmp(substr($line,$length-2,1),"\r")) ? 2 : 1); - $line=substr($line,0,$length); - if($this->debug) - $this->OutputDebug("S $line"); - return($line); - } - } - } + public Function GetLine() + { + for ($line="";;) { + if ($this->use_curl) { + $eol=strpos($this->response,"\n",$this->read_response); + $data=($eol ? substr($this->response,$this->read_response,$eol+1-$this->read_response) : ""); + $this->read_response+=strlen($data); + } else { + if (feof($this->connection)) { + $this->SetDataAccessError("reached the end of data while reading from the HTTP server connection"); + return(0); + } + $data=fgets($this->connection,100); + } + if(GetType($data)!="string" + || strlen($data)==0) + { + $this->SetDataAccessError("it was not possible to read line from the HTTP server"); + return(0); + } + $line.=$data; + $length=strlen($line); + if($length + && !strcmp(substr($line,$length-1,1),"\n")) + { + $length-=(($length>=2 && !strcmp(substr($line,$length-2,1),"\r")) ? 2 : 1); + $line=substr($line,0,$length); + if($this->debug) + $this->OutputDebug("S $line"); + return($line); + } + } + } - Function PutLine($line) - { - if($this->debug) - $this->OutputDebug("C $line"); - if(!fputs($this->connection,$line."\r\n")) - { - $this->SetDataAccessError("it was not possible to send a line to the HTTP server"); - return(0); - } - return(1); - } + public Function PutLine($line) + { + if($this->debug) + $this->OutputDebug("C $line"); + if (!fputs($this->connection,$line."\r\n")) { + $this->SetDataAccessError("it was not possible to send a line to the HTTP server"); + return(0); + } + return(1); + } - Function PutData($data) - { - if(strlen($data)) - { - if($this->debug) - $this->OutputDebug('C '.$data); - if(!fputs($this->connection,$data)) - { - $this->SetDataAccessError("it was not possible to send data to the HTTP server"); - return(0); - } - } - return(1); - } + public Function PutData($data) + { + if (strlen($data)) { + if($this->debug) + $this->OutputDebug('C '.$data); + if (!fputs($this->connection,$data)) { + $this->SetDataAccessError("it was not possible to send data to the HTTP server"); + return(0); + } + } + return(1); + } - Function FlushData() - { - if(!fflush($this->connection)) - { - $this->SetDataAccessError("it was not possible to send data to the HTTP server"); - return(0); - } - return(1); - } + public Function FlushData() + { + if (!fflush($this->connection)) { + $this->SetDataAccessError("it was not possible to send data to the HTTP server"); + return(0); + } + return(1); + } - Function ReadChunkSize() - { - if($this->remaining_chunk==0) - { - $debug=$this->debug; - if(!$this->debug_response_body) - $this->debug=0; - $line=$this->GetLine(); - $this->debug=$debug; - if(GetType($line)!="string") - return($this->SetError("could not read chunk start: ".$this->error, $this->error_code)); - $this->remaining_chunk=hexdec($line); - if($this->remaining_chunk == 0) - { - if(!$this->debug_response_body) - $this->debug=0; - $line=$this->GetLine(); - $this->debug=$debug; - if(GetType($line)!="string") - return($this->SetError("could not read chunk end: ".$this->error, $this->error_code)); - } - } - return(""); - } + public Function ReadChunkSize() + { + if ($this->remaining_chunk==0) { + $debug=$this->debug; + if(!$this->debug_response_body) + $this->debug=0; + $line=$this->GetLine(); + $this->debug=$debug; + if(GetType($line)!="string") + return($this->SetError("could not read chunk start: ".$this->error, $this->error_code)); + $this->remaining_chunk=hexdec($line); + if ($this->remaining_chunk == 0) { + if(!$this->debug_response_body) + $this->debug=0; + $line=$this->GetLine(); + $this->debug=$debug; + if(GetType($line)!="string") + return($this->SetError("could not read chunk end: ".$this->error, $this->error_code)); + } + } + return(""); + } - Function ReadBytes($length) - { - if($this->use_curl) - { - $bytes=substr($this->response,$this->read_response,min($length,strlen($this->response)-$this->read_response)); - $this->read_response+=strlen($bytes); - if($this->debug - && $this->debug_response_body - && strlen($bytes)) - $this->OutputDebug("S ".$bytes); - } - else - { - if($this->chunked) - { - for($bytes="",$remaining=$length;$remaining;) - { - if(strlen($this->ReadChunkSize())) - return(""); - if($this->remaining_chunk==0) - { - $this->last_chunk_read=1; - break; - } - $ask=min($this->remaining_chunk,$remaining); - $chunk=@fread($this->connection,$ask); - $read=strlen($chunk); - if($read==0) - { - $this->SetDataAccessError("it was not possible to read data chunk from the HTTP server"); - return(""); - } - if($this->debug - && $this->debug_response_body) - $this->OutputDebug("S ".$chunk); - $bytes.=$chunk; - $this->remaining_chunk-=$read; - $remaining-=$read; - if($this->remaining_chunk==0) - { - if(feof($this->connection)) - return($this->SetError("reached the end of data while reading the end of data chunk mark from the HTTP server", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); - $data=@fread($this->connection,2); - if(strcmp($data,"\r\n")) - { - $this->SetDataAccessError("it was not possible to read end of data chunk from the HTTP server"); - return(""); - } - } - } - } - else - { - $bytes=@fread($this->connection,$length); - if(strlen($bytes)) - { - if($this->debug - && $this->debug_response_body) - $this->OutputDebug("S ".$bytes); - } - else - $this->SetDataAccessError("it was not possible to read data from the HTTP server", $this->connection_close); - } - } - return($bytes); - } + public Function ReadBytes($length) + { + if ($this->use_curl) { + $bytes=substr($this->response,$this->read_response,min($length,strlen($this->response)-$this->read_response)); + $this->read_response+=strlen($bytes); + if($this->debug + && $this->debug_response_body + && strlen($bytes)) + $this->OutputDebug("S ".$bytes); + } else { + if ($this->chunked) { + for ($bytes="",$remaining=$length;$remaining;) { + if(strlen($this->ReadChunkSize())) + return(""); + if ($this->remaining_chunk==0) { + $this->last_chunk_read=1; + break; + } + $ask=min($this->remaining_chunk,$remaining); + $chunk=@fread($this->connection,$ask); + $read=strlen($chunk); + if ($read==0) { + $this->SetDataAccessError("it was not possible to read data chunk from the HTTP server"); + return(""); + } + if($this->debug + && $this->debug_response_body) + $this->OutputDebug("S ".$chunk); + $bytes.=$chunk; + $this->remaining_chunk-=$read; + $remaining-=$read; + if ($this->remaining_chunk==0) { + if(feof($this->connection)) + return($this->SetError("reached the end of data while reading the end of data chunk mark from the HTTP server", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); + $data=@fread($this->connection,2); + if (strcmp($data,"\r\n")) { + $this->SetDataAccessError("it was not possible to read end of data chunk from the HTTP server"); + return(""); + } + } + } + } else { + $bytes=@fread($this->connection,$length); + if (strlen($bytes)) { + if($this->debug + && $this->debug_response_body) + $this->OutputDebug("S ".$bytes); + } else + $this->SetDataAccessError("it was not possible to read data from the HTTP server", $this->connection_close); + } + } + return($bytes); + } - Function EndOfInput() - { - if($this->use_curl) - return($this->read_response>=strlen($this->response)); - if($this->chunked) - return($this->last_chunk_read); - if($this->content_length_set) - return($this->content_length <= $this->read_length); - return(feof($this->connection)); - } + public Function EndOfInput() + { + if($this->use_curl) + return($this->read_response>=strlen($this->response)); + if($this->chunked) + return($this->last_chunk_read); + if($this->content_length_set) + return($this->content_length <= $this->read_length); + return(feof($this->connection)); + } - Function Resolve($domain, &$ip, $server_type) - { - if(preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/',$domain)) - $ip=$domain; - else - { - if($this->debug) - $this->OutputDebug('Resolving '.$server_type.' server domain "'.$domain.'"...'); - if(!strcmp($ip=@gethostbyname($domain),$domain)) - $ip=""; - } - if(strlen($ip)==0 - || (strlen($this->exclude_address) - && !strcmp(@gethostbyname($this->exclude_address),$ip))) - return($this->SetError("could not resolve the host domain \"".$domain."\"", HTTP_CLIENT_ERROR_INVALID_SERVER_ADDRESS)); - return(''); - } + public Function Resolve($domain, &$ip, $server_type) + { + if(preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/',$domain)) + $ip=$domain; + else { + if($this->debug) + $this->OutputDebug('Resolving '.$server_type.' server domain "'.$domain.'"...'); + if(!strcmp($ip=@gethostbyname($domain),$domain)) + $ip=""; + } + if(strlen($ip)==0 + || (strlen($this->exclude_address) + && !strcmp(@gethostbyname($this->exclude_address),$ip))) + return($this->SetError("could not resolve the host domain \"".$domain."\"", HTTP_CLIENT_ERROR_INVALID_SERVER_ADDRESS)); + return(''); + } - Function Connect($host_name, $host_port, $ssl, $server_type = 'HTTP') - { - $domain=$host_name; - $port = $host_port; - if(strlen($error = $this->Resolve($domain, $ip, $server_type))) - return($error); - if(strlen($this->socks_host_name)) - { - switch($this->socks_version) - { - case '4': - $version = 4; - break; - case '5': - $version = 5; - break; - default: - return('it was not specified a supported SOCKS protocol version'); - break; - } - $host_ip = $ip; - $port = $this->socks_host_port; - $host_server_type = $server_type; - $server_type = 'SOCKS'; - if(strlen($error = $this->Resolve($this->socks_host_name, $ip, $server_type))) - return($error); - } - if($this->debug) - $this->OutputDebug('Connecting to '.$server_type.' server IP '.$ip.' port '.$port.'...'); - if($ssl) - $ip="ssl://".$host_name; - if(($this->connection=($this->timeout ? @fsockopen($ip, $port, $errno, $error, $this->timeout) : @fsockopen($ip, $port, $errno)))==0) - { - $error_code = HTTP_CLIENT_ERROR_CANNOT_CONNECT; - switch($errno) - { - case -3: - return($this->SetError("socket could not be created", $error_code)); - case -4: - return($this->SetError("dns lookup on hostname \"".$host_name."\" failed", $error_code)); - case -5: - return($this->SetError("connection refused or timed out", $error_code)); - case -6: - return($this->SetError("fdopen() call failed", $error_code)); - case -7: - return($this->SetError("setvbuf() call failed", $error_code)); - default: - return($this->SetPHPError($errno." could not connect to the host \"".$host_name."\"",$php_errormsg, $error_code)); - } - } - else - { - if($this->data_timeout - && function_exists("socket_set_timeout")) - socket_set_timeout($this->connection,$this->data_timeout,0); - if(strlen($this->socks_host_name)) - { - if($this->debug) - $this->OutputDebug('Connected to the SOCKS server '.$this->socks_host_name); - $send_error = 'it was not possible to send data to the SOCKS server'; - $receive_error = 'it was not possible to receive data from the SOCKS server'; - switch($version) - { - case 4: - $command = 1; - $user = ''; - if(!fputs($this->connection, chr($version).chr($command).pack('nN', $host_port, ip2long($host_ip)).$user.Chr(0))) - $error = $this->SetDataAccessError($send_error); - else - { - $response = fgets($this->connection, 9); - if(strlen($response) != 8) - $error = $this->SetDataAccessError($receive_error); - else - { - $socks_errors = array( - "\x5a"=>'', - "\x5b"=>'request rejected', - "\x5c"=>'request failed because client is not running identd (or not reachable from the server)', - "\x5d"=>'request failed because client\'s identd could not confirm the user ID string in the request', - ); - $error_code = $response[1]; - $error = (IsSet($socks_errors[$error_code]) ? $socks_errors[$error_code] : 'unknown'); - if(strlen($error)) - $error = 'SOCKS error: '.$error; - } - } - break; - case 5: - if($this->debug) - $this->OutputDebug('Negotiating the authentication method ...'); - $methods = 1; - $method = 0; - if(!fputs($this->connection, chr($version).chr($methods).chr($method))) - $error = $this->SetDataAccessError($send_error); - else - { - $response = fgets($this->connection, 3); - if(strlen($response) != 2) - $error = $this->SetDataAccessError($receive_error); - elseif(Ord($response[1]) != $method) - $error = 'the SOCKS server requires an authentication method that is not yet supported'; - else - { - if($this->debug) - $this->OutputDebug('Connecting to '.$host_server_type.' server IP '.$host_ip.' port '.$host_port.'...'); - $command = 1; - $address_type = 1; - if(!fputs($this->connection, chr($version).chr($command)."\x00".chr($address_type).pack('Nn', ip2long($host_ip), $host_port))) - $error = $this->SetDataAccessError($send_error); - else - { - $response = fgets($this->connection, 11); - if(strlen($response) != 10) - $error = $this->SetDataAccessError($receive_error); - else - { - $socks_errors = array( - "\x00"=>'', - "\x01"=>'general SOCKS server failure', - "\x02"=>'connection not allowed by ruleset', - "\x03"=>'Network unreachable', - "\x04"=>'Host unreachable', - "\x05"=>'Connection refused', - "\x06"=>'TTL expired', - "\x07"=>'Command not supported', - "\x08"=>'Address type not supported' - ); - $error_code = $response[1]; - $error = (IsSet($socks_errors[$error_code]) ? $socks_errors[$error_code] : 'unknown'); - if(strlen($error)) - $error = 'SOCKS error: '.$error; - } - } - } - } - break; - default: - $error = 'support for SOCKS protocol version '.$this->socks_version.' is not yet implemented'; - break; - } - if(strlen($error)) - { - fclose($this->connection); - return($error); - } - } - if($this->debug) - $this->OutputDebug("Connected to $host_name"); - if(strlen($this->proxy_host_name) - && !strcmp(strtolower($this->protocol), 'https')) - { - if(function_exists('stream_socket_enable_crypto') - && in_array('ssl', stream_get_transports())) - $this->state = "ConnectedToProxy"; - else - { - $this->OutputDebug("It is not possible to start SSL after connecting to the proxy server. If the proxy refuses to forward the SSL request, you may need to upgrade to PHP 5.1 or later with OpenSSL support enabled."); - $this->state="Connected"; - } - } - else - $this->state="Connected"; - return(""); - } - } + public Function Connect($host_name, $host_port, $ssl, $server_type = 'HTTP') + { + $domain=$host_name; + $port = $host_port; + if(strlen($error = $this->Resolve($domain, $ip, $server_type))) + return($error); + if (strlen($this->socks_host_name)) { + switch ($this->socks_version) { + case '4': + $version = 4; + break; + case '5': + $version = 5; + break; + default: + return('it was not specified a supported SOCKS protocol version'); + break; + } + $host_ip = $ip; + $port = $this->socks_host_port; + $host_server_type = $server_type; + $server_type = 'SOCKS'; + if(strlen($error = $this->Resolve($this->socks_host_name, $ip, $server_type))) + return($error); + } + if($this->debug) + $this->OutputDebug('Connecting to '.$server_type.' server IP '.$ip.' port '.$port.'...'); + if($ssl) + $ip="ssl://".$host_name; + if (($this->connection=($this->timeout ? @fsockopen($ip, $port, $errno, $error, $this->timeout) : @fsockopen($ip, $port, $errno)))==0) { + $error_code = HTTP_CLIENT_ERROR_CANNOT_CONNECT; + switch ($errno) { + case -3: + return($this->SetError("socket could not be created", $error_code)); + case -4: + return($this->SetError("dns lookup on hostname \"".$host_name."\" failed", $error_code)); + case -5: + return($this->SetError("connection refused or timed out", $error_code)); + case -6: + return($this->SetError("fdopen() call failed", $error_code)); + case -7: + return($this->SetError("setvbuf() call failed", $error_code)); + default: + return($this->SetPHPError($errno." could not connect to the host \"".$host_name."\"",$php_errormsg, $error_code)); + } + } else { + if($this->data_timeout + && function_exists("socket_set_timeout")) + socket_set_timeout($this->connection,$this->data_timeout,0); + if (strlen($this->socks_host_name)) { + if($this->debug) + $this->OutputDebug('Connected to the SOCKS server '.$this->socks_host_name); + $send_error = 'it was not possible to send data to the SOCKS server'; + $receive_error = 'it was not possible to receive data from the SOCKS server'; + switch ($version) { + case 4: + $command = 1; + $user = ''; + if(!fputs($this->connection, chr($version).chr($command).pack('nN', $host_port, ip2long($host_ip)).$user.Chr(0))) + $error = $this->SetDataAccessError($send_error); + else { + $response = fgets($this->connection, 9); + if(strlen($response) != 8) + $error = $this->SetDataAccessError($receive_error); + else { + $socks_errors = array( + "\x5a"=>'', + "\x5b"=>'request rejected', + "\x5c"=>'request failed because client is not running identd (or not reachable from the server)', + "\x5d"=>'request failed because client\'s identd could not confirm the user ID string in the request', + ); + $error_code = $response[1]; + $error = (IsSet($socks_errors[$error_code]) ? $socks_errors[$error_code] : 'unknown'); + if(strlen($error)) + $error = 'SOCKS error: '.$error; + } + } + break; + case 5: + if($this->debug) + $this->OutputDebug('Negotiating the authentication method ...'); + $methods = 1; + $method = 0; + if(!fputs($this->connection, chr($version).chr($methods).chr($method))) + $error = $this->SetDataAccessError($send_error); + else { + $response = fgets($this->connection, 3); + if(strlen($response) != 2) + $error = $this->SetDataAccessError($receive_error); + elseif(Ord($response[1]) != $method) + $error = 'the SOCKS server requires an authentication method that is not yet supported'; + else { + if($this->debug) + $this->OutputDebug('Connecting to '.$host_server_type.' server IP '.$host_ip.' port '.$host_port.'...'); + $command = 1; + $address_type = 1; + if(!fputs($this->connection, chr($version).chr($command)."\x00".chr($address_type).pack('Nn', ip2long($host_ip), $host_port))) + $error = $this->SetDataAccessError($send_error); + else { + $response = fgets($this->connection, 11); + if(strlen($response) != 10) + $error = $this->SetDataAccessError($receive_error); + else { + $socks_errors = array( + "\x00"=>'', + "\x01"=>'general SOCKS server failure', + "\x02"=>'connection not allowed by ruleset', + "\x03"=>'Network unreachable', + "\x04"=>'Host unreachable', + "\x05"=>'Connection refused', + "\x06"=>'TTL expired', + "\x07"=>'Command not supported', + "\x08"=>'Address type not supported' + ); + $error_code = $response[1]; + $error = (IsSet($socks_errors[$error_code]) ? $socks_errors[$error_code] : 'unknown'); + if(strlen($error)) + $error = 'SOCKS error: '.$error; + } + } + } + } + break; + default: + $error = 'support for SOCKS protocol version '.$this->socks_version.' is not yet implemented'; + break; + } + if (strlen($error)) { + fclose($this->connection); + return($error); + } + } + if($this->debug) + $this->OutputDebug("Connected to $host_name"); + if(strlen($this->proxy_host_name) + && !strcmp(strtolower($this->protocol), 'https')) + { + if(function_exists('stream_socket_enable_crypto') + && in_array('ssl', stream_get_transports())) + $this->state = "ConnectedToProxy"; + else { + $this->OutputDebug("It is not possible to start SSL after connecting to the proxy server. If the proxy refuses to forward the SSL request, you may need to upgrade to PHP 5.1 or later with OpenSSL support enabled."); + $this->state="Connected"; + } + } else + $this->state="Connected"; + return(""); + } + } - Function Disconnect() - { - if($this->debug) - $this->OutputDebug("Disconnected from ".$this->connected_host); - if($this->use_curl) - { - curl_close($this->connection); - $this->response=""; - } - else - fclose($this->connection); - $this->state="Disconnected"; - return(""); - } + public Function Disconnect() + { + if($this->debug) + $this->OutputDebug("Disconnected from ".$this->connected_host); + if ($this->use_curl) { + curl_close($this->connection); + $this->response=""; + } else + fclose($this->connection); + $this->state="Disconnected"; + return(""); + } - /* Public methods */ + /* Public methods */ - Function GetRequestArguments($url, &$arguments) - { - $this->error = ''; - $this->error_code = HTTP_CLIENT_ERROR_NO_ERROR; - $arguments=array(); - $url = str_replace(' ', '%20', $url); - $parameters=@parse_url($url); - if(!$parameters) - return($this->SetError("it was not specified a valid URL", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - if(!IsSet($parameters["scheme"])) - return($this->SetError("it was not specified the protocol type argument", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - switch(strtolower($parameters["scheme"])) - { - case "http": - case "https": - $arguments["Protocol"]=$parameters["scheme"]; - break; - default: - return($parameters["scheme"]." connection scheme is not yet supported"); - } - if(!IsSet($parameters["host"])) - return($this->SetError("it was not specified the connection host argument", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - $arguments["HostName"]=$parameters["host"]; - $arguments["Headers"]=array("Host"=>$parameters["host"].(IsSet($parameters["port"]) ? ":".$parameters["port"] : "")); - if(IsSet($parameters["user"])) - { - $arguments["AuthUser"]=UrlDecode($parameters["user"]); - if(!IsSet($parameters["pass"])) - $arguments["AuthPassword"]=""; - } - if(IsSet($parameters["pass"])) - { - if(!IsSet($parameters["user"])) - $arguments["AuthUser"]=""; - $arguments["AuthPassword"]=UrlDecode($parameters["pass"]); - } - if(IsSet($parameters["port"])) - { - if(strcmp($parameters["port"],strval(intval($parameters["port"])))) - return($this->SetError("it was not specified a valid connection host argument", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - $arguments["HostPort"]=intval($parameters["port"]); - } - else - $arguments["HostPort"]=0; - $arguments["RequestURI"]=(IsSet($parameters["path"]) ? $parameters["path"] : "/").(IsSet($parameters["query"]) ? "?".$parameters["query"] : ""); - if(strlen($this->user_agent)) - $arguments["Headers"]["User-Agent"]=$this->user_agent; - if(strlen($this->accept)) - $arguments["Headers"]["Accept"]=$this->accept; - return(""); - } + public Function GetRequestArguments($url, &$arguments) + { + $this->error = ''; + $this->error_code = HTTP_CLIENT_ERROR_NO_ERROR; + $arguments=array(); + $url = str_replace(' ', '%20', $url); + $parameters=@parse_url($url); + if(!$parameters) + return($this->SetError("it was not specified a valid URL", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + if(!IsSet($parameters["scheme"])) + return($this->SetError("it was not specified the protocol type argument", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + switch (strtolower($parameters["scheme"])) { + case "http": + case "https": + $arguments["Protocol"]=$parameters["scheme"]; + break; + default: + return($parameters["scheme"]." connection scheme is not yet supported"); + } + if(!IsSet($parameters["host"])) + return($this->SetError("it was not specified the connection host argument", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + $arguments["HostName"]=$parameters["host"]; + $arguments["Headers"]=array("Host"=>$parameters["host"].(IsSet($parameters["port"]) ? ":".$parameters["port"] : "")); + if (IsSet($parameters["user"])) { + $arguments["AuthUser"]=UrlDecode($parameters["user"]); + if(!IsSet($parameters["pass"])) + $arguments["AuthPassword"]=""; + } + if (IsSet($parameters["pass"])) { + if(!IsSet($parameters["user"])) + $arguments["AuthUser"]=""; + $arguments["AuthPassword"]=UrlDecode($parameters["pass"]); + } + if (IsSet($parameters["port"])) { + if(strcmp($parameters["port"],strval(intval($parameters["port"])))) + return($this->SetError("it was not specified a valid connection host argument", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + $arguments["HostPort"]=intval($parameters["port"]); + } else + $arguments["HostPort"]=0; + $arguments["RequestURI"]=(IsSet($parameters["path"]) ? $parameters["path"] : "/").(IsSet($parameters["query"]) ? "?".$parameters["query"] : ""); + if(strlen($this->user_agent)) + $arguments["Headers"]["User-Agent"]=$this->user_agent; + if(strlen($this->accept)) + $arguments["Headers"]["Accept"]=$this->accept; + return(""); + } - Function Open($arguments) - { - if(strlen($this->error)) - return($this->error); - $error_code = HTTP_CLIENT_ERROR_UNSPECIFIED_ERROR; - if(IsSet($arguments["HostName"])) - $this->host_name=$arguments["HostName"]; - if(IsSet($arguments["HostPort"])) - $this->host_port=$arguments["HostPort"]; - if(IsSet($arguments["ProxyHostName"])) - $this->proxy_host_name=$arguments["ProxyHostName"]; - if(IsSet($arguments["ProxyHostPort"])) - $this->proxy_host_port=$arguments["ProxyHostPort"]; - if(IsSet($arguments["SOCKSHostName"])) - $this->socks_host_name=$arguments["SOCKSHostName"]; - if(IsSet($arguments["SOCKSHostPort"])) - $this->socks_host_port=$arguments["SOCKSHostPort"]; - if(IsSet($arguments["SOCKSVersion"])) - $this->socks_version=$arguments["SOCKSVersion"]; - if(IsSet($arguments["Protocol"])) - $this->protocol=$arguments["Protocol"]; - switch(strtolower($this->protocol)) - { - case "http": - $default_port=80; - break; - case "https": - $default_port=443; - break; - default: - return($this->SetError("it was not specified a valid connection protocol", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - } - if(strlen($this->proxy_host_name)==0) - { - if(strlen($this->host_name)==0) - return($this->SetError("it was not specified a valid hostname", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - $host_name=$this->host_name; - $host_port=($this->host_port ? $this->host_port : $default_port); - $server_type = 'HTTP'; - } - else - { - $host_name=$this->proxy_host_name; - $host_port=$this->proxy_host_port; - $server_type = 'HTTP proxy'; - } - $ssl=(strtolower($this->protocol)=="https" && strlen($this->proxy_host_name)==0); - if($ssl - && strlen($this->socks_host_name)) - return($this->SetError('establishing SSL connections via a SOCKS server is not yet supported', HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - $this->use_curl=($ssl && $this->prefer_curl && function_exists("curl_init")); - switch($this->state) - { - case 'Connected': - if(!strcmp($host_name, $this->connected_host) - && intval($host_port) == $this->connected_port - && intval($ssl) == $this->connected_ssl) - { - if($this->debug) - $this->OutputDebug("Reusing connection to ".$this->connected_host); - return(''); - } - if(strlen($error = $this->Disconnect())) - return($error); - case "Disconnected": - break; - default: - return("1 already connected"); - } - if($this->debug) - $this->OutputDebug("Connecting to ".$this->host_name); - if($this->use_curl) - { - $error=(($this->connection=curl_init($this->protocol."://".$this->host_name.($host_port==$default_port ? "" : ":".strval($host_port))."/")) ? "" : "Could not initialize a CURL session"); - if(strlen($error)==0) - { - if(IsSet($arguments["SSLCertificateFile"])) - curl_setopt($this->connection,CURLOPT_SSLCERT,$arguments["SSLCertificateFile"]); - if(IsSet($arguments["SSLCertificatePassword"])) - curl_setopt($this->connection,CURLOPT_SSLCERTPASSWD,$arguments["SSLCertificatePassword"]); - if(IsSet($arguments["SSLKeyFile"])) - curl_setopt($this->connection,CURLOPT_SSLKEY,$arguments["SSLKeyFile"]); - if(IsSet($arguments["SSLKeyPassword"])) - curl_setopt($this->connection,CURLOPT_SSLKEYPASSWD,$arguments["SSLKeyPassword"]); - } - $this->state="Connected"; - } - else - { - $error=""; - if(strlen($this->proxy_host_name) - && (IsSet($arguments["SSLCertificateFile"]) - || IsSet($arguments["SSLCertificateFile"]))) - $error="establishing SSL connections using certificates or private keys via non-SSL proxies is not supported"; - else - { - if($ssl) - { - if(IsSet($arguments["SSLCertificateFile"])) - $error="establishing SSL connections using certificates is only supported when the cURL extension is enabled"; - elseif(IsSet($arguments["SSLKeyFile"])) - $error="establishing SSL connections using a private key is only supported when the cURL extension is enabled"; - else - { - $version=explode(".",function_exists("phpversion") ? phpversion() : "3.0.7"); - $php_version=intval($version[0])*1000000+intval($version[1])*1000+intval($version[2]); - if($php_version<4003000) - $error="establishing SSL connections requires at least PHP version 4.3.0 or having the cURL extension enabled"; - elseif(!function_exists("extension_loaded") - || !extension_loaded("openssl")) - $error="establishing SSL connections requires the OpenSSL extension enabled"; - } - } - if(strlen($error)==0) - { - $error=$this->Connect($host_name, $host_port, $ssl, $server_type); - $error_code = $this->error_code; - } - } - } - if(strlen($error)) - return($this->SetError($error, $error_code)); - $this->session=md5(uniqid("")); - $this->connected_host = $host_name; - $this->connected_port = intval($host_port); - $this->connected_ssl = intval($ssl); - return(""); - } + public Function Open($arguments) + { + if(strlen($this->error)) + return($this->error); + $error_code = HTTP_CLIENT_ERROR_UNSPECIFIED_ERROR; + if(IsSet($arguments["HostName"])) + $this->host_name=$arguments["HostName"]; + if(IsSet($arguments["HostPort"])) + $this->host_port=$arguments["HostPort"]; + if(IsSet($arguments["ProxyHostName"])) + $this->proxy_host_name=$arguments["ProxyHostName"]; + if(IsSet($arguments["ProxyHostPort"])) + $this->proxy_host_port=$arguments["ProxyHostPort"]; + if(IsSet($arguments["SOCKSHostName"])) + $this->socks_host_name=$arguments["SOCKSHostName"]; + if(IsSet($arguments["SOCKSHostPort"])) + $this->socks_host_port=$arguments["SOCKSHostPort"]; + if(IsSet($arguments["SOCKSVersion"])) + $this->socks_version=$arguments["SOCKSVersion"]; + if(IsSet($arguments["Protocol"])) + $this->protocol=$arguments["Protocol"]; + switch (strtolower($this->protocol)) { + case "http": + $default_port=80; + break; + case "https": + $default_port=443; + break; + default: + return($this->SetError("it was not specified a valid connection protocol", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + } + if (strlen($this->proxy_host_name)==0) { + if(strlen($this->host_name)==0) + return($this->SetError("it was not specified a valid hostname", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + $host_name=$this->host_name; + $host_port=($this->host_port ? $this->host_port : $default_port); + $server_type = 'HTTP'; + } else { + $host_name=$this->proxy_host_name; + $host_port=$this->proxy_host_port; + $server_type = 'HTTP proxy'; + } + $ssl=(strtolower($this->protocol)=="https" && strlen($this->proxy_host_name)==0); + if($ssl + && strlen($this->socks_host_name)) + return($this->SetError('establishing SSL connections via a SOCKS server is not yet supported', HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + $this->use_curl=($ssl && $this->prefer_curl && function_exists("curl_init")); + switch ($this->state) { + case 'Connected': + if(!strcmp($host_name, $this->connected_host) + && intval($host_port) == $this->connected_port + && intval($ssl) == $this->connected_ssl) + { + if($this->debug) + $this->OutputDebug("Reusing connection to ".$this->connected_host); + return(''); + } + if(strlen($error = $this->Disconnect())) + return($error); + case "Disconnected": + break; + default: + return("1 already connected"); + } + if($this->debug) + $this->OutputDebug("Connecting to ".$this->host_name); + if ($this->use_curl) { + $error=(($this->connection=curl_init($this->protocol."://".$this->host_name.($host_port==$default_port ? "" : ":".strval($host_port))."/")) ? "" : "Could not initialize a CURL session"); + if (strlen($error)==0) { + if(IsSet($arguments["SSLCertificateFile"])) + curl_setopt($this->connection,CURLOPT_SSLCERT,$arguments["SSLCertificateFile"]); + if(IsSet($arguments["SSLCertificatePassword"])) + curl_setopt($this->connection,CURLOPT_SSLCERTPASSWD,$arguments["SSLCertificatePassword"]); + if(IsSet($arguments["SSLKeyFile"])) + curl_setopt($this->connection,CURLOPT_SSLKEY,$arguments["SSLKeyFile"]); + if(IsSet($arguments["SSLKeyPassword"])) + curl_setopt($this->connection,CURLOPT_SSLKEYPASSWD,$arguments["SSLKeyPassword"]); + } + $this->state="Connected"; + } else { + $error=""; + if(strlen($this->proxy_host_name) + && (IsSet($arguments["SSLCertificateFile"]) + || IsSet($arguments["SSLCertificateFile"]))) + $error="establishing SSL connections using certificates or private keys via non-SSL proxies is not supported"; + else { + if ($ssl) { + if(IsSet($arguments["SSLCertificateFile"])) + $error="establishing SSL connections using certificates is only supported when the cURL extension is enabled"; + elseif(IsSet($arguments["SSLKeyFile"])) + $error="establishing SSL connections using a private key is only supported when the cURL extension is enabled"; + else { + $version=explode(".",function_exists("phpversion") ? phpversion() : "3.0.7"); + $php_version=intval($version[0])*1000000+intval($version[1])*1000+intval($version[2]); + if($php_version<4003000) + $error="establishing SSL connections requires at least PHP version 4.3.0 or having the cURL extension enabled"; + elseif(!function_exists("extension_loaded") + || !extension_loaded("openssl")) + $error="establishing SSL connections requires the OpenSSL extension enabled"; + } + } + if (strlen($error)==0) { + $error=$this->Connect($host_name, $host_port, $ssl, $server_type); + $error_code = $this->error_code; + } + } + } + if(strlen($error)) + return($this->SetError($error, $error_code)); + $this->session=md5(uniqid("")); + $this->connected_host = $host_name; + $this->connected_port = intval($host_port); + $this->connected_ssl = intval($ssl); + return(""); + } - Function Close($force = 0) - { - if($this->state=="Disconnected") - return("1 already disconnected"); - if(!$this->force_close - && $this->keep_alive - && !$force - && $this->state == 'ResponseReceived') - { - if($this->debug) - $this->OutputDebug('Keeping the connection alive to '.$this->connected_host); - $this->state = 'Connected'; - return(''); - } - return($this->Disconnect()); - } + public Function Close($force = 0) + { + if($this->state=="Disconnected") + return("1 already disconnected"); + if(!$this->force_close + && $this->keep_alive + && !$force + && $this->state == 'ResponseReceived') + { + if($this->debug) + $this->OutputDebug('Keeping the connection alive to '.$this->connected_host); + $this->state = 'Connected'; + return(''); + } + return($this->Disconnect()); + } - Function PickCookies(&$cookies,$secure) - { - if(IsSet($this->cookies[$secure])) - { - $now=gmdate("Y-m-d H-i-s"); - for($domain=0,Reset($this->cookies[$secure]);$domaincookies[$secure]);Next($this->cookies[$secure]),$domain++) - { - $domain_pattern=Key($this->cookies[$secure]); - $match=strlen($this->request_host)-strlen($domain_pattern); - if($match>=0 - && !strcmp($domain_pattern,substr($this->request_host,$match)) - && ($match==0 - || $domain_pattern[0]=="." - || $this->request_host[$match-1]==".")) - { - for(Reset($this->cookies[$secure][$domain_pattern]),$path_part=0;$path_partcookies[$secure][$domain_pattern]);Next($this->cookies[$secure][$domain_pattern]),$path_part++) - { - $path=Key($this->cookies[$secure][$domain_pattern]); - if(strlen($this->request_uri)>=strlen($path) - && substr($this->request_uri,0,strlen($path))==$path) - { - for(Reset($this->cookies[$secure][$domain_pattern][$path]),$cookie=0;$cookiecookies[$secure][$domain_pattern][$path]);Next($this->cookies[$secure][$domain_pattern][$path]),$cookie++) - { - $cookie_name=Key($this->cookies[$secure][$domain_pattern][$path]); - $expires=$this->cookies[$secure][$domain_pattern][$path][$cookie_name]["expires"]; - if($expires=="" - || strcmp($now,$expires)<0) - $cookies[$cookie_name]=$this->cookies[$secure][$domain_pattern][$path][$cookie_name]; - } - } - } - } - } - } - } + public Function PickCookies(&$cookies,$secure) + { + if (IsSet($this->cookies[$secure])) { + $now=gmdate("Y-m-d H-i-s"); + for ($domain=0,Reset($this->cookies[$secure]);$domaincookies[$secure]);Next($this->cookies[$secure]),$domain++) { + $domain_pattern=Key($this->cookies[$secure]); + $match=strlen($this->request_host)-strlen($domain_pattern); + if($match>=0 + && !strcmp($domain_pattern,substr($this->request_host,$match)) + && ($match==0 + || $domain_pattern[0]=="." + || $this->request_host[$match-1]==".")) + { + for (Reset($this->cookies[$secure][$domain_pattern]),$path_part=0;$path_partcookies[$secure][$domain_pattern]);Next($this->cookies[$secure][$domain_pattern]),$path_part++) { + $path=Key($this->cookies[$secure][$domain_pattern]); + if(strlen($this->request_uri)>=strlen($path) + && substr($this->request_uri,0,strlen($path))==$path) + { + for (Reset($this->cookies[$secure][$domain_pattern][$path]),$cookie=0;$cookiecookies[$secure][$domain_pattern][$path]);Next($this->cookies[$secure][$domain_pattern][$path]),$cookie++) { + $cookie_name=Key($this->cookies[$secure][$domain_pattern][$path]); + $expires=$this->cookies[$secure][$domain_pattern][$path][$cookie_name]["expires"]; + if($expires=="" + || strcmp($now,$expires)<0) + $cookies[$cookie_name]=$this->cookies[$secure][$domain_pattern][$path][$cookie_name]; + } + } + } + } + } + } + } - Function GetFileDefinition($file, &$definition) - { - $name=""; - if(IsSet($file["FileName"])) - $name=basename($file["FileName"]); - if(IsSet($file["Name"])) - $name=$file["Name"]; - if(strlen($name)==0) - return("it was not specified the file part name"); - if(IsSet($file["Content-Type"])) - { - $content_type=$file["Content-Type"]; - $type=$this->Tokenize(strtolower($content_type),"/"); - $sub_type=$this->Tokenize(""); - switch($type) - { - case "text": - case "image": - case "audio": - case "video": - case "application": - case "message": - break; - case "automatic": - switch($sub_type) - { - case "name": - switch(GetType($dot=strrpos($name,"."))=="integer" ? strtolower(substr($name,$dot)) : "") - { - case ".xls": - $content_type="application/excel"; - break; - case ".hqx": - $content_type="application/macbinhex40"; - break; - case ".doc": - case ".dot": - case ".wrd": - $content_type="application/msword"; - break; - case ".pdf": - $content_type="application/pdf"; - break; - case ".pgp": - $content_type="application/pgp"; - break; - case ".ps": - case ".eps": - case ".ai": - $content_type="application/postscript"; - break; - case ".ppt": - $content_type="application/powerpoint"; - break; - case ".rtf": - $content_type="application/rtf"; - break; - case ".tgz": - case ".gtar": - $content_type="application/x-gtar"; - break; - case ".gz": - $content_type="application/x-gzip"; - break; - case ".php": - case ".php3": - $content_type="application/x-httpd-php"; - break; - case ".js": - $content_type="application/x-javascript"; - break; - case ".ppd": - case ".psd": - $content_type="application/x-photoshop"; - break; - case ".swf": - case ".swc": - case ".rf": - $content_type="application/x-shockwave-flash"; - break; - case ".tar": - $content_type="application/x-tar"; - break; - case ".zip": - $content_type="application/zip"; - break; - case ".mid": - case ".midi": - case ".kar": - $content_type="audio/midi"; - break; - case ".mp2": - case ".mp3": - case ".mpga": - $content_type="audio/mpeg"; - break; - case ".ra": - $content_type="audio/x-realaudio"; - break; - case ".wav": - $content_type="audio/wav"; - break; - case ".bmp": - $content_type="image/bitmap"; - break; - case ".gif": - $content_type="image/gif"; - break; - case ".iff": - $content_type="image/iff"; - break; - case ".jb2": - $content_type="image/jb2"; - break; - case ".jpg": - case ".jpe": - case ".jpeg": - $content_type="image/jpeg"; - break; - case ".jpx": - $content_type="image/jpx"; - break; - case ".png": - $content_type="image/png"; - break; - case ".tif": - case ".tiff": - $content_type="image/tiff"; - break; - case ".wbmp": - $content_type="image/vnd.wap.wbmp"; - break; - case ".xbm": - $content_type="image/xbm"; - break; - case ".css": - $content_type="text/css"; - break; - case ".txt": - $content_type="text/plain"; - break; - case ".htm": - case ".html": - $content_type="text/html"; - break; - case ".xml": - $content_type="text/xml"; - break; - case ".mpg": - case ".mpe": - case ".mpeg": - $content_type="video/mpeg"; - break; - case ".qt": - case ".mov": - $content_type="video/quicktime"; - break; - case ".avi": - $content_type="video/x-ms-video"; - break; - case ".eml": - $content_type="message/rfc822"; - break; - default: - $content_type="application/octet-stream"; - break; - } - break; - default: - return($content_type." is not a supported automatic content type detection method"); - } - break; - default: - return($content_type." is not a supported file content type"); - } - } - else - $content_type="application/octet-stream"; - $definition=array( - "Content-Type"=>$content_type, - "NAME"=>$name - ); - if(IsSet($file["FileName"])) - { - if(GetType($length=@filesize($file["FileName"]))!="integer") - { - $error="it was not possible to determine the length of the file ".$file["FileName"]; - if(IsSet($php_errormsg) - && strlen($php_errormsg)) - $error.=": ".$php_errormsg; - if(!file_exists($file["FileName"])) - $error="it was not possible to access the file ".$file["FileName"]; - return($error); - } - $definition["FILENAME"]=$file["FileName"]; - $definition["Content-Length"]=$length; - } - elseif(IsSet($file["Data"])) - $definition["Content-Length"]=strlen($definition["DATA"]=$file["Data"]); - else - return("it was not specified a valid file name"); - return(""); - } + public Function GetFileDefinition($file, &$definition) + { + $name=""; + if(IsSet($file["FileName"])) + $name=basename($file["FileName"]); + if(IsSet($file["Name"])) + $name=$file["Name"]; + if(strlen($name)==0) + return("it was not specified the file part name"); + if (IsSet($file["Content-Type"])) { + $content_type=$file["Content-Type"]; + $type=$this->Tokenize(strtolower($content_type),"/"); + $sub_type=$this->Tokenize(""); + switch ($type) { + case "text": + case "image": + case "audio": + case "video": + case "application": + case "message": + break; + case "automatic": + switch ($sub_type) { + case "name": + switch (GetType($dot=strrpos($name,"."))=="integer" ? strtolower(substr($name,$dot)) : "") { + case ".xls": + $content_type="application/excel"; + break; + case ".hqx": + $content_type="application/macbinhex40"; + break; + case ".doc": + case ".dot": + case ".wrd": + $content_type="application/msword"; + break; + case ".pdf": + $content_type="application/pdf"; + break; + case ".pgp": + $content_type="application/pgp"; + break; + case ".ps": + case ".eps": + case ".ai": + $content_type="application/postscript"; + break; + case ".ppt": + $content_type="application/powerpoint"; + break; + case ".rtf": + $content_type="application/rtf"; + break; + case ".tgz": + case ".gtar": + $content_type="application/x-gtar"; + break; + case ".gz": + $content_type="application/x-gzip"; + break; + case ".php": + case ".php3": + $content_type="application/x-httpd-php"; + break; + case ".js": + $content_type="application/x-javascript"; + break; + case ".ppd": + case ".psd": + $content_type="application/x-photoshop"; + break; + case ".swf": + case ".swc": + case ".rf": + $content_type="application/x-shockwave-flash"; + break; + case ".tar": + $content_type="application/x-tar"; + break; + case ".zip": + $content_type="application/zip"; + break; + case ".mid": + case ".midi": + case ".kar": + $content_type="audio/midi"; + break; + case ".mp2": + case ".mp3": + case ".mpga": + $content_type="audio/mpeg"; + break; + case ".ra": + $content_type="audio/x-realaudio"; + break; + case ".wav": + $content_type="audio/wav"; + break; + case ".bmp": + $content_type="image/bitmap"; + break; + case ".gif": + $content_type="image/gif"; + break; + case ".iff": + $content_type="image/iff"; + break; + case ".jb2": + $content_type="image/jb2"; + break; + case ".jpg": + case ".jpe": + case ".jpeg": + $content_type="image/jpeg"; + break; + case ".jpx": + $content_type="image/jpx"; + break; + case ".png": + $content_type="image/png"; + break; + case ".tif": + case ".tiff": + $content_type="image/tiff"; + break; + case ".wbmp": + $content_type="image/vnd.wap.wbmp"; + break; + case ".xbm": + $content_type="image/xbm"; + break; + case ".css": + $content_type="text/css"; + break; + case ".txt": + $content_type="text/plain"; + break; + case ".htm": + case ".html": + $content_type="text/html"; + break; + case ".xml": + $content_type="text/xml"; + break; + case ".mpg": + case ".mpe": + case ".mpeg": + $content_type="video/mpeg"; + break; + case ".qt": + case ".mov": + $content_type="video/quicktime"; + break; + case ".avi": + $content_type="video/x-ms-video"; + break; + case ".eml": + $content_type="message/rfc822"; + break; + default: + $content_type="application/octet-stream"; + break; + } + break; + default: + return($content_type." is not a supported automatic content type detection method"); + } + break; + default: + return($content_type." is not a supported file content type"); + } + } else + $content_type="application/octet-stream"; + $definition=array( + "Content-Type"=>$content_type, + "NAME"=>$name + ); + if (IsSet($file["FileName"])) { + if (GetType($length=@filesize($file["FileName"]))!="integer") { + $error="it was not possible to determine the length of the file ".$file["FileName"]; + if(IsSet($php_errormsg) + && strlen($php_errormsg)) + $error.=": ".$php_errormsg; + if(!file_exists($file["FileName"])) + $error="it was not possible to access the file ".$file["FileName"]; + return($error); + } + $definition["FILENAME"]=$file["FileName"]; + $definition["Content-Length"]=$length; + } elseif(IsSet($file["Data"])) + $definition["Content-Length"]=strlen($definition["DATA"]=$file["Data"]); + else + return("it was not specified a valid file name"); + return(""); + } - Function ConnectFromProxy($arguments, &$headers) - { - if(!$this->PutLine('CONNECT '.$this->host_name.':'.($this->host_port ? $this->host_port : 443).' HTTP/1.0') - || (strlen($this->user_agent) - && !$this->PutLine('User-Agent: '.$this->user_agent)) - || (strlen($this->accept) - && !$this->PutLine('Accept: '.$this->accept)) - || (IsSet($arguments['Headers']['Proxy-Authorization']) - && !$this->PutLine('Proxy-Authorization: '.$arguments['Headers']['Proxy-Authorization'])) - || !$this->PutLine('')) - { - $this->Disconnect(); - return($this->error); - } - $this->state = "ConnectSent"; - if(strlen($error=$this->ReadReplyHeadersResponse($headers))) - return($error); - $proxy_authorization=""; - while(!strcmp($this->response_status, "100")) - { - $this->state="ConnectSent"; - if(strlen($error=$this->ReadReplyHeadersResponse($headers))) - return($error); - } - switch($this->response_status) - { - case "200": - if(!@stream_socket_enable_crypto($this->connection, 1, STREAM_CRYPTO_METHOD_SSLv23_CLIENT)) - { - $this->SetPHPError('it was not possible to start a SSL encrypted connection via this proxy', $php_errormsg, HTTP_CLIENT_ERROR_COMMUNICATION_FAILURE); - $this->Disconnect(); - return($this->error); - } - $this->state = "Connected"; - break; - case "407": - if(strlen($error=$this->Authenticate($headers, -1, $proxy_authorization, $this->proxy_request_user, $this->proxy_request_password, $this->proxy_request_realm, $this->proxy_request_workstation))) - return($error); - break; - default: - return($this->SetError("unable to send request via proxy", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); - } - return(""); - } + public Function ConnectFromProxy($arguments, &$headers) + { + if(!$this->PutLine('CONNECT '.$this->host_name.':'.($this->host_port ? $this->host_port : 443).' HTTP/1.0') + || (strlen($this->user_agent) + && !$this->PutLine('User-Agent: '.$this->user_agent)) + || (strlen($this->accept) + && !$this->PutLine('Accept: '.$this->accept)) + || (IsSet($arguments['Headers']['Proxy-Authorization']) + && !$this->PutLine('Proxy-Authorization: '.$arguments['Headers']['Proxy-Authorization'])) + || !$this->PutLine('')) + { + $this->Disconnect(); + return($this->error); + } + $this->state = "ConnectSent"; + if(strlen($error=$this->ReadReplyHeadersResponse($headers))) + return($error); + $proxy_authorization=""; + while (!strcmp($this->response_status, "100")) { + $this->state="ConnectSent"; + if(strlen($error=$this->ReadReplyHeadersResponse($headers))) + return($error); + } + switch ($this->response_status) { + case "200": + if (!@stream_socket_enable_crypto($this->connection, 1, STREAM_CRYPTO_METHOD_SSLv23_CLIENT)) { + $this->SetPHPError('it was not possible to start a SSL encrypted connection via this proxy', $php_errormsg, HTTP_CLIENT_ERROR_COMMUNICATION_FAILURE); + $this->Disconnect(); + return($this->error); + } + $this->state = "Connected"; + break; + case "407": + if(strlen($error=$this->Authenticate($headers, -1, $proxy_authorization, $this->proxy_request_user, $this->proxy_request_password, $this->proxy_request_realm, $this->proxy_request_workstation))) + return($error); + break; + default: + return($this->SetError("unable to send request via proxy", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); + } + return(""); + } - Function SendRequest($arguments) - { - if(strlen($this->error)) - return($this->error); - if(IsSet($arguments["ProxyUser"])) - $this->proxy_request_user=$arguments["ProxyUser"]; - elseif(IsSet($this->proxy_user)) - $this->proxy_request_user=$this->proxy_user; - if(IsSet($arguments["ProxyPassword"])) - $this->proxy_request_password=$arguments["ProxyPassword"]; - elseif(IsSet($this->proxy_password)) - $this->proxy_request_password=$this->proxy_password; - if(IsSet($arguments["ProxyRealm"])) - $this->proxy_request_realm=$arguments["ProxyRealm"]; - elseif(IsSet($this->proxy_realm)) - $this->proxy_request_realm=$this->proxy_realm; - if(IsSet($arguments["ProxyWorkstation"])) - $this->proxy_request_workstation=$arguments["ProxyWorkstation"]; - elseif(IsSet($this->proxy_workstation)) - $this->proxy_request_workstation=$this->proxy_workstation; - switch($this->state) - { - case "Disconnected": - return($this->SetError("connection was not yet established", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - case "Connected": - $connect = 0; - break; - case "ConnectedToProxy": - if(strlen($error = $this->ConnectFromProxy($arguments, $headers))) - return($error); - $connect = 1; - break; - default: - return($this->SetError("can not send request in the current connection state", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - } - if(IsSet($arguments["RequestMethod"])) - $this->request_method=$arguments["RequestMethod"]; - if(IsSet($arguments["User-Agent"])) - $this->user_agent=$arguments["User-Agent"]; - if(!IsSet($arguments["Headers"]["User-Agent"]) - && strlen($this->user_agent)) - $arguments["Headers"]["User-Agent"]=$this->user_agent; - if(IsSet($arguments["KeepAlive"])) - $this->keep_alive=intval($arguments["KeepAlive"]); - if(!IsSet($arguments["Headers"]["Connection"]) - && $this->keep_alive) - $arguments["Headers"]["Connection"]='Keep-Alive'; - if(IsSet($arguments["Accept"])) - $this->user_agent=$arguments["Accept"]; - if(!IsSet($arguments["Headers"]["Accept"]) - && strlen($this->accept)) - $arguments["Headers"]["Accept"]=$this->accept; - if(strlen($this->request_method)==0) - return($this->SetError("it was not specified a valid request method", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - if(IsSet($arguments["RequestURI"])) - $this->request_uri=$arguments["RequestURI"]; - if(strlen($this->request_uri)==0 - || substr($this->request_uri,0,1)!="/") - return($this->SetError("it was not specified a valid request URI", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - $this->request_arguments=$arguments; - $this->request_headers=(IsSet($arguments["Headers"]) ? $arguments["Headers"] : array()); - $body_length=0; - $this->request_body=""; - $get_body=1; - if($this->request_method=="POST" - || $this->request_method=="PUT") - { - if(IsSet($arguments['StreamRequest'])) - { - $get_body = 0; - $this->request_headers["Transfer-Encoding"]="chunked"; - } - elseif(IsSet($arguments["PostFiles"]) - || ($this->force_multipart_form_post - && IsSet($arguments["PostValues"]))) - { - $boundary="--".md5(uniqid(time())); - $this->request_headers["Content-Type"]="multipart/form-data; boundary=".$boundary.(IsSet($arguments["CharSet"]) ? "; charset=".$arguments["CharSet"] : ""); - $post_parts=array(); - if(IsSet($arguments["PostValues"])) - { - $values=$arguments["PostValues"]; - if(GetType($values)!="array") - return($this->SetError("it was not specified a valid POST method values array", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - for(Reset($values),$value=0;$value$headers,"DATA"=>$data); - $body_length+=strlen($headers)+strlen($data)+strlen("\r\n"); - } - } - $body_length+=strlen("--".$boundary."--\r\n"); - $files=(IsSet($arguments["PostFiles"]) ? $arguments["PostFiles"] : array()); - Reset($files); - $end=(GetType($input=Key($files))!="string"); - for(;!$end;) - { - if(strlen($error=$this->GetFileDefinition($files[$input],$definition))) - return("3 ".$error); - $headers="--".$boundary."\r\nContent-Disposition: form-data; name=\"".$input."\"; filename=\"".$definition["NAME"]."\"\r\nContent-Type: ".$definition["Content-Type"]."\r\n\r\n"; - $part=count($post_parts); - $post_parts[$part]=array("HEADERS"=>$headers); - if(IsSet($definition["FILENAME"])) - { - $post_parts[$part]["FILENAME"]=$definition["FILENAME"]; - $data=""; - } - else - $data=$definition["DATA"]; - $post_parts[$part]["DATA"]=$data; - $body_length+=strlen($headers)+$definition["Content-Length"]+strlen("\r\n"); - Next($files); - $end=(GetType($input=Key($files))!="string"); - } - $get_body=0; - } - elseif(IsSet($arguments["PostValues"])) - { - $values=$arguments["PostValues"]; - if(GetType($values)!="array") - return($this->SetError("it was not specified a valid POST method values array", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - for(Reset($values),$value=0;$value0) - $this->request_body.="&"; - $this->request_body.=UrlEncode($k)."=".UrlEncode($values[$k][$v]); - } - } - else - { - if($value>0) - $this->request_body.="&"; - $this->request_body.=UrlEncode($k)."=".UrlEncode($values[$k]); - } - } - $this->request_headers["Content-Type"]="application/x-www-form-urlencoded".(IsSet($arguments["CharSet"]) ? "; charset=".$arguments["CharSet"] : ""); - $get_body=0; - } - } - if($get_body - && (IsSet($arguments["Body"]) - || IsSet($arguments["BodyStream"]))) - { - if(IsSet($arguments["Body"])) - $this->request_body=$arguments["Body"]; - else - { - $stream=$arguments["BodyStream"]; - $this->request_body=""; - for($part=0; $partrequest_body.=$stream[$part]["Data"]; - elseif(IsSet($stream[$part]["File"])) - { - if(!($file=@fopen($stream[$part]["File"],"rb"))) - return($this->SetPHPError("could not open upload file ".$stream[$part]["File"], $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE)); - while(!feof($file)) - { - if(GetType($block=@fread($file,$this->file_buffer_length))!="string") - { - $error=$this->SetPHPError("could not read body stream file ".$stream[$part]["File"], $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE); - fclose($file); - return($error); - } - $this->request_body.=$block; - } - fclose($file); - } - else - return("5 it was not specified a valid file or data body stream element at position ".$part); - } - } - if(!IsSet($this->request_headers["Content-Type"])) - $this->request_headers["Content-Type"]="application/octet-stream".(IsSet($arguments["CharSet"]) ? "; charset=".$arguments["CharSet"] : ""); - } - if(IsSet($arguments["AuthUser"])) - $this->request_user=$arguments["AuthUser"]; - elseif(IsSet($this->user)) - $this->request_user=$this->user; - if(IsSet($arguments["AuthPassword"])) - $this->request_password=$arguments["AuthPassword"]; - elseif(IsSet($this->password)) - $this->request_password=$this->password; - if(IsSet($arguments["AuthRealm"])) - $this->request_realm=$arguments["AuthRealm"]; - elseif(IsSet($this->realm)) - $this->request_realm=$this->realm; - if(IsSet($arguments["AuthWorkstation"])) - $this->request_workstation=$arguments["AuthWorkstation"]; - elseif(IsSet($this->workstation)) - $this->request_workstation=$this->workstation; - if(strlen($this->proxy_host_name)==0 - || $connect) - $request_uri=$this->request_uri; - else - { - switch(strtolower($this->protocol)) - { - case "http": - $default_port=80; - break; - case "https": - $default_port=443; - break; - } - $request_uri=strtolower($this->protocol)."://".$this->host_name.(($this->host_port==0 || $this->host_port==$default_port) ? "" : ":".$this->host_port).$this->request_uri; - } - if($this->use_curl) - { - $version=(GetType($v=curl_version())=="array" ? (IsSet($v["version"]) ? $v["version"] : "0.0.0") : (preg_match("/^libcurl\\/([0-9]+\\.[0-9]+\\.[0-9]+)/",$v,$m) ? $m[1] : "0.0.0")); - $curl_version=100000*intval($this->Tokenize($version,"."))+1000*intval($this->Tokenize("."))+intval($this->Tokenize("")); - $protocol_version=($curl_version<713002 ? "1.0" : $this->protocol_version); - } - else - $protocol_version=$this->protocol_version; - $this->request=$this->request_method." ".$request_uri." HTTP/".$protocol_version; - if($body_length - || ($body_length=strlen($this->request_body))) - $this->request_headers["Content-Length"]=$body_length; - for($headers=array(),$host_set=0,Reset($this->request_headers),$header=0;$headerrequest_headers);Next($this->request_headers),$header++) - { - $header_name=Key($this->request_headers); - $header_value=$this->request_headers[$header_name]; - if(GetType($header_value)=="array") - { - for(Reset($header_value),$value=0;$valuerequest_headers))=="host") - { - $this->request_host=strtolower($header_value); - $host_set=1; - } - } - if(!$host_set) - { - $headers[]="Host: ".$this->host_name; - $this->request_host=strtolower($this->host_name); - } - if(count($this->cookies)) - { - $cookies=array(); - $this->PickCookies($cookies,0); - if(strtolower($this->protocol)=="https") - $this->PickCookies($cookies,1); - if(count($cookies)) - { - $h=count($headers); - $headers[$h]="Cookie:"; - for(Reset($cookies),$cookie=0;$cookieuse_curl) - { - if(IsSet($arguments['StreamRequest'])) - return($this->SetError("Streaming request data is not supported when using Curl", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - if($body_length - && strlen($this->request_body)==0) - { - for($request_body="",$success=1,$part=0;$partSetPHPError("could not open upload file ".$post_parts[$part]["FILENAME"], $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE); - $success=0; - break; - } - while(!feof($file)) - { - if(GetType($block=@fread($file,$this->file_buffer_length))!="string") - { - $this->SetPHPError("could not read upload file", $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE); - $success=0; - break; - } - $request_body.=$block; - } - fclose($file); - if(!$success) - break; - } - $request_body.="\r\n"; - } - $request_body.="--".$boundary."--\r\n"; - } - else - $request_body=$this->request_body; - curl_setopt($this->connection,CURLOPT_HEADER,1); - curl_setopt($this->connection,CURLOPT_RETURNTRANSFER,1); - if($this->timeout) - curl_setopt($this->connection,CURLOPT_TIMEOUT,$this->timeout); - curl_setopt($this->connection,CURLOPT_SSL_VERIFYPEER,0); - curl_setopt($this->connection,CURLOPT_SSL_VERIFYHOST,0); - $request=$this->request."\r\n".implode("\r\n",$headers)."\r\n\r\n".$request_body; - curl_setopt($this->connection,CURLOPT_CUSTOMREQUEST,$request); - if($this->debug) - $this->OutputDebug("C ".$request); - if(!($success=(strlen($this->response=curl_exec($this->connection))!=0))) - { - $error=curl_error($this->connection); - $this->SetError("Could not execute the request".(strlen($error) ? ": ".$error : ""), HTTP_CLIENT_ERROR_PROTOCOL_FAILURE); - } - } - else - { - if(($success=$this->PutLine($this->request))) - { - for($header=0;$headerPutLine($headers[$header])) - break; - } - if($success - && ($success=$this->PutLine(""))) - { - if(IsSet($arguments['StreamRequest'])) - $next_state = "SendingRequestBody"; - elseif($body_length) - { - if(strlen($this->request_body)) - $success=$this->PutData($this->request_body); - else - { - for($part=0;$partPutData($post_parts[$part]["HEADERS"])) - || !($success=$this->PutData($post_parts[$part]["DATA"]))) - break; - if(IsSet($post_parts[$part]["FILENAME"])) - { - if(!($file=@fopen($post_parts[$part]["FILENAME"],"rb"))) - { - $this->SetPHPError("could not open upload file ".$post_parts[$part]["FILENAME"], $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE); - $success=0; - break; - } - while(!feof($file)) - { - if(GetType($block=@fread($file,$this->file_buffer_length))!="string") - { - $this->SetPHPError("could not read upload file", $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE); - $success=0; - break; - } - if(!($success=$this->PutData($block))) - break; - } - fclose($file); - if(!$success) - break; - } - if(!($success=$this->PutLine(""))) - break; - } - if($success) - $success=$this->PutLine("--".$boundary."--"); - } - if($success) - $sucess=$this->FlushData(); - } - } - } - } - if(!$success) - return($this->SetError("could not send the HTTP request: ".$this->error, $this->error_code)); - $this->state=$next_state; - return(""); - } + public Function SendRequest($arguments) + { + if(strlen($this->error)) + return($this->error); + if(IsSet($arguments["ProxyUser"])) + $this->proxy_request_user=$arguments["ProxyUser"]; + elseif(IsSet($this->proxy_user)) + $this->proxy_request_user=$this->proxy_user; + if(IsSet($arguments["ProxyPassword"])) + $this->proxy_request_password=$arguments["ProxyPassword"]; + elseif(IsSet($this->proxy_password)) + $this->proxy_request_password=$this->proxy_password; + if(IsSet($arguments["ProxyRealm"])) + $this->proxy_request_realm=$arguments["ProxyRealm"]; + elseif(IsSet($this->proxy_realm)) + $this->proxy_request_realm=$this->proxy_realm; + if(IsSet($arguments["ProxyWorkstation"])) + $this->proxy_request_workstation=$arguments["ProxyWorkstation"]; + elseif(IsSet($this->proxy_workstation)) + $this->proxy_request_workstation=$this->proxy_workstation; + switch ($this->state) { + case "Disconnected": + return($this->SetError("connection was not yet established", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + case "Connected": + $connect = 0; + break; + case "ConnectedToProxy": + if(strlen($error = $this->ConnectFromProxy($arguments, $headers))) + return($error); + $connect = 1; + break; + default: + return($this->SetError("can not send request in the current connection state", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + } + if(IsSet($arguments["RequestMethod"])) + $this->request_method=$arguments["RequestMethod"]; + if(IsSet($arguments["User-Agent"])) + $this->user_agent=$arguments["User-Agent"]; + if(!IsSet($arguments["Headers"]["User-Agent"]) + && strlen($this->user_agent)) + $arguments["Headers"]["User-Agent"]=$this->user_agent; + if(IsSet($arguments["KeepAlive"])) + $this->keep_alive=intval($arguments["KeepAlive"]); + if(!IsSet($arguments["Headers"]["Connection"]) + && $this->keep_alive) + $arguments["Headers"]["Connection"]='Keep-Alive'; + if(IsSet($arguments["Accept"])) + $this->user_agent=$arguments["Accept"]; + if(!IsSet($arguments["Headers"]["Accept"]) + && strlen($this->accept)) + $arguments["Headers"]["Accept"]=$this->accept; + if(strlen($this->request_method)==0) + return($this->SetError("it was not specified a valid request method", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + if(IsSet($arguments["RequestURI"])) + $this->request_uri=$arguments["RequestURI"]; + if(strlen($this->request_uri)==0 + || substr($this->request_uri,0,1)!="/") + return($this->SetError("it was not specified a valid request URI", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + $this->request_arguments=$arguments; + $this->request_headers=(IsSet($arguments["Headers"]) ? $arguments["Headers"] : array()); + $body_length=0; + $this->request_body=""; + $get_body=1; + if($this->request_method=="POST" + || $this->request_method=="PUT") + { + if (IsSet($arguments['StreamRequest'])) { + $get_body = 0; + $this->request_headers["Transfer-Encoding"]="chunked"; + } elseif(IsSet($arguments["PostFiles"]) + || ($this->force_multipart_form_post + && IsSet($arguments["PostValues"]))) + { + $boundary="--".md5(uniqid(time())); + $this->request_headers["Content-Type"]="multipart/form-data; boundary=".$boundary.(IsSet($arguments["CharSet"]) ? "; charset=".$arguments["CharSet"] : ""); + $post_parts=array(); + if (IsSet($arguments["PostValues"])) { + $values=$arguments["PostValues"]; + if(GetType($values)!="array") + return($this->SetError("it was not specified a valid POST method values array", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + for (Reset($values),$value=0;$value$headers,"DATA"=>$data); + $body_length+=strlen($headers)+strlen($data)+strlen("\r\n"); + } + } + $body_length+=strlen("--".$boundary."--\r\n"); + $files=(IsSet($arguments["PostFiles"]) ? $arguments["PostFiles"] : array()); + Reset($files); + $end=(GetType($input=Key($files))!="string"); + for (;!$end;) { + if(strlen($error=$this->GetFileDefinition($files[$input],$definition))) + return("3 ".$error); + $headers="--".$boundary."\r\nContent-Disposition: form-data; name=\"".$input."\"; filename=\"".$definition["NAME"]."\"\r\nContent-Type: ".$definition["Content-Type"]."\r\n\r\n"; + $part=count($post_parts); + $post_parts[$part]=array("HEADERS"=>$headers); + if (IsSet($definition["FILENAME"])) { + $post_parts[$part]["FILENAME"]=$definition["FILENAME"]; + $data=""; + } else + $data=$definition["DATA"]; + $post_parts[$part]["DATA"]=$data; + $body_length+=strlen($headers)+$definition["Content-Length"]+strlen("\r\n"); + Next($files); + $end=(GetType($input=Key($files))!="string"); + } + $get_body=0; + } elseif (IsSet($arguments["PostValues"])) { + $values=$arguments["PostValues"]; + if(GetType($values)!="array") + return($this->SetError("it was not specified a valid POST method values array", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + for (Reset($values),$value=0;$value0) + $this->request_body.="&"; + $this->request_body.=UrlEncode($k)."=".UrlEncode($values[$k][$v]); + } + } else { + if($value>0) + $this->request_body.="&"; + $this->request_body.=UrlEncode($k)."=".UrlEncode($values[$k]); + } + } + $this->request_headers["Content-Type"]="application/x-www-form-urlencoded".(IsSet($arguments["CharSet"]) ? "; charset=".$arguments["CharSet"] : ""); + $get_body=0; + } + } + if($get_body + && (IsSet($arguments["Body"]) + || IsSet($arguments["BodyStream"]))) + { + if(IsSet($arguments["Body"])) + $this->request_body=$arguments["Body"]; + else { + $stream=$arguments["BodyStream"]; + $this->request_body=""; + for ($part=0; $partrequest_body.=$stream[$part]["Data"]; + elseif (IsSet($stream[$part]["File"])) { + if(!($file=@fopen($stream[$part]["File"],"rb"))) + return($this->SetPHPError("could not open upload file ".$stream[$part]["File"], $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE)); + while (!feof($file)) { + if (GetType($block=@fread($file,$this->file_buffer_length))!="string") { + $error=$this->SetPHPError("could not read body stream file ".$stream[$part]["File"], $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE); + fclose($file); + return($error); + } + $this->request_body.=$block; + } + fclose($file); + } else + return("5 it was not specified a valid file or data body stream element at position ".$part); + } + } + if(!IsSet($this->request_headers["Content-Type"])) + $this->request_headers["Content-Type"]="application/octet-stream".(IsSet($arguments["CharSet"]) ? "; charset=".$arguments["CharSet"] : ""); + } + if(IsSet($arguments["AuthUser"])) + $this->request_user=$arguments["AuthUser"]; + elseif(IsSet($this->user)) + $this->request_user=$this->user; + if(IsSet($arguments["AuthPassword"])) + $this->request_password=$arguments["AuthPassword"]; + elseif(IsSet($this->password)) + $this->request_password=$this->password; + if(IsSet($arguments["AuthRealm"])) + $this->request_realm=$arguments["AuthRealm"]; + elseif(IsSet($this->realm)) + $this->request_realm=$this->realm; + if(IsSet($arguments["AuthWorkstation"])) + $this->request_workstation=$arguments["AuthWorkstation"]; + elseif(IsSet($this->workstation)) + $this->request_workstation=$this->workstation; + if(strlen($this->proxy_host_name)==0 + || $connect) + $request_uri=$this->request_uri; + else { + switch (strtolower($this->protocol)) { + case "http": + $default_port=80; + break; + case "https": + $default_port=443; + break; + } + $request_uri=strtolower($this->protocol)."://".$this->host_name.(($this->host_port==0 || $this->host_port==$default_port) ? "" : ":".$this->host_port).$this->request_uri; + } + if ($this->use_curl) { + $version=(GetType($v=curl_version())=="array" ? (IsSet($v["version"]) ? $v["version"] : "0.0.0") : (preg_match("/^libcurl\\/([0-9]+\\.[0-9]+\\.[0-9]+)/",$v,$m) ? $m[1] : "0.0.0")); + $curl_version=100000*intval($this->Tokenize($version,"."))+1000*intval($this->Tokenize("."))+intval($this->Tokenize("")); + $protocol_version=($curl_version<713002 ? "1.0" : $this->protocol_version); + } else + $protocol_version=$this->protocol_version; + $this->request=$this->request_method." ".$request_uri." HTTP/".$protocol_version; + if($body_length + || ($body_length=strlen($this->request_body))) + $this->request_headers["Content-Length"]=$body_length; + for ($headers=array(),$host_set=0,Reset($this->request_headers),$header=0;$headerrequest_headers);Next($this->request_headers),$header++) { + $header_name=Key($this->request_headers); + $header_value=$this->request_headers[$header_name]; + if (GetType($header_value)=="array") { + for(Reset($header_value),$value=0;$valuerequest_headers))=="host") { + $this->request_host=strtolower($header_value); + $host_set=1; + } + } + if (!$host_set) { + $headers[]="Host: ".$this->host_name; + $this->request_host=strtolower($this->host_name); + } + if (count($this->cookies)) { + $cookies=array(); + $this->PickCookies($cookies,0); + if(strtolower($this->protocol)=="https") + $this->PickCookies($cookies,1); + if (count($cookies)) { + $h=count($headers); + $headers[$h]="Cookie:"; + for (Reset($cookies),$cookie=0;$cookieuse_curl) { + if(IsSet($arguments['StreamRequest'])) + return($this->SetError("Streaming request data is not supported when using Curl", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + if($body_length + && strlen($this->request_body)==0) + { + for ($request_body="",$success=1,$part=0;$partSetPHPError("could not open upload file ".$post_parts[$part]["FILENAME"], $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE); + $success=0; + break; + } + while (!feof($file)) { + if (GetType($block=@fread($file,$this->file_buffer_length))!="string") { + $this->SetPHPError("could not read upload file", $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE); + $success=0; + break; + } + $request_body.=$block; + } + fclose($file); + if(!$success) + break; + } + $request_body.="\r\n"; + } + $request_body.="--".$boundary."--\r\n"; + } else + $request_body=$this->request_body; + curl_setopt($this->connection,CURLOPT_HEADER,1); + curl_setopt($this->connection,CURLOPT_RETURNTRANSFER,1); + if($this->timeout) + curl_setopt($this->connection,CURLOPT_TIMEOUT,$this->timeout); + curl_setopt($this->connection,CURLOPT_SSL_VERIFYPEER,0); + curl_setopt($this->connection,CURLOPT_SSL_VERIFYHOST,0); + $request=$this->request."\r\n".implode("\r\n",$headers)."\r\n\r\n".$request_body; + curl_setopt($this->connection,CURLOPT_CUSTOMREQUEST,$request); + if($this->debug) + $this->OutputDebug("C ".$request); + if (!($success=(strlen($this->response=curl_exec($this->connection))!=0))) { + $error=curl_error($this->connection); + $this->SetError("Could not execute the request".(strlen($error) ? ": ".$error : ""), HTTP_CLIENT_ERROR_PROTOCOL_FAILURE); + } + } else { + if (($success=$this->PutLine($this->request))) { + for ($header=0;$headerPutLine($headers[$header])) + break; + } + if($success + && ($success=$this->PutLine(""))) + { + if(IsSet($arguments['StreamRequest'])) + $next_state = "SendingRequestBody"; + elseif ($body_length) { + if(strlen($this->request_body)) + $success=$this->PutData($this->request_body); + else { + for ($part=0;$partPutData($post_parts[$part]["HEADERS"])) + || !($success=$this->PutData($post_parts[$part]["DATA"]))) + break; + if (IsSet($post_parts[$part]["FILENAME"])) { + if (!($file=@fopen($post_parts[$part]["FILENAME"],"rb"))) { + $this->SetPHPError("could not open upload file ".$post_parts[$part]["FILENAME"], $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE); + $success=0; + break; + } + while (!feof($file)) { + if (GetType($block=@fread($file,$this->file_buffer_length))!="string") { + $this->SetPHPError("could not read upload file", $php_errormsg, HTTP_CLIENT_ERROR_CANNOT_ACCESS_LOCAL_FILE); + $success=0; + break; + } + if(!($success=$this->PutData($block))) + break; + } + fclose($file); + if(!$success) + break; + } + if(!($success=$this->PutLine(""))) + break; + } + if($success) + $success=$this->PutLine("--".$boundary."--"); + } + if($success) + $sucess=$this->FlushData(); + } + } + } + } + if(!$success) + return($this->SetError("could not send the HTTP request: ".$this->error, $this->error_code)); + $this->state=$next_state; + return(""); + } - Function SetCookie($name, $value, $expires="" , $path="/" , $domain="" , $secure=0, $verbatim=0) - { - if(strlen($this->error)) - return($this->error); - if(strlen($name)==0) - return($this->SetError("it was not specified a valid cookie name", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - if(strlen($path)==0 - || strcmp($path[0],"/")) - return($this->SetError($path." is not a valid path for setting cookie ".$name, HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - if($domain=="" - || !strpos($domain,".",$domain[0]=="." ? 1 : 0)) - return($this->SetError($domain." is not a valid domain for setting cookie ".$name, HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - $domain=strtolower($domain); - if(!strcmp($domain[0],".")) - $domain=substr($domain,1); - if(!$verbatim) - { - $name=$this->CookieEncode($name,1); - $value=$this->CookieEncode($value,0); - } - $secure=intval($secure); - $this->cookies[$secure][$domain][$path][$name]=array( - "name"=>$name, - "value"=>$value, - "domain"=>$domain, - "path"=>$path, - "expires"=>$expires, - "secure"=>$secure - ); - return(""); - } + public Function SetCookie($name, $value, $expires="" , $path="/" , $domain="" , $secure=0, $verbatim=0) + { + if(strlen($this->error)) + return($this->error); + if(strlen($name)==0) + return($this->SetError("it was not specified a valid cookie name", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + if(strlen($path)==0 + || strcmp($path[0],"/")) + return($this->SetError($path." is not a valid path for setting cookie ".$name, HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + if($domain=="" + || !strpos($domain,".",$domain[0]=="." ? 1 : 0)) + return($this->SetError($domain." is not a valid domain for setting cookie ".$name, HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + $domain=strtolower($domain); + if(!strcmp($domain[0],".")) + $domain=substr($domain,1); + if (!$verbatim) { + $name=$this->CookieEncode($name,1); + $value=$this->CookieEncode($value,0); + } + $secure=intval($secure); + $this->cookies[$secure][$domain][$path][$name]=array( + "name"=>$name, + "value"=>$value, + "domain"=>$domain, + "path"=>$path, + "expires"=>$expires, + "secure"=>$secure + ); + return(""); + } - Function SendRequestBody($data, $end_of_data) - { - if(strlen($this->error)) - return($this->error); - switch($this->state) - { - case "Disconnected": - return($this->SetError("connection was not yet established", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - case "Connected": - case "ConnectedToProxy": - return($this->SetError("request was not sent", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - case "SendingRequestBody": - break; - case "RequestSent": - return($this->SetError("request body was already sent", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - default: - return($this->SetError("can not send the request body in the current connection state", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - } - $length = strlen($data); - if($length) - { - $size = dechex($length)."\r\n"; - if(!$this->PutData($size) - || !$this->PutData($data)) - return($this->error); - } - if($end_of_data) - { - $size = "0\r\n"; - if(!$this->PutData($size)) - return($this->error); - $this->state = "RequestSent"; - } - return(""); - } + public Function SendRequestBody($data, $end_of_data) + { + if(strlen($this->error)) + return($this->error); + switch ($this->state) { + case "Disconnected": + return($this->SetError("connection was not yet established", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + case "Connected": + case "ConnectedToProxy": + return($this->SetError("request was not sent", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + case "SendingRequestBody": + break; + case "RequestSent": + return($this->SetError("request body was already sent", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + default: + return($this->SetError("can not send the request body in the current connection state", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + } + $length = strlen($data); + if ($length) { + $size = dechex($length)."\r\n"; + if(!$this->PutData($size) + || !$this->PutData($data)) + return($this->error); + } + if ($end_of_data) { + $size = "0\r\n"; + if(!$this->PutData($size)) + return($this->error); + $this->state = "RequestSent"; + } + return(""); + } - Function ReadReplyHeadersResponse(&$headers) - { - $headers=array(); - if(strlen($this->error)) - return($this->error); - switch($this->state) - { - case "Disconnected": - return($this->SetError("connection was not yet established", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - case "Connected": - return($this->SetError("request was not sent", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - case "ConnectedToProxy": - return($this->SetError("connection from the remote server from the proxy was not yet established", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - case "SendingRequestBody": - return($this->SetError("request body data was not completely sent", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - case "ConnectSent": - $connect = 1; - break; - case "RequestSent": - $connect = 0; - break; - default: - return($this->SetError("can not get request headers in the current connection state", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - } - $this->content_length=$this->read_length=$this->read_response=$this->remaining_chunk=0; - $this->content_length_set=$this->chunked=$this->last_chunk_read=$chunked=0; - $this->force_close = $this->connection_close=0; - for($this->response_status="";;) - { - $line=$this->GetLine(); - if(GetType($line)!="string") - return($this->SetError("could not read request reply: ".$this->error, $this->error_code)); - if(strlen($this->response_status)==0) - { - if(!preg_match($match="/^http\\/[0-9]+\\.[0-9]+[ \t]+([0-9]+)[ \t]*(.*)\$/i",$line,$matches)) - return($this->SetError("it was received an unexpected HTTP response status", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); - $this->response_status=$matches[1]; - $this->response_message=$matches[2]; - } - if($line=="") - { - if(strlen($this->response_status)==0) - return($this->SetError("it was not received HTTP response status", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); - $this->state=($connect ? "GotConnectHeaders" : "GotReplyHeaders"); - break; - } - $header_name=strtolower($this->Tokenize($line,":")); - $header_value=Trim(Chop($this->Tokenize("\r\n"))); - if(IsSet($headers[$header_name])) - { - if(GetType($headers[$header_name])=="string") - $headers[$header_name]=array($headers[$header_name]); - $headers[$header_name][]=$header_value; - } - else - $headers[$header_name]=$header_value; - if(!$connect) - { - switch($header_name) - { - case "content-length": - $this->content_length=intval($headers[$header_name]); - $this->content_length_set=1; - break; - case "transfer-encoding": - $encoding=$this->Tokenize($header_value,"; \t"); - if(!$this->use_curl - && !strcmp($encoding,"chunked")) - $chunked=1; - break; - case "set-cookie": - if($this->support_cookies) - { - if(GetType($headers[$header_name])=="array") - $cookie_headers=$headers[$header_name]; - else - $cookie_headers=array($headers[$header_name]); - for($cookie=0;$cookieTokenize($cookie_headers[$cookie],"=")); - $cookie_value=$this->Tokenize(";"); - $domain=$this->request_host; - $path="/"; - $expires=""; - $secure=0; - while(($name = strtolower(trim(UrlDecode($this->Tokenize("=")))))!="") - { - $value=UrlDecode($this->Tokenize(";")); - switch($name) - { - case "domain": - $domain=$value; - break; - case "path": - $path=$value; - break; - case "expires": - if(preg_match("/^((Mon|Monday|Tue|Tuesday|Wed|Wednesday|Thu|Thursday|Fri|Friday|Sat|Saturday|Sun|Sunday), )?([0-9]{2})\\-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\-([0-9]{2,4}) ([0-9]{2})\\:([0-9]{2})\\:([0-9]{2}) GMT\$/",$value,$matches)) - { - $year=intval($matches[5]); - if($year<1900) - $year+=($year<70 ? 2000 : 1900); - $expires="$year-".$this->months[$matches[4]]."-".$matches[3]." ".$matches[6].":".$matches[7].":".$matches[8]; - } - break; - case "secure": - $secure=1; - break; - } - } - if(strlen($this->SetCookie($cookie_name, $cookie_value, $expires, $path , $domain, $secure, 1))) - $this->error=""; - } - } - break; - case "connection": - $this->force_close = $this->connection_close=!strcmp(strtolower($header_value),"close"); - break; - } - } - } - $this->chunked=$chunked; - if($this->content_length_set) - $this->connection_close=0; - return(""); - } + public Function ReadReplyHeadersResponse(&$headers) + { + $headers=array(); + if(strlen($this->error)) + return($this->error); + switch ($this->state) { + case "Disconnected": + return($this->SetError("connection was not yet established", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + case "Connected": + return($this->SetError("request was not sent", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + case "ConnectedToProxy": + return($this->SetError("connection from the remote server from the proxy was not yet established", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + case "SendingRequestBody": + return($this->SetError("request body data was not completely sent", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + case "ConnectSent": + $connect = 1; + break; + case "RequestSent": + $connect = 0; + break; + default: + return($this->SetError("can not get request headers in the current connection state", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + } + $this->content_length=$this->read_length=$this->read_response=$this->remaining_chunk=0; + $this->content_length_set=$this->chunked=$this->last_chunk_read=$chunked=0; + $this->force_close = $this->connection_close=0; + for ($this->response_status="";;) { + $line=$this->GetLine(); + if(GetType($line)!="string") + return($this->SetError("could not read request reply: ".$this->error, $this->error_code)); + if (strlen($this->response_status)==0) { + if(!preg_match($match="/^http\\/[0-9]+\\.[0-9]+[ \t]+([0-9]+)[ \t]*(.*)\$/i",$line,$matches)) + return($this->SetError("it was received an unexpected HTTP response status", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); + $this->response_status=$matches[1]; + $this->response_message=$matches[2]; + } + if ($line=="") { + if(strlen($this->response_status)==0) + return($this->SetError("it was not received HTTP response status", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); + $this->state=($connect ? "GotConnectHeaders" : "GotReplyHeaders"); + break; + } + $header_name=strtolower($this->Tokenize($line,":")); + $header_value=Trim(Chop($this->Tokenize("\r\n"))); + if (IsSet($headers[$header_name])) { + if(GetType($headers[$header_name])=="string") + $headers[$header_name]=array($headers[$header_name]); + $headers[$header_name][]=$header_value; + } else + $headers[$header_name]=$header_value; + if (!$connect) { + switch ($header_name) { + case "content-length": + $this->content_length=intval($headers[$header_name]); + $this->content_length_set=1; + break; + case "transfer-encoding": + $encoding=$this->Tokenize($header_value,"; \t"); + if(!$this->use_curl + && !strcmp($encoding,"chunked")) + $chunked=1; + break; + case "set-cookie": + if ($this->support_cookies) { + if(GetType($headers[$header_name])=="array") + $cookie_headers=$headers[$header_name]; + else + $cookie_headers=array($headers[$header_name]); + for ($cookie=0;$cookieTokenize($cookie_headers[$cookie],"=")); + $cookie_value=$this->Tokenize(";"); + $domain=$this->request_host; + $path="/"; + $expires=""; + $secure=0; + while (($name = strtolower(trim(UrlDecode($this->Tokenize("=")))))!="") { + $value=UrlDecode($this->Tokenize(";")); + switch ($name) { + case "domain": + $domain=$value; + break; + case "path": + $path=$value; + break; + case "expires": + if (preg_match("/^((Mon|Monday|Tue|Tuesday|Wed|Wednesday|Thu|Thursday|Fri|Friday|Sat|Saturday|Sun|Sunday), )?([0-9]{2})\\-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\-([0-9]{2,4}) ([0-9]{2})\\:([0-9]{2})\\:([0-9]{2}) GMT\$/",$value,$matches)) { + $year=intval($matches[5]); + if($year<1900) + $year+=($year<70 ? 2000 : 1900); + $expires="$year-".$this->months[$matches[4]]."-".$matches[3]." ".$matches[6].":".$matches[7].":".$matches[8]; + } + break; + case "secure": + $secure=1; + break; + } + } + if(strlen($this->SetCookie($cookie_name, $cookie_value, $expires, $path , $domain, $secure, 1))) + $this->error=""; + } + } + break; + case "connection": + $this->force_close = $this->connection_close=!strcmp(strtolower($header_value),"close"); + break; + } + } + } + $this->chunked=$chunked; + if($this->content_length_set) + $this->connection_close=0; + return(""); + } - Function Redirect(&$headers) - { - if($this->follow_redirect) - { - if(!IsSet($headers["location"]) - || (GetType($headers["location"])!="array" - && strlen($location=$headers["location"])==0) - || (GetType($headers["location"])=="array" - && strlen($location=$headers["location"][0])==0)) - return($this->SetError("it was received a redirect without location URL", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); - if(strcmp($location[0],"/")) - { - if(!($location_arguments=@parse_url($location))) - return($this->SetError("the server did not return a valid redirection location URL", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); - if(!IsSet($location_arguments["scheme"])) - $location=((GetType($end=strrpos($this->request_uri,"/"))=="integer" && $end>1) ? substr($this->request_uri,0,$end) : "")."/".$location; - } - if(!strcmp($location[0],"/")) - $location=$this->protocol."://".$this->host_name.($this->host_port ? ":".$this->host_port : "").$location; - $error=$this->GetRequestArguments($location,$arguments); - if(strlen($error)) - return($this->SetError("could not process redirect url: ".$error, HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); - $arguments["RequestMethod"]="GET"; - if(strlen($error=$this->Close())==0 - && strlen($error=$this->Open($arguments))==0 - && strlen($error=$this->SendRequest($arguments))==0) - { - $this->redirection_level++; - if($this->redirection_level>$this->redirection_limit) - { - $error="it was exceeded the limit of request redirections"; - $this->error_code = HTTP_CLIENT_ERROR_PROTOCOL_FAILURE; - } - else - $error=$this->ReadReplyHeaders($headers); - $this->redirection_level--; - } - if(strlen($error)) - return($this->SetError($error, $this->error_code)); - } - return(""); - } + public Function Redirect(&$headers) + { + if ($this->follow_redirect) { + if(!IsSet($headers["location"]) + || (GetType($headers["location"])!="array" + && strlen($location=$headers["location"])==0) + || (GetType($headers["location"])=="array" + && strlen($location=$headers["location"][0])==0)) + return($this->SetError("it was received a redirect without location URL", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); + if (strcmp($location[0],"/")) { + if(!($location_arguments=@parse_url($location))) + return($this->SetError("the server did not return a valid redirection location URL", HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); + if(!IsSet($location_arguments["scheme"])) + $location=((GetType($end=strrpos($this->request_uri,"/"))=="integer" && $end>1) ? substr($this->request_uri,0,$end) : "")."/".$location; + } + if(!strcmp($location[0],"/")) + $location=$this->protocol."://".$this->host_name.($this->host_port ? ":".$this->host_port : "").$location; + $error=$this->GetRequestArguments($location,$arguments); + if(strlen($error)) + return($this->SetError("could not process redirect url: ".$error, HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); + $arguments["RequestMethod"]="GET"; + if(strlen($error=$this->Close())==0 + && strlen($error=$this->Open($arguments))==0 + && strlen($error=$this->SendRequest($arguments))==0) + { + $this->redirection_level++; + if ($this->redirection_level>$this->redirection_limit) { + $error="it was exceeded the limit of request redirections"; + $this->error_code = HTTP_CLIENT_ERROR_PROTOCOL_FAILURE; + } else + $error=$this->ReadReplyHeaders($headers); + $this->redirection_level--; + } + if(strlen($error)) + return($this->SetError($error, $this->error_code)); + } + return(""); + } - Function Authenticate(&$headers, $proxy, &$proxy_authorization, &$user, &$password, &$realm, &$workstation) - { - if($proxy) - { - $authenticate_header="proxy-authenticate"; - $authorization_header="Proxy-Authorization"; - $authenticate_status="407"; - $authentication_mechanism=$this->proxy_authentication_mechanism; - } - else - { - $authenticate_header="www-authenticate"; - $authorization_header="Authorization"; - $authenticate_status="401"; - $authentication_mechanism=$this->authentication_mechanism; - } - if(IsSet($headers[$authenticate_header])) - { - if(function_exists("class_exists") - && !class_exists("sasl_client_class")) - return($this->SetError("the SASL client class needs to be loaded to be able to authenticate".($proxy ? " with the proxy server" : "")." and access this site", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - if(GetType($headers[$authenticate_header])=="array") - $authenticate=$headers[$authenticate_header]; - else - $authenticate=array($headers[$authenticate_header]); - for($response="", $mechanisms=array(),$m=0;$mTokenize($authenticate[$m]," "); - $response=$this->Tokenize(""); - if(strlen($authentication_mechanism)) - { - if(!strcmp($authentication_mechanism,$mechanism)) - { - $mechanisms[]=$mechanism; - break; - } - } - else - $mechanisms[]=$mechanism; - } - $sasl=new sasl_client_class; - if(IsSet($user)) - $sasl->SetCredential("user",$user); - if(IsSet($password)) - $sasl->SetCredential("password",$password); - if(IsSet($realm)) - $sasl->SetCredential("realm",$realm); - if(IsSet($workstation)) - $sasl->SetCredential("workstation",$workstation); - $sasl->SetCredential("uri",$this->request_uri); - $sasl->SetCredential("method",$this->request_method); - $sasl->SetCredential("session",$this->session); - do - { - $status=$sasl->Start($mechanisms,$message,$interactions); - } - while($status==SASL_INTERACT); - switch($status) - { - case SASL_CONTINUE: - break; - case SASL_NOMECH: - return($this->SetError(($proxy ? "proxy " : "")."authentication error: ".(strlen($authentication_mechanism) ? "authentication mechanism ".$authentication_mechanism." may not be used: " : "").$sasl->error, HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - default: - return($this->SetError("Could not start the SASL ".($proxy ? "proxy " : "")."authentication client: ".$sasl->error, HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - } - if($proxy >= 0) - { - for(;;) - { - if(strlen($error=$this->ReadReplyBody($body,$this->file_buffer_length))) - return($error); - if(strlen($body)==0) - break; - } - } - $authorization_value=$sasl->mechanism.(IsSet($message) ? " ".($sasl->encode_response ? base64_encode($message) : $message) : ""); - $request_arguments=$this->request_arguments; - $arguments=$request_arguments; - $arguments["Headers"][$authorization_header]=$authorization_value; - if(!$proxy - && strlen($proxy_authorization)) - $arguments["Headers"]["Proxy-Authorization"]=$proxy_authorization; - if(strlen($error=$this->Close()) - || strlen($error=$this->Open($arguments))) - return($this->SetError($error, $this->error_code)); - $authenticated=0; - if(IsSet($message)) - { - if($proxy < 0) - { - if(strlen($error=$this->ConnectFromProxy($arguments, $headers))) - return($this->SetError($error, $this->error_code)); - } - else - { - if(strlen($error=$this->SendRequest($arguments)) - || strlen($error=$this->ReadReplyHeadersResponse($headers))) - return($this->SetError($error, $this->error_code)); - } - if(!IsSet($headers[$authenticate_header])) - $authenticate=array(); - elseif(GetType($headers[$authenticate_header])=="array") - $authenticate=$headers[$authenticate_header]; - else - $authenticate=array($headers[$authenticate_header]); - for($mechanism=0;$mechanismTokenize($authenticate[$mechanism]," "),$sasl->mechanism)) - { - $response=$this->Tokenize(""); - break; - } - } - switch($this->response_status) - { - case $authenticate_status: - break; - case "301": - case "302": - case "303": - case "307": - if($proxy >= 0) - return($this->Redirect($headers)); - default: - if(intval($this->response_status/100)==2) - { - if($proxy) - $proxy_authorization=$authorization_value; - $authenticated=1; - break; - } - if($proxy - && !strcmp($this->response_status,"401")) - { - $proxy_authorization=$authorization_value; - $authenticated=1; - break; - } - return($this->SetError(($proxy ? "proxy " : "")."authentication error: ".$this->response_status." ".$this->response_message, HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); - } - } - for(;!$authenticated;) - { - do - { - $status=$sasl->Step($response,$message,$interactions); - } - while($status==SASL_INTERACT); - switch($status) - { - case SASL_CONTINUE: - $authorization_value=$sasl->mechanism.(IsSet($message) ? " ".($sasl->encode_response ? base64_encode($message) : $message) : ""); - $arguments=$request_arguments; - $arguments["Headers"][$authorization_header]=$authorization_value; - if(!$proxy - && strlen($proxy_authorization)) - $arguments["Headers"]["Proxy-Authorization"]=$proxy_authorization; - if($proxy < 0) - { - if(strlen($error=$this->ConnectFromProxy($arguments, $headers))) - return($this->SetError($error, $this->error_code)); - } - else - { - if(strlen($error=$this->SendRequest($arguments)) - || strlen($error=$this->ReadReplyHeadersResponse($headers))) - return($this->SetError($error, $this->error_code)); - } - switch($this->response_status) - { - case $authenticate_status: - if(GetType($headers[$authenticate_header])=="array") - $authenticate=$headers[$authenticate_header]; - else - $authenticate=array($headers[$authenticate_header]); - for($response="",$mechanism=0;$mechanismTokenize($authenticate[$mechanism]," "),$sasl->mechanism)) - { - $response=$this->Tokenize(""); - break; - } - } - if($proxy >= 0) - { - for(;;) - { - if(strlen($error=$this->ReadReplyBody($body,$this->file_buffer_length))) - return($error); - if(strlen($body)==0) - break; - } - } - $this->state="Connected"; - break; - case "301": - case "302": - case "303": - case "307": - if($proxy >= 0) - return($this->Redirect($headers)); - default: - if(intval($this->response_status/100)==2) - { - if($proxy) - $proxy_authorization=$authorization_value; - $authenticated=1; - break; - } - if($proxy - && !strcmp($this->response_status,"401")) - { - $proxy_authorization=$authorization_value; - $authenticated=1; - break; - } - return($this->SetError(($proxy ? "proxy " : "")."authentication error: ".$this->response_status." ".$this->response_message)); - } - break; - default: - return($this->SetError("Could not process the SASL ".($proxy ? "proxy " : "")."authentication step: ".$sasl->error, HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); - } - } - } - return(""); - } - - Function ReadReplyHeaders(&$headers) - { - if(strlen($error=$this->ReadReplyHeadersResponse($headers))) - return($error); - $proxy_authorization=""; - while(!strcmp($this->response_status, "100")) - { - $this->state="RequestSent"; - if(strlen($error=$this->ReadReplyHeadersResponse($headers))) - return($error); - } - switch($this->response_status) - { - case "301": - case "302": - case "303": - case "307": - if(strlen($error=$this->Redirect($headers))) - return($error); - break; - case "407": - if(strlen($error=$this->Authenticate($headers, 1, $proxy_authorization, $this->proxy_request_user, $this->proxy_request_password, $this->proxy_request_realm, $this->proxy_request_workstation))) - return($error); - if(strcmp($this->response_status,"401")) - return(""); - case "401": - return($this->Authenticate($headers, 0, $proxy_authorization, $this->request_user, $this->request_password, $this->request_realm, $this->request_workstation)); - } - return(""); - } + public Function Authenticate(&$headers, $proxy, &$proxy_authorization, &$user, &$password, &$realm, &$workstation) + { + if ($proxy) { + $authenticate_header="proxy-authenticate"; + $authorization_header="Proxy-Authorization"; + $authenticate_status="407"; + $authentication_mechanism=$this->proxy_authentication_mechanism; + } else { + $authenticate_header="www-authenticate"; + $authorization_header="Authorization"; + $authenticate_status="401"; + $authentication_mechanism=$this->authentication_mechanism; + } + if (IsSet($headers[$authenticate_header])) { + if(function_exists("class_exists") + && !class_exists("sasl_client_class")) + return($this->SetError("the SASL client class needs to be loaded to be able to authenticate".($proxy ? " with the proxy server" : "")." and access this site", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + if(GetType($headers[$authenticate_header])=="array") + $authenticate=$headers[$authenticate_header]; + else + $authenticate=array($headers[$authenticate_header]); + for ($response="", $mechanisms=array(),$m=0;$mTokenize($authenticate[$m]," "); + $response=$this->Tokenize(""); + if (strlen($authentication_mechanism)) { + if (!strcmp($authentication_mechanism,$mechanism)) { + $mechanisms[]=$mechanism; + break; + } + } else + $mechanisms[]=$mechanism; + } + $sasl=new sasl_client_class; + if(IsSet($user)) + $sasl->SetCredential("user",$user); + if(IsSet($password)) + $sasl->SetCredential("password",$password); + if(IsSet($realm)) + $sasl->SetCredential("realm",$realm); + if(IsSet($workstation)) + $sasl->SetCredential("workstation",$workstation); + $sasl->SetCredential("uri",$this->request_uri); + $sasl->SetCredential("method",$this->request_method); + $sasl->SetCredential("session",$this->session); + do { + $status=$sasl->Start($mechanisms,$message,$interactions); + } + while($status==SASL_INTERACT); + switch ($status) { + case SASL_CONTINUE: + break; + case SASL_NOMECH: + return($this->SetError(($proxy ? "proxy " : "")."authentication error: ".(strlen($authentication_mechanism) ? "authentication mechanism ".$authentication_mechanism." may not be used: " : "").$sasl->error, HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + default: + return($this->SetError("Could not start the SASL ".($proxy ? "proxy " : "")."authentication client: ".$sasl->error, HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + } + if ($proxy >= 0) { + for (;;) { + if(strlen($error=$this->ReadReplyBody($body,$this->file_buffer_length))) + return($error); + if(strlen($body)==0) + break; + } + } + $authorization_value=$sasl->mechanism.(IsSet($message) ? " ".($sasl->encode_response ? base64_encode($message) : $message) : ""); + $request_arguments=$this->request_arguments; + $arguments=$request_arguments; + $arguments["Headers"][$authorization_header]=$authorization_value; + if(!$proxy + && strlen($proxy_authorization)) + $arguments["Headers"]["Proxy-Authorization"]=$proxy_authorization; + if(strlen($error=$this->Close()) + || strlen($error=$this->Open($arguments))) + return($this->SetError($error, $this->error_code)); + $authenticated=0; + if (IsSet($message)) { + if ($proxy < 0) { + if(strlen($error=$this->ConnectFromProxy($arguments, $headers))) + return($this->SetError($error, $this->error_code)); + } else { + if(strlen($error=$this->SendRequest($arguments)) + || strlen($error=$this->ReadReplyHeadersResponse($headers))) + return($this->SetError($error, $this->error_code)); + } + if(!IsSet($headers[$authenticate_header])) + $authenticate=array(); + elseif(GetType($headers[$authenticate_header])=="array") + $authenticate=$headers[$authenticate_header]; + else + $authenticate=array($headers[$authenticate_header]); + for ($mechanism=0;$mechanismTokenize($authenticate[$mechanism]," "),$sasl->mechanism)) { + $response=$this->Tokenize(""); + break; + } + } + switch ($this->response_status) { + case $authenticate_status: + break; + case "301": + case "302": + case "303": + case "307": + if($proxy >= 0) + return($this->Redirect($headers)); + default: + if (intval($this->response_status/100)==2) { + if($proxy) + $proxy_authorization=$authorization_value; + $authenticated=1; + break; + } + if($proxy + && !strcmp($this->response_status,"401")) + { + $proxy_authorization=$authorization_value; + $authenticated=1; + break; + } + return($this->SetError(($proxy ? "proxy " : "")."authentication error: ".$this->response_status." ".$this->response_message, HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); + } + } + for (;!$authenticated;) { + do { + $status=$sasl->Step($response,$message,$interactions); + } while ($status==SASL_INTERACT); + switch ($status) { + case SASL_CONTINUE: + $authorization_value=$sasl->mechanism.(IsSet($message) ? " ".($sasl->encode_response ? base64_encode($message) : $message) : ""); + $arguments=$request_arguments; + $arguments["Headers"][$authorization_header]=$authorization_value; + if(!$proxy + && strlen($proxy_authorization)) + $arguments["Headers"]["Proxy-Authorization"]=$proxy_authorization; + if ($proxy < 0) { + if(strlen($error=$this->ConnectFromProxy($arguments, $headers))) + return($this->SetError($error, $this->error_code)); + } else { + if(strlen($error=$this->SendRequest($arguments)) + || strlen($error=$this->ReadReplyHeadersResponse($headers))) + return($this->SetError($error, $this->error_code)); + } + switch ($this->response_status) { + case $authenticate_status: + if(GetType($headers[$authenticate_header])=="array") + $authenticate=$headers[$authenticate_header]; + else + $authenticate=array($headers[$authenticate_header]); + for ($response="",$mechanism=0;$mechanismTokenize($authenticate[$mechanism]," "),$sasl->mechanism)) { + $response=$this->Tokenize(""); + break; + } + } + if ($proxy >= 0) { + for (;;) { + if(strlen($error=$this->ReadReplyBody($body,$this->file_buffer_length))) + return($error); + if(strlen($body)==0) + break; + } + } + $this->state="Connected"; + break; + case "301": + case "302": + case "303": + case "307": + if($proxy >= 0) + return($this->Redirect($headers)); + default: + if (intval($this->response_status/100)==2) { + if($proxy) + $proxy_authorization=$authorization_value; + $authenticated=1; + break; + } + if($proxy + && !strcmp($this->response_status,"401")) + { + $proxy_authorization=$authorization_value; + $authenticated=1; + break; + } + return($this->SetError(($proxy ? "proxy " : "")."authentication error: ".$this->response_status." ".$this->response_message)); + } + break; + default: + return($this->SetError("Could not process the SASL ".($proxy ? "proxy " : "")."authentication step: ".$sasl->error, HTTP_CLIENT_ERROR_PROTOCOL_FAILURE)); + } + } + } + return(""); + } - Function ReadReplyBody(&$body,$length) - { - $body=""; - if(strlen($this->error)) - return($this->error); - switch($this->state) - { - case "Disconnected": - return($this->SetError("connection was not yet established", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - case "Connected": - case "ConnectedToProxy": - return($this->SetError("request was not sent", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - case "RequestSent": - if(($error=$this->ReadReplyHeaders($headers))!="") - return($error); - break; - case "GotReplyHeaders": - break; - case 'ResponseReceived': - $body = ''; - return(''); - default: - return($this->SetError("can not get request headers in the current connection state", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - } - if($this->content_length_set) - $length=min($this->content_length-$this->read_length,$length); - $body = ''; - if($length>0) - { - if(!$this->EndOfInput() - && ($body=$this->ReadBytes($length))=="") - { - if(strlen($this->error)) - return($this->SetError("could not get the request reply body: ".$this->error, $this->error_code)); - } - $this->read_length+=strlen($body); - if($this->EndOfInput()) - $this->state = 'ResponseReceived'; - } - return(""); - } + public Function ReadReplyHeaders(&$headers) + { + if(strlen($error=$this->ReadReplyHeadersResponse($headers))) + return($error); + $proxy_authorization=""; + while (!strcmp($this->response_status, "100")) { + $this->state="RequestSent"; + if(strlen($error=$this->ReadReplyHeadersResponse($headers))) + return($error); + } + switch ($this->response_status) { + case "301": + case "302": + case "303": + case "307": + if(strlen($error=$this->Redirect($headers))) + return($error); + break; + case "407": + if(strlen($error=$this->Authenticate($headers, 1, $proxy_authorization, $this->proxy_request_user, $this->proxy_request_password, $this->proxy_request_realm, $this->proxy_request_workstation))) + return($error); + if(strcmp($this->response_status,"401")) + return(""); + case "401": + return($this->Authenticate($headers, 0, $proxy_authorization, $this->request_user, $this->request_password, $this->request_realm, $this->request_workstation)); + } + return(""); + } - Function ReadWholeReplyBody(&$body) - { - $body = ''; - for(;;) - { - if(strlen($error = $this->ReadReplyBody($block, $this->file_buffer_length))) - return($error); - if(strlen($block) == 0) - return(''); - $body .= $block; - } - } + public Function ReadReplyBody(&$body,$length) + { + $body=""; + if(strlen($this->error)) + return($this->error); + switch ($this->state) { + case "Disconnected": + return($this->SetError("connection was not yet established", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + case "Connected": + case "ConnectedToProxy": + return($this->SetError("request was not sent", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + case "RequestSent": + if(($error=$this->ReadReplyHeaders($headers))!="") + return($error); + break; + case "GotReplyHeaders": + break; + case 'ResponseReceived': + $body = ''; + return(''); + default: + return($this->SetError("can not get request headers in the current connection state", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + } + if($this->content_length_set) + $length=min($this->content_length-$this->read_length,$length); + $body = ''; + if ($length>0) { + if(!$this->EndOfInput() + && ($body=$this->ReadBytes($length))=="") + { + if(strlen($this->error)) + return($this->SetError("could not get the request reply body: ".$this->error, $this->error_code)); + } + $this->read_length+=strlen($body); + if($this->EndOfInput()) + $this->state = 'ResponseReceived'; + } + return(""); + } - Function SaveCookies(&$cookies, $domain='', $secure_only=0, $persistent_only=0) - { - $now=gmdate("Y-m-d H-i-s"); - $cookies=array(); - for($secure_cookies=0,Reset($this->cookies);$secure_cookiescookies);Next($this->cookies),$secure_cookies++) - { - $secure=Key($this->cookies); - if(!$secure_only - || $secure) - { - for($cookie_domain=0,Reset($this->cookies[$secure]);$cookie_domaincookies[$secure]);Next($this->cookies[$secure]),$cookie_domain++) - { - $domain_pattern=Key($this->cookies[$secure]); - $match=strlen($domain)-strlen($domain_pattern); - if(strlen($domain)==0 - || ($match>=0 - && !strcmp($domain_pattern,substr($domain,$match)) - && ($match==0 - || $domain_pattern[0]=="." - || $domain[$match-1]=="."))) - { - for(Reset($this->cookies[$secure][$domain_pattern]),$path_part=0;$path_partcookies[$secure][$domain_pattern]);Next($this->cookies[$secure][$domain_pattern]),$path_part++) - { - $path=Key($this->cookies[$secure][$domain_pattern]); - for(Reset($this->cookies[$secure][$domain_pattern][$path]),$cookie=0;$cookiecookies[$secure][$domain_pattern][$path]);Next($this->cookies[$secure][$domain_pattern][$path]),$cookie++) - { - $cookie_name=Key($this->cookies[$secure][$domain_pattern][$path]); - $expires=$this->cookies[$secure][$domain_pattern][$path][$cookie_name]["expires"]; - if((!$persistent_only - && strlen($expires)==0) - || (strlen($expires) - && strcmp($now,$expires)<0)) - $cookies[$secure][$domain_pattern][$path][$cookie_name]=$this->cookies[$secure][$domain_pattern][$path][$cookie_name]; - } - } - } - } - } - } - } + public Function ReadWholeReplyBody(&$body) + { + $body = ''; + for (;;) { + if(strlen($error = $this->ReadReplyBody($block, $this->file_buffer_length))) + return($error); + if(strlen($block) == 0) + return(''); + $body .= $block; + } + } - Function SavePersistentCookies(&$cookies, $domain='', $secure_only=0) - { - $this->SaveCookies($cookies, $domain, $secure_only, 1); - } + public Function SaveCookies(&$cookies, $domain='', $secure_only=0, $persistent_only=0) + { + $now=gmdate("Y-m-d H-i-s"); + $cookies=array(); + for ($secure_cookies=0,Reset($this->cookies);$secure_cookiescookies);Next($this->cookies),$secure_cookies++) { + $secure=Key($this->cookies); + if(!$secure_only + || $secure) + { + for ($cookie_domain=0,Reset($this->cookies[$secure]);$cookie_domaincookies[$secure]);Next($this->cookies[$secure]),$cookie_domain++) { + $domain_pattern=Key($this->cookies[$secure]); + $match=strlen($domain)-strlen($domain_pattern); + if(strlen($domain)==0 + || ($match>=0 + && !strcmp($domain_pattern,substr($domain,$match)) + && ($match==0 + || $domain_pattern[0]=="." + || $domain[$match-1]=="."))) + { + for (Reset($this->cookies[$secure][$domain_pattern]),$path_part=0;$path_partcookies[$secure][$domain_pattern]);Next($this->cookies[$secure][$domain_pattern]),$path_part++) { + $path=Key($this->cookies[$secure][$domain_pattern]); + for (Reset($this->cookies[$secure][$domain_pattern][$path]),$cookie=0;$cookiecookies[$secure][$domain_pattern][$path]);Next($this->cookies[$secure][$domain_pattern][$path]),$cookie++) { + $cookie_name=Key($this->cookies[$secure][$domain_pattern][$path]); + $expires=$this->cookies[$secure][$domain_pattern][$path][$cookie_name]["expires"]; + if((!$persistent_only + && strlen($expires)==0) + || (strlen($expires) + && strcmp($now,$expires)<0)) + $cookies[$secure][$domain_pattern][$path][$cookie_name]=$this->cookies[$secure][$domain_pattern][$path][$cookie_name]; + } + } + } + } + } + } + } - Function GetPersistentCookies(&$cookies, $domain='', $secure_only=0) - { - $this->SavePersistentCookies($cookies, $domain, $secure_only); - } + public Function SavePersistentCookies(&$cookies, $domain='', $secure_only=0) + { + $this->SaveCookies($cookies, $domain, $secure_only, 1); + } - Function RestoreCookies($cookies, $clear=1) - { - $new_cookies=($clear ? array() : $this->cookies); - for($secure_cookies=0, Reset($cookies); $secure_cookiesSetError("invalid cookie secure value type (".serialize($secure).")", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - for($cookie_domain=0,Reset($cookies[$secure]);$cookie_domainSetError("invalid cookie domain value type (".serialize($domain_pattern).")", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - for(Reset($cookies[$secure][$domain_pattern]),$path_part=0;$path_partSetError("invalid cookie path value type (".serialize($path).")", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - for(Reset($cookies[$secure][$domain_pattern][$path]),$cookie=0;$cookieSetError("invalid cookie expiry value type (".serialize($expires).")", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); - $new_cookies[$secure][$domain_pattern][$path][$cookie_name]=array( - "name"=>$cookie_name, - "value"=>$value, - "domain"=>$domain_pattern, - "path"=>$path, - "expires"=>$expires, - "secure"=>$secure - ); - } - } - } - } - $this->cookies=$new_cookies; - return(""); - } -}; + public Function GetPersistentCookies(&$cookies, $domain='', $secure_only=0) + { + $this->SavePersistentCookies($cookies, $domain, $secure_only); + } -?> \ No newline at end of file + public Function RestoreCookies($cookies, $clear=1) + { + $new_cookies=($clear ? array() : $this->cookies); + for ($secure_cookies=0, Reset($cookies); $secure_cookiesSetError("invalid cookie secure value type (".serialize($secure).")", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + for ($cookie_domain=0,Reset($cookies[$secure]);$cookie_domainSetError("invalid cookie domain value type (".serialize($domain_pattern).")", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + for (Reset($cookies[$secure][$domain_pattern]),$path_part=0;$path_partSetError("invalid cookie path value type (".serialize($path).")", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + for (Reset($cookies[$secure][$domain_pattern][$path]),$cookie=0;$cookieSetError("invalid cookie expiry value type (".serialize($expires).")", HTTP_CLIENT_ERROR_INVALID_PARAMETERS)); + $new_cookies[$secure][$domain_pattern][$path][$cookie_name]=array( + "name"=>$cookie_name, + "value"=>$value, + "domain"=>$domain_pattern, + "path"=>$path, + "expires"=>$expires, + "secure"=>$secure + ); + } + } + } + } + $this->cookies=$new_cookies; + return(""); + } +}; diff --git a/core/src/core/classes/interface.AjxpGroupPathProvider.php b/core/src/core/classes/interface.AjxpGroupPathProvider.php index 1dd90cc5b8..4ba81dfd74 100644 --- a/core/src/core/classes/interface.AjxpGroupPathProvider.php +++ b/core/src/core/classes/interface.AjxpGroupPathProvider.php @@ -24,9 +24,8 @@ * @package AjaXplorer * @subpackage Core */ -interface AjxpGroupPathProvider { - - +interface AjxpGroupPathProvider +{ /** * @abstract * @return String @@ -41,4 +40,4 @@ public function getGroupPath(); */ public function setGroupPath($groupPath); -} \ No newline at end of file +} diff --git a/core/src/core/classes/interface.AjxpWrapper.php b/core/src/core/classes/interface.AjxpWrapper.php index ffffbba6d2..df7d5f22d2 100644 --- a/core/src/core/classes/interface.AjxpWrapper.php +++ b/core/src/core/classes/interface.AjxpWrapper.php @@ -28,13 +28,13 @@ */ interface AjxpWrapper { - /** - * Get a "usable" reference to a file : the real file or a tmp copy. - * - * @param unknown_type $path - */ + /** + * Get a "usable" reference to a file : the real file or a tmp copy. + * + * @param unknown_type $path + */ public static function getRealFSReference($path); - + /** * Read a file (by chunks) and copy the data directly inside the given stream. * @@ -42,14 +42,14 @@ public static function getRealFSReference($path); * @param unknown_type $stream */ public static function copyFileInStream($path, $stream); - + /** * Chmod implementation for this type of access. * * @param unknown_type $path * @param unknown_type $chmodValue */ - public static function changeMode($path, $chmodValue); + public static function changeMode($path, $chmodValue); /** * Describe whether the current wrapper operates on a remote server or not. @@ -203,5 +203,4 @@ public function unlink($path); * @return array */ public function url_stat($path , $flags); -} -?> \ No newline at end of file +} diff --git a/core/src/core/classes/interface.AjxpWrapperProvider.php b/core/src/core/classes/interface.AjxpWrapperProvider.php index 044c757867..3f0b6158b8 100644 --- a/core/src/core/classes/interface.AjxpWrapperProvider.php +++ b/core/src/core/classes/interface.AjxpWrapperProvider.php @@ -26,45 +26,43 @@ * @subpackage Core * @interface AjxpWrapperProvider */ -interface AjxpWrapperProvider { +interface AjxpWrapperProvider +{ + /** + * @return string + */ + public function getWrapperClassName(); + /** + * Convert a path (from the repository root) to a fully + * qualified ajaxplorer url like ajxp.protocol://repoId/path/to/node + * @param String $path + * @return String + */ + public function getResourceUrl($path); + + /** + * Creates a directory + * @param String $path + * @param String $newDirName + */ + public function mkDir($path, $newDirName); - /** - * @return string - */ - function getWrapperClassName(); - /** - * Convert a path (from the repository root) to a fully - * qualified ajaxplorer url like ajxp.protocol://repoId/path/to/node - * @param String $path - * @return String - */ - function getResourceUrl($path); - - /** - * Creates a directory - * @param String $path - * @param String $newDirName - */ - function mkDir($path, $newDirName); - - /** - * Creates an empty file - * @param String $path - * @param String $newDirName - */ - function createEmptyFile($path, $newDirName); + /** + * Creates an empty file + * @param String $path + * @param String $newDirName + */ + public function createEmptyFile($path, $newDirName); /** * @param String $from * @param String $to * @param Boolean $copy */ - function nodeChanged(&$from, &$to, $copy = false); + public function nodeChanged(&$from, &$to, $copy = false); /** * @param String $node */ - function nodeWillChange($node, $newSize = null); + public function nodeWillChange($node, $newSize = null); } - -?> \ No newline at end of file diff --git a/core/src/core/classes/packer/class.JavaScriptPacker.php b/core/src/core/classes/packer/class.JavaScriptPacker.php index bed9710181..98d34ebb7f 100644 --- a/core/src/core/classes/packer/class.JavaScriptPacker.php +++ b/core/src/core/classes/packer/class.JavaScriptPacker.php @@ -1,40 +1,40 @@ pack(); - * + * * or - * + * * $myPacker = new JavaScriptPacker($script, 'Normal', true, false); * $packed = $myPacker->pack(); - * + * * or (default values) - * + * * $myPacker = new JavaScriptPacker($script); * $packed = $myPacker->pack(); - * - * + * + * * params of the constructor : * $script: the JavaScript to pack, string. * $encoding: level of encoding, int or string : @@ -45,14 +45,14 @@ * $specialChars: if you are flagged your private and local variables * in the script, boolean. * default: false. - * + * * The pack() method return the compressed JavasScript, as a string. - * + * * see http://dean.edwards.name/packer/usage/ for more information. - * + * * Notes : * # need PHP 5 . Tested with PHP 5.1.2, 5.1.3, 5.1.4, 5.2.3 - * + * * # The packed result may be different than with the Dean Edwards * version, but with the same length. The reason is that the PHP * function usort to sort array don't necessarily preserve the @@ -60,399 +60,422 @@ * in fact preserve this order (but that's not require by the * ECMAScript standard). So the encoded keywords order can be * different in the two results. - * + * * # Be careful with the 'High ASCII' Level encoding if you use - * UTF-8 in your files... + * UTF-8 in your files... */ -class JavaScriptPacker { - // constants - const IGNORE = '$1'; - - // validate parameters - private $_script = ''; - private $_encoding = 62; - private $_fastDecode = true; - private $_specialChars = false; - - private $LITERAL_ENCODING = array( - 'None' => 0, - 'Numeric' => 10, - 'Normal' => 62, - 'High ASCII' => 95 - ); - - public function __construct($_script, $_encoding = 62, $_fastDecode = true, $_specialChars = false) - { - $this->_script = $_script . "\n"; - if (array_key_exists($_encoding, $this->LITERAL_ENCODING)) - $_encoding = $this->LITERAL_ENCODING[$_encoding]; - $this->_encoding = min((int)$_encoding, 95); - $this->_fastDecode = $_fastDecode; - $this->_specialChars = $_specialChars; - } - - public function pack() { - $this->_addParser('_basicCompression'); - if ($this->_specialChars) - $this->_addParser('_encodeSpecialChars'); - if ($this->_encoding) - $this->_addParser('_encodeKeywords'); - - // go! - return $this->_pack($this->_script); - } - - // apply all parsing routines - private function _pack($script) { - for ($i = 0; isset($this->_parsers[$i]); $i++) { - $script = call_user_func(array(&$this,$this->_parsers[$i]), $script); - } - return $script; - } - - // keep a list of parsing functions, they'll be executed all at once - private $_parsers = array(); - private function _addParser($parser) { - $this->_parsers[] = $parser; - } - - // zero encoding - just removal of white space and comments - private function _basicCompression($script) { - $parser = new ParseMaster(); - // make safe - $parser->escapeChar = '\\'; - // protect strings - $parser->add('/\'[^\'\\n\\r]*\'/', self::IGNORE); - $parser->add('/"[^"\\n\\r]*"/', self::IGNORE); - // remove comments - $parser->add('/\\/\\/[^\\n\\r]*[\\n\\r]/', ' '); - $parser->add('/\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\//', ' '); - // protect regular expressions - $parser->add('/\\s+(\\/[^\\/\\n\\r\\*][^\\/\\n\\r]*\\/g?i?)/', '$2'); // IGNORE - $parser->add('/[^\\w\\x24\\/\'"*)\\?:]\\/[^\\/\\n\\r\\*][^\\/\\n\\r]*\\/g?i?/', self::IGNORE); - // remove: ;;; doSomething(); - if ($this->_specialChars) $parser->add('/;;;[^\\n\\r]+[\\n\\r]/'); - // remove redundant semi-colons - $parser->add('/\\(;;\\)/', self::IGNORE); // protect for (;;) loops - $parser->add('/;+\\s*([};])/', '$2'); - // apply the above - $script = $parser->exec($script); - - // remove white-space - $parser->add('/(\\b|\\x24)\\s+(\\b|\\x24)/', '$2 $3'); - $parser->add('/([+\\-])\\s+([+\\-])/', '$2 $3'); - $parser->add('/\\s+/', ''); - // done - return $parser->exec($script); - } - - private function _encodeSpecialChars($script) { - $parser = new ParseMaster(); - // replace: $name -> n, $$name -> na - $parser->add('/((\\x24+)([a-zA-Z$_]+))(\\d*)/', - array('fn' => '_replace_name') - ); - // replace: _name -> _0, double-underscore (__name) is ignored - $regexp = '/\\b_[A-Za-z\\d]\\w*/'; - // build the word list - $keywords = $this->_analyze($script, $regexp, '_encodePrivate'); - // quick ref - $encoded = $keywords['encoded']; - - $parser->add($regexp, - array( - 'fn' => '_replace_encoded', - 'data' => $encoded - ) - ); - return $parser->exec($script); - } - - private function _encodeKeywords($script) { - // escape high-ascii values already in the script (i.e. in strings) - if ($this->_encoding > 62) - $script = $this->_escape95($script); - // create the parser - $parser = new ParseMaster(); - $encode = $this->_getEncoder($this->_encoding); - // for high-ascii, don't encode single character low-ascii - $regexp = ($this->_encoding > 62) ? '/\\w\\w+/' : '/\\w+/'; - // build the word list - $keywords = $this->_analyze($script, $regexp, $encode); - $encoded = $keywords['encoded']; - - // encode - $parser->add($regexp, - array( - 'fn' => '_replace_encoded', - 'data' => $encoded - ) - ); - if (empty($script)) return $script; - else { - //$res = $parser->exec($script); - //$res = $this->_bootStrap($res, $keywords); - //return $res; - return $this->_bootStrap($parser->exec($script), $keywords); - } - } - - private function _analyze($script, $regexp, $encode) { - // analyse - // retreive all words in the script - $all = array(); - preg_match_all($regexp, $script, $all); - $_sorted = array(); // list of words sorted by frequency - $_encoded = array(); // dictionary of word->encoding - $_protected = array(); // instances of "protected" words - $all = $all[0]; // simulate the javascript comportement of global match - if (!empty($all)) { - $unsorted = array(); // same list, not sorted - $protected = array(); // "protected" words (dictionary of word->"word") - $value = array(); // dictionary of charCode->encoding (eg. 256->ff) - $this->_count = array(); // word->count - $i = count($all); $j = 0; //$word = null; - // count the occurrences - used for sorting later - do { - --$i; - $word = '$' . $all[$i]; - if (!isset($this->_count[$word])) { - $this->_count[$word] = 0; - $unsorted[$j] = $word; - // make a dictionary of all of the protected words in this script - // these are words that might be mistaken for encoding - //if (is_string($encode) && method_exists($this, $encode)) - $values[$j] = call_user_func(array(&$this, $encode), $j); - $protected['$' . $values[$j]] = $j++; - } - // increment the word counter - $this->_count[$word]++; - } while ($i > 0); - // prepare to sort the word list, first we must protect - // words that are also used as codes. we assign them a code - // equivalent to the word itself. - // e.g. if "do" falls within our encoding range - // then we store keywords["do"] = "do"; - // this avoids problems when decoding - $i = count($unsorted); - do { - $word = $unsorted[--$i]; - if (isset($protected[$word]) /*!= null*/) { - $_sorted[$protected[$word]] = substr($word, 1); - $_protected[$protected[$word]] = true; - $this->_count[$word] = 0; - } - } while ($i); - - // sort the words by frequency - // Note: the javascript and php version of sort can be different : - // in php manual, usort : - // " If two members compare as equal, - // their order in the sorted array is undefined." - // so the final packed script is different of the Dean's javascript version - // but equivalent. - // the ECMAscript standard does not guarantee this behaviour, - // and thus not all browsers (e.g. Mozilla versions dating back to at - // least 2003) respect this. - usort($unsorted, array(&$this, '_sortWords')); - $j = 0; - // because there are "protected" words in the list - // we must add the sorted words around them - do { - if (!isset($_sorted[$i])) - $_sorted[$i] = substr($unsorted[$j++], 1); - $_encoded[$_sorted[$i]] = $values[$i]; - } while (++$i < count($unsorted)); - } - return array( - 'sorted' => $_sorted, - 'encoded' => $_encoded, - 'protected' => $_protected); - } - - private $_count = array(); - private function _sortWords($match1, $match2) { - return $this->_count[$match2] - $this->_count[$match1]; - } - - // build the boot function used for loading and decoding - private function _bootStrap($packed, $keywords) { - $ENCODE = $this->_safeRegExp('$encode\\($count\\)'); - - // $packed: the packed script - $packed = "'" . $this->_escape($packed) . "'"; - - // $ascii: base for encoding - $ascii = min(count($keywords['sorted']), $this->_encoding); - if ($ascii == 0) $ascii = 1; - - // $count: number of words contained in the script - $count = count($keywords['sorted']); - - // $keywords: list of words contained in the script - foreach ($keywords['protected'] as $i=>$value) { - $keywords['sorted'][$i] = ''; - } - // convert from a string to an array - ksort($keywords['sorted']); - $keywords = "'" . implode('|',$keywords['sorted']) . "'.split('|')"; - - $encode = ($this->_encoding > 62) ? '_encode95' : $this->_getEncoder($ascii); - $encode = $this->_getJSFunction($encode); - $encode = preg_replace('/_encoding/','$ascii', $encode); - $encode = preg_replace('/arguments\\.callee/','$encode', $encode); - $inline = '\\$count' . ($ascii > 10 ? '.toString(\\$ascii)' : ''); - - // $decode: code snippet to speed up decoding - if ($this->_fastDecode) { - // create the decoder - $decode = $this->_getJSFunction('_decodeBody'); - if ($this->_encoding > 62) - $decode = preg_replace('/\\\\w/', '[\\xa1-\\xff]', $decode); - // perform the encoding inline for lower ascii values - elseif ($ascii < 36) - $decode = preg_replace($ENCODE, $inline, $decode); - // special case: when $count==0 there are no keywords. I want to keep - // the basic shape of the unpacking funcion so i'll frig the code... - if ($count == 0) - $decode = preg_replace($this->_safeRegExp('($count)\\s*=\\s*1'), '$1=0', $decode, 1); - } - - // boot function - $unpack = $this->_getJSFunction('_unpack'); - if ($this->_fastDecode) { - // insert the decoder - $this->buffer = $decode; - $unpack = preg_replace_callback('/\\{/', array(&$this, '_insertFastDecode'), $unpack, 1); - } - $unpack = preg_replace('/"/', "'", $unpack); - if ($this->_encoding > 62) { // high-ascii - // get rid of the word-boundaries for regexp matches - $unpack = preg_replace('/\'\\\\\\\\b\'\s*\\+|\\+\s*\'\\\\\\\\b\'/', '', $unpack); - } - if ($ascii > 36 || $this->_encoding > 62 || $this->_fastDecode) { - // insert the encode function - $this->buffer = $encode; - $unpack = preg_replace_callback('/\\{/', array(&$this, '_insertFastEncode'), $unpack, 1); - } else { - // perform the encoding inline - $unpack = preg_replace($ENCODE, $inline, $unpack); - } - // pack the boot function too - $unpackPacker = new JavaScriptPacker($unpack, 0, false, true); - $unpack = $unpackPacker->pack(); - - // arguments - $params = array($packed, $ascii, $count, $keywords); - if ($this->_fastDecode) { - $params[] = 0; - $params[] = '{}'; - } - $params = implode(',', $params); - - // the whole thing - return 'eval(' . $unpack . '(' . $params . "))\n"; - } - - private $buffer; - private function _insertFastDecode($match) { - return '{' . $this->buffer . ';'; - } - private function _insertFastEncode($match) { - return '{$encode=' . $this->buffer . ';'; - } - - // mmm.. ..which one do i need ?? - private function _getEncoder($ascii) { - return $ascii > 10 ? $ascii > 36 ? $ascii > 62 ? - '_encode95' : '_encode62' : '_encode36' : '_encode10'; - } - - // zero encoding - // characters: 0123456789 - private function _encode10($charCode) { - return $charCode; - } - - // inherent base36 support - // characters: 0123456789abcdefghijklmnopqrstuvwxyz - private function _encode36($charCode) { - return base_convert($charCode, 10, 36); - } - - // hitch a ride on base36 and add the upper case alpha characters - // characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ - private function _encode62($charCode) { - $res = ''; - if ($charCode >= $this->_encoding) { - $res = $this->_encode62((int)($charCode / $this->_encoding)); - } - $charCode = $charCode % $this->_encoding; - - if ($charCode > 35) - return $res . chr($charCode + 29); - else - return $res . base_convert($charCode, 10, 36); - } - - // use high-ascii values - // characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ - private function _encode95($charCode) { - $res = ''; - if ($charCode >= $this->_encoding) - $res = $this->_encode95($charCode / $this->_encoding); - - return $res . chr(($charCode % $this->_encoding) + 161); - } - - private function _safeRegExp($string) { - return '/'.preg_replace('/\$/', '\\\$', $string).'/'; - } - - private function _encodePrivate($charCode) { - return "_" . $charCode; - } - - // protect characters used by the parser - private function _escape($script) { - return preg_replace('/([\\\\\'])/', '\\\$1', $script); - } - - // protect high-ascii characters already in the script - private function _escape95($script) { - return preg_replace_callback( - '/[\\xa1-\\xff]/', - array(&$this, '_escape95Bis'), - $script - ); - } - private function _escape95Bis($match) { - return '\x'.((string)dechex(ord($match))); - } - - - private function _getJSFunction($aName) { - if (defined('self::JSFUNCTION'.$aName)) - return constant('self::JSFUNCTION'.$aName); - else - return ''; - } - - // JavaScript Functions used. - // Note : In Dean's version, these functions are converted - // with 'String(aFunctionName);'. - // This internal conversion complete the original code, ex : - // 'while (aBool) anAction();' is converted to - // 'while (aBool) { anAction(); }'. - // The JavaScript functions below are corrected. - - // unpacking function - this is the boot strap function - // data extracted from this packing routine is passed to - // this function when decoded in the target - // NOTE ! : without the ';' final. - const JSFUNCTION_unpack = +class JavaScriptPacker +{ + // constants + const IGNORE = '$1'; + + // validate parameters + private $_script = ''; + private $_encoding = 62; + private $_fastDecode = true; + private $_specialChars = false; + + private $LITERAL_ENCODING = array( + 'None' => 0, + 'Numeric' => 10, + 'Normal' => 62, + 'High ASCII' => 95 + ); + + public function __construct($_script, $_encoding = 62, $_fastDecode = true, $_specialChars = false) + { + $this->_script = $_script . "\n"; + if (array_key_exists($_encoding, $this->LITERAL_ENCODING)) + $_encoding = $this->LITERAL_ENCODING[$_encoding]; + $this->_encoding = min((int) $_encoding, 95); + $this->_fastDecode = $_fastDecode; + $this->_specialChars = $_specialChars; + } + + public function pack() + { + $this->_addParser('_basicCompression'); + if ($this->_specialChars) + $this->_addParser('_encodeSpecialChars'); + if ($this->_encoding) + $this->_addParser('_encodeKeywords'); + + // go! + return $this->_pack($this->_script); + } + + // apply all parsing routines + private function _pack($script) + { + for ($i = 0; isset($this->_parsers[$i]); $i++) { + $script = call_user_func(array(&$this,$this->_parsers[$i]), $script); + } + return $script; + } + + // keep a list of parsing functions, they'll be executed all at once + private $_parsers = array(); + private function _addParser($parser) + { + $this->_parsers[] = $parser; + } + + // zero encoding - just removal of white space and comments + private function _basicCompression($script) + { + $parser = new ParseMaster(); + // make safe + $parser->escapeChar = '\\'; + // protect strings + $parser->add('/\'[^\'\\n\\r]*\'/', self::IGNORE); + $parser->add('/"[^"\\n\\r]*"/', self::IGNORE); + // remove comments + $parser->add('/\\/\\/[^\\n\\r]*[\\n\\r]/', ' '); + $parser->add('/\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\//', ' '); + // protect regular expressions + $parser->add('/\\s+(\\/[^\\/\\n\\r\\*][^\\/\\n\\r]*\\/g?i?)/', '$2'); // IGNORE + $parser->add('/[^\\w\\x24\\/\'"*)\\?:]\\/[^\\/\\n\\r\\*][^\\/\\n\\r]*\\/g?i?/', self::IGNORE); + // remove: ;;; doSomething(); + if ($this->_specialChars) $parser->add('/;;;[^\\n\\r]+[\\n\\r]/'); + // remove redundant semi-colons + $parser->add('/\\(;;\\)/', self::IGNORE); // protect for (;;) loops + $parser->add('/;+\\s*([};])/', '$2'); + // apply the above + $script = $parser->exec($script); + + // remove white-space + $parser->add('/(\\b|\\x24)\\s+(\\b|\\x24)/', '$2 $3'); + $parser->add('/([+\\-])\\s+([+\\-])/', '$2 $3'); + $parser->add('/\\s+/', ''); + // done + return $parser->exec($script); + } + + private function _encodeSpecialChars($script) + { + $parser = new ParseMaster(); + // replace: $name -> n, $$name -> na + $parser->add('/((\\x24+)([a-zA-Z$_]+))(\\d*)/', + array('fn' => '_replace_name') + ); + // replace: _name -> _0, double-underscore (__name) is ignored + $regexp = '/\\b_[A-Za-z\\d]\\w*/'; + // build the word list + $keywords = $this->_analyze($script, $regexp, '_encodePrivate'); + // quick ref + $encoded = $keywords['encoded']; + + $parser->add($regexp, + array( + 'fn' => '_replace_encoded', + 'data' => $encoded + ) + ); + return $parser->exec($script); + } + + private function _encodeKeywords($script) + { + // escape high-ascii values already in the script (i.e. in strings) + if ($this->_encoding > 62) + $script = $this->_escape95($script); + // create the parser + $parser = new ParseMaster(); + $encode = $this->_getEncoder($this->_encoding); + // for high-ascii, don't encode single character low-ascii + $regexp = ($this->_encoding > 62) ? '/\\w\\w+/' : '/\\w+/'; + // build the word list + $keywords = $this->_analyze($script, $regexp, $encode); + $encoded = $keywords['encoded']; + + // encode + $parser->add($regexp, + array( + 'fn' => '_replace_encoded', + 'data' => $encoded + ) + ); + if (empty($script)) return $script; + else { + //$res = $parser->exec($script); + //$res = $this->_bootStrap($res, $keywords); + //return $res; + return $this->_bootStrap($parser->exec($script), $keywords); + } + } + + private function _analyze($script, $regexp, $encode) + { + // analyse + // retreive all words in the script + $all = array(); + preg_match_all($regexp, $script, $all); + $_sorted = array(); // list of words sorted by frequency + $_encoded = array(); // dictionary of word->encoding + $_protected = array(); // instances of "protected" words + $all = $all[0]; // simulate the javascript comportement of global match + if (!empty($all)) { + $unsorted = array(); // same list, not sorted + $protected = array(); // "protected" words (dictionary of word->"word") + $value = array(); // dictionary of charCode->encoding (eg. 256->ff) + $this->_count = array(); // word->count + $i = count($all); $j = 0; //$word = null; + // count the occurrences - used for sorting later + do { + --$i; + $word = '$' . $all[$i]; + if (!isset($this->_count[$word])) { + $this->_count[$word] = 0; + $unsorted[$j] = $word; + // make a dictionary of all of the protected words in this script + // these are words that might be mistaken for encoding + //if (is_string($encode) && method_exists($this, $encode)) + $values[$j] = call_user_func(array(&$this, $encode), $j); + $protected['$' . $values[$j]] = $j++; + } + // increment the word counter + $this->_count[$word]++; + } while ($i > 0); + // prepare to sort the word list, first we must protect + // words that are also used as codes. we assign them a code + // equivalent to the word itself. + // e.g. if "do" falls within our encoding range + // then we store keywords["do"] = "do"; + // this avoids problems when decoding + $i = count($unsorted); + do { + $word = $unsorted[--$i]; + if (isset($protected[$word]) /*!= null*/) { + $_sorted[$protected[$word]] = substr($word, 1); + $_protected[$protected[$word]] = true; + $this->_count[$word] = 0; + } + } while ($i); + + // sort the words by frequency + // Note: the javascript and php version of sort can be different : + // in php manual, usort : + // " If two members compare as equal, + // their order in the sorted array is undefined." + // so the final packed script is different of the Dean's javascript version + // but equivalent. + // the ECMAscript standard does not guarantee this behaviour, + // and thus not all browsers (e.g. Mozilla versions dating back to at + // least 2003) respect this. + usort($unsorted, array(&$this, '_sortWords')); + $j = 0; + // because there are "protected" words in the list + // we must add the sorted words around them + do { + if (!isset($_sorted[$i])) + $_sorted[$i] = substr($unsorted[$j++], 1); + $_encoded[$_sorted[$i]] = $values[$i]; + } while (++$i < count($unsorted)); + } + return array( + 'sorted' => $_sorted, + 'encoded' => $_encoded, + 'protected' => $_protected); + } + + private $_count = array(); + private function _sortWords($match1, $match2) + { + return $this->_count[$match2] - $this->_count[$match1]; + } + + // build the boot function used for loading and decoding + private function _bootStrap($packed, $keywords) + { + $ENCODE = $this->_safeRegExp('$encode\\($count\\)'); + + // $packed: the packed script + $packed = "'" . $this->_escape($packed) . "'"; + + // $ascii: base for encoding + $ascii = min(count($keywords['sorted']), $this->_encoding); + if ($ascii == 0) $ascii = 1; + + // $count: number of words contained in the script + $count = count($keywords['sorted']); + + // $keywords: list of words contained in the script + foreach ($keywords['protected'] as $i=>$value) { + $keywords['sorted'][$i] = ''; + } + // convert from a string to an array + ksort($keywords['sorted']); + $keywords = "'" . implode('|',$keywords['sorted']) . "'.split('|')"; + + $encode = ($this->_encoding > 62) ? '_encode95' : $this->_getEncoder($ascii); + $encode = $this->_getJSFunction($encode); + $encode = preg_replace('/_encoding/','$ascii', $encode); + $encode = preg_replace('/arguments\\.callee/','$encode', $encode); + $inline = '\\$count' . ($ascii > 10 ? '.toString(\\$ascii)' : ''); + + // $decode: code snippet to speed up decoding + if ($this->_fastDecode) { + // create the decoder + $decode = $this->_getJSFunction('_decodeBody'); + if ($this->_encoding > 62) + $decode = preg_replace('/\\\\w/', '[\\xa1-\\xff]', $decode); + // perform the encoding inline for lower ascii values + elseif ($ascii < 36) + $decode = preg_replace($ENCODE, $inline, $decode); + // special case: when $count==0 there are no keywords. I want to keep + // the basic shape of the unpacking funcion so i'll frig the code... + if ($count == 0) + $decode = preg_replace($this->_safeRegExp('($count)\\s*=\\s*1'), '$1=0', $decode, 1); + } + + // boot function + $unpack = $this->_getJSFunction('_unpack'); + if ($this->_fastDecode) { + // insert the decoder + $this->buffer = $decode; + $unpack = preg_replace_callback('/\\{/', array(&$this, '_insertFastDecode'), $unpack, 1); + } + $unpack = preg_replace('/"/', "'", $unpack); + if ($this->_encoding > 62) { // high-ascii + // get rid of the word-boundaries for regexp matches + $unpack = preg_replace('/\'\\\\\\\\b\'\s*\\+|\\+\s*\'\\\\\\\\b\'/', '', $unpack); + } + if ($ascii > 36 || $this->_encoding > 62 || $this->_fastDecode) { + // insert the encode function + $this->buffer = $encode; + $unpack = preg_replace_callback('/\\{/', array(&$this, '_insertFastEncode'), $unpack, 1); + } else { + // perform the encoding inline + $unpack = preg_replace($ENCODE, $inline, $unpack); + } + // pack the boot function too + $unpackPacker = new JavaScriptPacker($unpack, 0, false, true); + $unpack = $unpackPacker->pack(); + + // arguments + $params = array($packed, $ascii, $count, $keywords); + if ($this->_fastDecode) { + $params[] = 0; + $params[] = '{}'; + } + $params = implode(',', $params); + + // the whole thing + return 'eval(' . $unpack . '(' . $params . "))\n"; + } + + private $buffer; + private function _insertFastDecode($match) + { + return '{' . $this->buffer . ';'; + } + private function _insertFastEncode($match) + { + return '{$encode=' . $this->buffer . ';'; + } + + // mmm.. ..which one do i need ?? + private function _getEncoder($ascii) + { + return $ascii > 10 ? $ascii > 36 ? $ascii > 62 ? + '_encode95' : '_encode62' : '_encode36' : '_encode10'; + } + + // zero encoding + // characters: 0123456789 + private function _encode10($charCode) + { + return $charCode; + } + + // inherent base36 support + // characters: 0123456789abcdefghijklmnopqrstuvwxyz + private function _encode36($charCode) + { + return base_convert($charCode, 10, 36); + } + + // hitch a ride on base36 and add the upper case alpha characters + // characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + private function _encode62($charCode) + { + $res = ''; + if ($charCode >= $this->_encoding) { + $res = $this->_encode62((int) ($charCode / $this->_encoding)); + } + $charCode = $charCode % $this->_encoding; + + if ($charCode > 35) + return $res . chr($charCode + 29); + else + return $res . base_convert($charCode, 10, 36); + } + + // use high-ascii values + // characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ + private function _encode95($charCode) + { + $res = ''; + if ($charCode >= $this->_encoding) + $res = $this->_encode95($charCode / $this->_encoding); + + return $res . chr(($charCode % $this->_encoding) + 161); + } + + private function _safeRegExp($string) + { + return '/'.preg_replace('/\$/', '\\\$', $string).'/'; + } + + private function _encodePrivate($charCode) + { + return "_" . $charCode; + } + + // protect characters used by the parser + private function _escape($script) + { + return preg_replace('/([\\\\\'])/', '\\\$1', $script); + } + + // protect high-ascii characters already in the script + private function _escape95($script) + { + return preg_replace_callback( + '/[\\xa1-\\xff]/', + array(&$this, '_escape95Bis'), + $script + ); + } + private function _escape95Bis($match) + { + return '\x'.((string) dechex(ord($match))); + } + + + private function _getJSFunction($aName) + { + if (defined('self::JSFUNCTION'.$aName)) + return constant('self::JSFUNCTION'.$aName); + else + return ''; + } + + // JavaScript Functions used. + // Note : In Dean's version, these functions are converted + // with 'String(aFunctionName);'. + // This internal conversion complete the original code, ex : + // 'while (aBool) anAction();' is converted to + // 'while (aBool) { anAction(); }'. + // The JavaScript functions below are corrected. + + // unpacking function - this is the boot strap function + // data extracted from this packing routine is passed to + // this function when decoded in the target + // NOTE ! : without the ';' final. + const JSFUNCTION_unpack = 'function($packed, $ascii, $count, $keywords, $encode, $decode) { while ($count--) { @@ -470,9 +493,9 @@ private function _getJSFunction($aName) { return $packed; }'; */ - - // code-snippet inserted into the unpacker to speed up decoding - const JSFUNCTION_decodeBody = + + // code-snippet inserted into the unpacker to speed up decoding + const JSFUNCTION_decodeBody = //_decode = function() { // does the browser support String.replace where the // replacement value is a function? @@ -503,239 +526,252 @@ private function _getJSFunction($aName) { $count = 1; }'; */ - - // zero encoding - // characters: 0123456789 - const JSFUNCTION_encode10 = + + // zero encoding + // characters: 0123456789 + const JSFUNCTION_encode10 = 'function($charCode) { return $charCode; }';//;'; - - // inherent base36 support - // characters: 0123456789abcdefghijklmnopqrstuvwxyz - const JSFUNCTION_encode36 = + + // inherent base36 support + // characters: 0123456789abcdefghijklmnopqrstuvwxyz + const JSFUNCTION_encode36 = 'function($charCode) { return $charCode.toString(36); }';//;'; - - // hitch a ride on base36 and add the upper case alpha characters - // characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ - const JSFUNCTION_encode62 = + + // hitch a ride on base36 and add the upper case alpha characters + // characters: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + const JSFUNCTION_encode62 = 'function($charCode) { return ($charCode < _encoding ? \'\' : arguments.callee(parseInt($charCode / _encoding))) + (($charCode = $charCode % _encoding) > 35 ? String.fromCharCode($charCode + 29) : $charCode.toString(36)); }'; - - // use high-ascii values - // characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ - const JSFUNCTION_encode95 = + + // use high-ascii values + // characters: ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ + const JSFUNCTION_encode95 = 'function($charCode) { return ($charCode < _encoding ? \'\' : arguments.callee($charCode / _encoding)) + String.fromCharCode($charCode % _encoding + 161); -}'; - +}'; + } -class ParseMaster { - public $ignoreCase = false; - public $escapeChar = ''; - - // constants - const EXPRESSION = 0; - const REPLACEMENT = 1; - const LENGTH = 2; - - // used to determine nesting levels - private $GROUPS = '/\\(/';//g - private $SUB_REPLACE = '/\\$\\d/'; - private $INDEXED = '/^\\$\\d+$/'; - private $TRIM = '/([\'"])\\1\\.(.*)\\.\\1\\1$/'; - private $ESCAPE = '/\\\./';//g - private $QUOTE = '/\'/'; - private $DELETED = '/\\x01[^\\x01]*\\x01/';//g - - public function add($expression, $replacement = '') { - // count the number of sub-expressions - // - add one because each pattern is itself a sub-expression - $length = 1 + preg_match_all($this->GROUPS, $this->_internalEscape((string)$expression), $out); - - // treat only strings $replacement - if (is_string($replacement)) { - // does the pattern deal with sub-expressions? - if (preg_match($this->SUB_REPLACE, $replacement)) { - // a simple lookup? (e.g. "$2") - if (preg_match($this->INDEXED, $replacement)) { - // store the index (used for fast retrieval of matched strings) - $replacement = (int)(substr($replacement, 1)) - 1; - } else { // a complicated lookup (e.g. "Hello $2 $1") - // build a function to do the lookup - $quote = preg_match($this->QUOTE, $this->_internalEscape($replacement)) - ? '"' : "'"; - $replacement = array( - 'fn' => '_backReferences', - 'data' => array( - 'replacement' => $replacement, - 'length' => $length, - 'quote' => $quote - ) - ); - } - } - } - // pass the modified arguments - if (!empty($expression)) $this->_add($expression, $replacement, $length); - else $this->_add('/^$/', $replacement, $length); - } - - public function exec($string) { - // execute the global replacement - $this->_escaped = array(); - - // simulate the _patterns.toSTring of Dean - $regexp = '/'; - foreach ($this->_patterns as $reg) { - $regexp .= '(' . substr($reg[self::EXPRESSION], 1, -1) . ')|'; - } - $regexp = substr($regexp, 0, -1) . '/'; - $regexp .= ($this->ignoreCase) ? 'i' : ''; - - $string = $this->_escape($string, $this->escapeChar); - $string = preg_replace_callback( - $regexp, - array( - &$this, - '_replacement' - ), - $string - ); - $string = $this->_unescape($string, $this->escapeChar); - - return preg_replace($this->DELETED, '', $string); - } - - public function reset() { - // clear the patterns collection so that this object may be re-used - $this->_patterns = array(); - } - - // private - private $_escaped = array(); // escaped characters - private $_patterns = array(); // patterns stored by index - - // create and add a new pattern to the patterns collection - private function _add() { - $arguments = func_get_args(); - $this->_patterns[] = $arguments; - } - - // this is the global replace function (it's quite complicated) - private function _replacement($arguments) { - if (empty($arguments)) return ''; - - $i = 1; $j = 0; - // loop through the patterns - while (isset($this->_patterns[$j])) { - $pattern = $this->_patterns[$j++]; - // do we have a result? - if (isset($arguments[$i]) && ($arguments[$i] != '')) { - $replacement = $pattern[self::REPLACEMENT]; - - if (is_array($replacement) && isset($replacement['fn'])) { - - if (isset($replacement['data'])) $this->buffer = $replacement['data']; - return call_user_func(array(&$this, $replacement['fn']), $arguments, $i); - - } elseif (is_int($replacement)) { - return $arguments[$replacement + $i]; - - } - $delete = ($this->escapeChar == '' || - strpos($arguments[$i], $this->escapeChar) === false) - ? '' : "\x01" . $arguments[$i] . "\x01"; - return $delete . $replacement; - - // skip over references to sub-expressions - } else { - $i += $pattern[self::LENGTH]; - } - } - } - - private function _backReferences($match, $offset) { - $replacement = $this->buffer['replacement']; - $quote = $this->buffer['quote']; - $i = $this->buffer['length']; - while ($i) { - $replacement = str_replace('$'.$i--, $match[$offset + $i], $replacement); - } - return $replacement; - } - - private function _replace_name($match, $offset){ - $length = strlen($match[$offset + 2]); - $start = $length - max($length - strlen($match[$offset + 3]), 0); - return substr($match[$offset + 1], $start, $length) . $match[$offset + 4]; - } - - private function _replace_encoded($match, $offset) { - return $this->buffer[$match[$offset]]; - } - - - // php : we cannot pass additional data to preg_replace_callback, - // and we cannot use &$this in create_function, so let's go to lower level - private $buffer; - - // encode escaped characters - private function _escape($string, $escapeChar) { - if ($escapeChar) { - $this->buffer = $escapeChar; - return preg_replace_callback( - '/\\' . $escapeChar . '(.)' .'/', - array(&$this, '_escapeBis'), - $string - ); - - } else { - return $string; - } - } - private function _escapeBis($match) { - $this->_escaped[] = $match[1]; - return $this->buffer; - } - - // decode escaped characters - private function _unescape($string, $escapeChar) { - if ($escapeChar) { - $regexp = '/'.'\\'.$escapeChar.'/'; - $this->buffer = array('escapeChar'=> $escapeChar, 'i' => 0); - return preg_replace_callback - ( - $regexp, - array(&$this, '_unescapeBis'), - $string - ); - - } else { - return $string; - } - } - private function _unescapeBis() { - if (isset($this->_escaped[$this->buffer['i']]) - && $this->_escaped[$this->buffer['i']] != '') - { - $temp = $this->_escaped[$this->buffer['i']]; - } else { - $temp = ''; - } - $this->buffer['i']++; - return $this->buffer['escapeChar'] . $temp; - } - - private function _internalEscape($string) { - return preg_replace($this->ESCAPE, '', $string); - } +class ParseMaster +{ + public $ignoreCase = false; + public $escapeChar = ''; + + // constants + const EXPRESSION = 0; + const REPLACEMENT = 1; + const LENGTH = 2; + + // used to determine nesting levels + private $GROUPS = '/\\(/';//g + private $SUB_REPLACE = '/\\$\\d/'; + private $INDEXED = '/^\\$\\d+$/'; + private $TRIM = '/([\'"])\\1\\.(.*)\\.\\1\\1$/'; + private $ESCAPE = '/\\\./';//g + private $QUOTE = '/\'/'; + private $DELETED = '/\\x01[^\\x01]*\\x01/';//g + + public function add($expression, $replacement = '') + { + // count the number of sub-expressions + // - add one because each pattern is itself a sub-expression + $length = 1 + preg_match_all($this->GROUPS, $this->_internalEscape((string) $expression), $out); + + // treat only strings $replacement + if (is_string($replacement)) { + // does the pattern deal with sub-expressions? + if (preg_match($this->SUB_REPLACE, $replacement)) { + // a simple lookup? (e.g. "$2") + if (preg_match($this->INDEXED, $replacement)) { + // store the index (used for fast retrieval of matched strings) + $replacement = (int) (substr($replacement, 1)) - 1; + } else { // a complicated lookup (e.g. "Hello $2 $1") + // build a function to do the lookup + $quote = preg_match($this->QUOTE, $this->_internalEscape($replacement)) + ? '"' : "'"; + $replacement = array( + 'fn' => '_backReferences', + 'data' => array( + 'replacement' => $replacement, + 'length' => $length, + 'quote' => $quote + ) + ); + } + } + } + // pass the modified arguments + if (!empty($expression)) $this->_add($expression, $replacement, $length); + else $this->_add('/^$/', $replacement, $length); + } + + public function exec($string) + { + // execute the global replacement + $this->_escaped = array(); + + // simulate the _patterns.toSTring of Dean + $regexp = '/'; + foreach ($this->_patterns as $reg) { + $regexp .= '(' . substr($reg[self::EXPRESSION], 1, -1) . ')|'; + } + $regexp = substr($regexp, 0, -1) . '/'; + $regexp .= ($this->ignoreCase) ? 'i' : ''; + + $string = $this->_escape($string, $this->escapeChar); + $string = preg_replace_callback( + $regexp, + array( + &$this, + '_replacement' + ), + $string + ); + $string = $this->_unescape($string, $this->escapeChar); + + return preg_replace($this->DELETED, '', $string); + } + + public function reset() + { + // clear the patterns collection so that this object may be re-used + $this->_patterns = array(); + } + + // private + private $_escaped = array(); // escaped characters + private $_patterns = array(); // patterns stored by index + + // create and add a new pattern to the patterns collection + private function _add() + { + $arguments = func_get_args(); + $this->_patterns[] = $arguments; + } + + // this is the global replace function (it's quite complicated) + private function _replacement($arguments) + { + if (empty($arguments)) return ''; + + $i = 1; $j = 0; + // loop through the patterns + while (isset($this->_patterns[$j])) { + $pattern = $this->_patterns[$j++]; + // do we have a result? + if (isset($arguments[$i]) && ($arguments[$i] != '')) { + $replacement = $pattern[self::REPLACEMENT]; + + if (is_array($replacement) && isset($replacement['fn'])) { + + if (isset($replacement['data'])) $this->buffer = $replacement['data']; + return call_user_func(array(&$this, $replacement['fn']), $arguments, $i); + + } elseif (is_int($replacement)) { + return $arguments[$replacement + $i]; + + } + $delete = ($this->escapeChar == '' || + strpos($arguments[$i], $this->escapeChar) === false) + ? '' : "\x01" . $arguments[$i] . "\x01"; + return $delete . $replacement; + + // skip over references to sub-expressions + } else { + $i += $pattern[self::LENGTH]; + } + } + } + + private function _backReferences($match, $offset) + { + $replacement = $this->buffer['replacement']; + $quote = $this->buffer['quote']; + $i = $this->buffer['length']; + while ($i) { + $replacement = str_replace('$'.$i--, $match[$offset + $i], $replacement); + } + return $replacement; + } + + private function _replace_name($match, $offset) + { + $length = strlen($match[$offset + 2]); + $start = $length - max($length - strlen($match[$offset + 3]), 0); + return substr($match[$offset + 1], $start, $length) . $match[$offset + 4]; + } + + private function _replace_encoded($match, $offset) + { + return $this->buffer[$match[$offset]]; + } + + + // php : we cannot pass additional data to preg_replace_callback, + // and we cannot use &$this in create_function, so let's go to lower level + private $buffer; + + // encode escaped characters + private function _escape($string, $escapeChar) + { + if ($escapeChar) { + $this->buffer = $escapeChar; + return preg_replace_callback( + '/\\' . $escapeChar . '(.)' .'/', + array(&$this, '_escapeBis'), + $string + ); + + } else { + return $string; + } + } + private function _escapeBis($match) + { + $this->_escaped[] = $match[1]; + return $this->buffer; + } + + // decode escaped characters + private function _unescape($string, $escapeChar) + { + if ($escapeChar) { + $regexp = '/'.'\\'.$escapeChar.'/'; + $this->buffer = array('escapeChar'=> $escapeChar, 'i' => 0); + return preg_replace_callback + ( + $regexp, + array(&$this, '_unescapeBis'), + $string + ); + + } else { + return $string; + } + } + private function _unescapeBis() + { + if (isset($this->_escaped[$this->buffer['i']]) + && $this->_escaped[$this->buffer['i']] != '') + { + $temp = $this->_escaped[$this->buffer['i']]; + } else { + $temp = ''; + } + $this->buffer['i']++; + return $this->buffer['escapeChar'] . $temp; + } + + private function _internalEscape($string) + { + return preg_replace($this->ESCAPE, '', $string); + } } -?> diff --git a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_AuthBackendBasic.php b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_AuthBackendBasic.php index 382dfb8db9..4363d4d619 100644 --- a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_AuthBackendBasic.php +++ b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_AuthBackendBasic.php @@ -21,8 +21,8 @@ defined('AJXP_EXEC') or die( 'Access not allowed'); -class AJXP_Sabre_AuthBackendBasic extends Sabre\DAV\Auth\Backend\AbstractBasic{ - +class AJXP_Sabre_AuthBackendBasic extends Sabre\DAV\Auth\Backend\AbstractBasic +{ protected $currentUser; private $repositoryId; @@ -30,7 +30,8 @@ class AJXP_Sabre_AuthBackendBasic extends Sabre\DAV\Auth\Backend\AbstractBasic{ * Utilitary method to detect basic header. * @return bool */ - public static function detectBasicHeader(){ + public static function detectBasicHeader() + { if(isSet($_SERVER["PHP_AUTH_USER"])) return true; if(isSet($_SERVER["HTTP_AUTHORIZATION"])) $value = $_SERVER["HTTP_AUTHORIZATION"]; if(!isSet($value) && isSet($_SERVER["REDIRECT_HTTP_AUTHORIZATION"])) $value = $_SERVER["HTTP_AUTHORIZATION"]; @@ -38,17 +39,20 @@ public static function detectBasicHeader(){ return (strpos(strtolower($value),'basic') ===0) ; } - function __construct($repositoryId){ + public function __construct($repositoryId) + { $this->repositoryId = $repositoryId; } - protected function validateUserPass($username, $password) { - // Warning, this can only work if TRANSMIT_CLEAR_PASS is true; + protected function validateUserPass($username, $password) + { + // Warning, this can only work if TRANSMIT_CLEAR_PASS is true; return AuthService::checkPassword($username, $password, false, -1); - } + } - public function authenticate(Sabre\DAV\Server $server, $realm){ + public function authenticate(Sabre\DAV\Server $server, $realm) + { $auth = new Sabre\HTTP\BasicAuth(); $auth->setHTTPRequest($server->httpRequest); $auth->setHTTPResponse($server->httpResponse); @@ -60,14 +64,14 @@ public function authenticate(Sabre\DAV\Server $server, $realm){ } // Authenticates the user - //AJXP_Logger::logAction("authenticate: " . $userpass[0]); - - $confDriver = ConfService::getConfStorageImpl(); - $userObject = $confDriver->createUserObject($userpass[0]); - $webdavData = $userObject->getPref("AJXP_WEBDAV_DATA"); - if (empty($webdavData) || !isset($webdavData["ACTIVE"]) || $webdavData["ACTIVE"] !== true) { - return false; - } + //AJXP_Logger::logAction("authenticate: " . $userpass[0]); + + $confDriver = ConfService::getConfStorageImpl(); + $userObject = $confDriver->createUserObject($userpass[0]); + $webdavData = $userObject->getPref("AJXP_WEBDAV_DATA"); + if (empty($webdavData) || !isset($webdavData["ACTIVE"]) || $webdavData["ACTIVE"] !== true) { + return false; + } // check if there are cached credentials. prevents excessive authentication calls to external // auth mechanism. $cachedPasswordValid = 0; @@ -85,19 +89,19 @@ public function authenticate(Sabre\DAV\Server $server, $realm){ } $this->currentUser = $userpass[0]; - AuthService::logUser($this->currentUser, $userpass[1], true); - $res = $this->updateCurrentUserRights(AuthService::getLoggedUser()); - if($res === false){ - return false; - } + AuthService::logUser($this->currentUser, $userpass[1], true); + $res = $this->updateCurrentUserRights(AuthService::getLoggedUser()); + if ($res === false) { + return false; + } - // the method used here will invalidate the cached password every minute on the minute - if (!$cachedPasswordValid) { - $webdavData["TMP_PASS"] = $encryptedPass; - $userObject->setPref("AJXP_WEBDAV_DATA", $webdavData); - $userObject->save("user"); - AuthService::updateUser($userObject); - } + // the method used here will invalidate the cached password every minute on the minute + if (!$cachedPasswordValid) { + $webdavData["TMP_PASS"] = $encryptedPass; + $userObject->setPref("AJXP_WEBDAV_DATA", $webdavData); + $userObject->save("user"); + AuthService::updateUser($userObject); + } return true; } @@ -107,12 +111,13 @@ public function authenticate(Sabre\DAV\Server $server, $realm){ * @param AbstractAjxpUser $user * @return bool */ - protected function updateCurrentUserRights($user){ - if(!$user->canSwitchTo($this->repositoryId)){ + protected function updateCurrentUserRights($user) + { + if (!$user->canSwitchTo($this->repositoryId)) { return false; } return true; } -} \ No newline at end of file +} diff --git a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_AuthBackendDigest.php b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_AuthBackendDigest.php index 4242249440..f09a76b20e 100644 --- a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_AuthBackendDigest.php +++ b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_AuthBackendDigest.php @@ -24,56 +24,59 @@ * @package AjaXplorer * @subpackage SabreDav */ -class AJXP_Sabre_AuthBackendDigest extends Sabre\DAV\Auth\Backend\AbstractDigest{ - +class AJXP_Sabre_AuthBackendDigest extends Sabre\DAV\Auth\Backend\AbstractDigest +{ protected $currentUser; - private $secretKey; + private $secretKey; private $repositoryId; - function __construct($repositoryId){ + public function __construct($repositoryId) + { $this->repositoryId = $repositoryId; - if(defined('AJXP_SAFE_SECRET_KEY')){ + if (defined('AJXP_SAFE_SECRET_KEY')) { $this->secretKey = AJXP_SAFE_SECRET_KEY; - }else{ + } else { $this->secretKey = "\1CDAFx¨op#"; } } - public function getDigestHash($realm, $username){ - if(!AuthService::userExists($username)){ + public function getDigestHash($realm, $username) + { + if (!AuthService::userExists($username)) { return false; } $confDriver = ConfService::getConfStorageImpl(); $user = $confDriver->createUserObject($username); $webdavData = $user->getPref("AJXP_WEBDAV_DATA"); - if(empty($webdavData) || !isset($webdavData["ACTIVE"]) || $webdavData["ACTIVE"] !== true || (!isSet($webdavData["PASS"]) && !isset($webdavData["HA1"]) ) ){ + if (empty($webdavData) || !isset($webdavData["ACTIVE"]) || $webdavData["ACTIVE"] !== true || (!isSet($webdavData["PASS"]) && !isset($webdavData["HA1"]) ) ) { return false; } - if(isSet($webdavData["HA1"])){ + if (isSet($webdavData["HA1"])) { return $webdavData["HA1"]; - }else{ + } else { $pass = $this->_decodePassword($webdavData["PASS"], $username); return md5("{$username}:{$realm}:{$pass}"); } } - public function authenticate(Sabre\DAV\Server $server, $realm){ + public function authenticate(Sabre\DAV\Server $server, $realm) + { //AJXP_Logger::debug("Try authentication on $realm", $server); $success = parent::authenticate($server, $realm); - if($success){ + if ($success) { $res = AuthService::logUser($this->currentUser, null, true); - if($res < 1){ + if ($res < 1) { throw new Sabre\DAV\Exception\NotAuthenticated(); } $this->updateCurrentUserRights(AuthService::getLoggedUser()); - if(ConfService::getCoreConf("SESSION_SET_CREDENTIALS", "auth")){ + if (ConfService::getCoreConf("SESSION_SET_CREDENTIALS", "auth")) { $webdavData = AuthService::getLoggedUser()->getPref("AJXP_WEBDAV_DATA"); AJXP_Safe::storeCredentials($this->currentUser, $this->_decodePassword($webdavData["PASS"], $this->currentUser)); } } - if($success === false){ + if ($success === false) { throw new Sabre\DAV\Exception\NotAuthenticated(); } ConfService::loadRepositoryDriver(); @@ -81,18 +84,19 @@ public function authenticate(Sabre\DAV\Server $server, $realm){ } - protected function updateCurrentUserRights($user){ - if($this->repositoryId == null) { + protected function updateCurrentUserRights($user) + { + if ($this->repositoryId == null) { return true; } - if(!$user->canSwitchTo($this->repositoryId)){ + if (!$user->canSwitchTo($this->repositoryId)) { throw new Sabre\DAV\Exception\NotAuthenticated(); } } - private function _decodePassword($encoded, $user){ - if (function_exists('mcrypt_decrypt')) - { + private function _decodePassword($encoded, $user) + { + if (function_exists('mcrypt_decrypt')) { $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); $encoded = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($user.$this->secretKey), base64_decode($encoded), MCRYPT_MODE_ECB, $iv), "\0"); } diff --git a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_BrowserPlugin.php b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_BrowserPlugin.php index b0997a0153..589352c87c 100755 --- a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_BrowserPlugin.php +++ b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_BrowserPlugin.php @@ -29,13 +29,14 @@ class AJXP_Sabre_BrowserPlugin extends Sabre\DAV\Browser\Plugin protected $repositoryLabel; - function __construct($currentRepositoryLabel = null){ + public function __construct($currentRepositoryLabel = null) + { parent::__construct(false, true); $this->repositoryLabel = $currentRepositoryLabel; } - function generateDirectoryIndex($path){ - + public function generateDirectoryIndex($path) + { $html = parent::generateDirectoryIndex($path); $html = str_replace("image/vnd.microsoft.icon", "image/png", $html); @@ -43,7 +44,7 @@ function generateDirectoryIndex($path){ $html = preg_replace("/(.*)<\/title>/i", '<title>'.$title.'', $html); $repoString = ""; - if(!empty($this->repositoryLabel)){ + if (!empty($this->repositoryLabel)) { $repoString = " - ".$this->repositoryLabel."

    Index of ".$this->escapeHTML($path)."/

    "; } $html = preg_replace("/

    (.*)<\/h1>/i", "

    ".$title.$repoString, $html); @@ -54,8 +55,9 @@ function generateDirectoryIndex($path){ } - function getLocalAssetPath($name){ - if($name != "favicon.ico") { + public function getLocalAssetPath($name) + { + if ($name != "favicon.ico") { return parent::getLocalAssetPath($name); } return AJXP_INSTALL_PATH."/plugins/gui.ajax/res/themes/umbra/images/html-folder.png"; diff --git a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_Collection.php b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_Collection.php index cd86a94d9d..ff731f10c1 100755 --- a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_Collection.php +++ b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_Collection.php @@ -53,9 +53,9 @@ class AJXP_Sabre_Collection extends AJXP_Sabre_Node implements Sabre\DAV\ICollec * @param resource|string $data Initial payload * @return null|string */ - function createFile($name, $data = null){ - - try{ + public function createFile($name, $data = null) + { + try { $name = ltrim($name, "/"); AJXP_Logger::debug("CREATE FILE $name"); @@ -64,16 +64,16 @@ function createFile($name, $data = null){ "filename" => $name ), array()); - if( $data != null && is_file($this->getUrl()."/".$name)){ + if ( $data != null && is_file($this->getUrl()."/".$name)) { $p = $this->path."/".$name; $this->getAccessDriver()->nodeWillChange($p, intval($_SERVER["CONTENT_LENGTH"])); //AJXP_Logger::debug("Should now copy stream or string in ".$this->getUrl()."/".$name); - if(is_resource($data)){ + if (is_resource($data)) { $stream = fopen($this->getUrl()."/".$name, "w"); stream_copy_to_stream($data, $stream); fclose($stream); - }else if(is_string($data)){ + } else if (is_string($data)) { file_put_contents($data, $this->getUrl()."/".$name); } @@ -82,12 +82,12 @@ function createFile($name, $data = null){ } $node = new AJXP_Sabre_NodeLeaf($this->path."/".$name, $this->repository, $this->getAccessDriver()); - if(isSet($this->children)){ + if (isSet($this->children)) { $this->children = null; } return $node->getETag(); - }catch (Exception $e){ + } catch (Exception $e) { AJXP_Logger::debug("Error ".$e->getMessage(), $e->getTraceAsString()); return null; } @@ -101,9 +101,9 @@ function createFile($name, $data = null){ * @param string $name * @return void */ - function createDirectory($name){ - - if(isSet($this->children)){ + public function createDirectory($name) + { + if (isSet($this->children)) { $this->children = null; } @@ -121,9 +121,9 @@ function createDirectory($name){ * @throws Sabre\DAV\Exception\NotFound * @return Sabre\DAV\INode */ - function getChild($name){ - - foreach($this->getChildren() as $child) { + public function getChild($name) + { + foreach ($this->getChildren() as $child) { if ($child->getName()==$name) return $child; @@ -137,9 +137,9 @@ function getChild($name){ * * @return Sabre\DAV\INode[] */ - function getChildren(){ - - if(isSet($this->children)) { + public function getChildren() + { + if (isSet($this->children)) { return $this->children; } @@ -149,21 +149,17 @@ function getChildren(){ $nodes = scandir($this->getUrl()); - foreach ( $nodes as $file ) - { - if($file == "." || $file == "..") { + foreach ($nodes as $file) { + if ($file == "." || $file == "..") { continue; } - if ( !$this->repository->getOption("SHOW_HIDDEN_FILES") && AJXP_Utils::isHidden($file)){ + if ( !$this->repository->getOption("SHOW_HIDDEN_FILES") && AJXP_Utils::isHidden($file)) { continue; } - if ( is_dir( $this->getUrl() . "/" . $file ) ) - { + if ( is_dir( $this->getUrl() . "/" . $file ) ) { // Add collection without any children $contents[] = new AJXP_Sabre_Collection($this->path."/".$file, $this->repository, $this->getAccessDriver()); - } - else - { + } else { // Add files without content $contents[] = new AJXP_Sabre_NodeLeaf($this->path."/".$file, $this->repository, $this->getAccessDriver()); } @@ -183,9 +179,9 @@ function getChildren(){ * @param string $name * @return bool */ - function childExists($name){ - - foreach($this->getChildren() as $child) { + public function childExists($name) + { + foreach ($this->getChildren() as $child) { if ($child->getName()==$name) return true; diff --git a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_Node.php b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_Node.php index d625c081b2..1151ad590f 100755 --- a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_Node.php +++ b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_Node.php @@ -42,10 +42,11 @@ class AJXP_Sabre_Node implements Sabre\DAV\INode, Sabre\DAV\IProperties protected $url; protected $path; - function __construct($path, $repository, $accessDriver = null){ + public function __construct($path, $repository, $accessDriver = null) + { $this->repository = $repository; $this->path = $path; - if($accessDriver != null){ + if ($accessDriver != null) { $this->accessDriver = $accessDriver; } } @@ -54,13 +55,14 @@ function __construct($path, $repository, $accessDriver = null){ * @return AjxpWrapperProvider * @throws Sabre\DAV\Exception\FileNotFound */ - function getAccessDriver(){ - if(!isset($this->accessDriver)){ + public function getAccessDriver() + { + if (!isset($this->accessDriver)) { $RID = $this->repository->getId(); ConfService::switchRootDir($RID); ConfService::getConfStorageImpl(); $this->accessDriver = ConfService::loadRepositoryDriver(); - if(!$this->accessDriver instanceof AjxpWrapperProvider){ + if (!$this->accessDriver instanceof AjxpWrapperProvider) { throw new Sabre\DAV\Exception\FileNotFound( $RID ); } $this->accessDriver->detectStreamWrapper(true); @@ -71,8 +73,9 @@ function getAccessDriver(){ /** * @return String */ - function getUrl(){ - if(!isSet($this->url)){ + public function getUrl() + { + if (!isSet($this->url)) { $this->url = $this->getAccessDriver()->getResourceUrl($this->path); } return $this->url; @@ -83,15 +86,15 @@ function getUrl(){ * * @return void */ - function delete(){ - + public function delete() + { ob_start(); - try{ + try { AJXP_Controller::findActionAndApply("delete", array( "dir" => dirname($this->path), "file_0" => $this->path ), array()); - }catch(Exception $e){ + } catch (Exception $e) { } ob_get_flush(); @@ -106,7 +109,8 @@ function delete(){ * * @return string */ - function getName(){ + public function getName() + { return basename($this->getUrl()); } @@ -116,7 +120,8 @@ function getName(){ * @param string $name The new name * @return void */ - function setName($name){ + public function setName($name) + { $data = $this->getResourceData(); ob_start(); AJXP_Controller::findActionAndApply("rename", array( @@ -134,7 +139,8 @@ function setName($name){ * * @return int */ - function getLastModified(){ + public function getLastModified() + { return filemtime($this->getUrl()); } @@ -146,11 +152,11 @@ function getLastModified(){ * @see Sabre\DAV\IProperties::updateProperties * @return bool|array */ - public function updateProperties($properties) { - + public function updateProperties($properties) + { $resourceData = $this->getResourceData(); - foreach($properties as $propertyName=>$propertyValue) { + foreach ($properties as $propertyName=>$propertyValue) { // If it was null, we need to delete the property if (is_null($propertyValue)) { @@ -177,15 +183,15 @@ public function updateProperties($properties) { * @param array $properties * @return array */ - function getProperties($properties) { - + public function getProperties($properties) + { $resourceData = $this->getResourceData(); // if the array was empty, we need to return everything if (!$properties) return $resourceData['properties']; $props = array(); - foreach($properties as $property) { + foreach ($properties as $property) { if (isset($resourceData['properties'][$property])) $props[$property] = $resourceData['properties'][$property]; } @@ -193,20 +199,21 @@ function getProperties($properties) { } - protected function putResourceData($array, $newURL = null){ - + protected function putResourceData($array, $newURL = null) + { $metaStore = $this->getMetastore(); - if($metaStore != false){ + if ($metaStore != false) { $metaStore->setMetadata(new AJXP_Node(($newURL!=null?$newURL:$this->getUrl())), "SABRE_DAV", $array, false, AJXP_METADATA_SCOPE_GLOBAL); } } - protected function getResourceData(){ + protected function getResourceData() + { $metaStore = $this->getMetastore(); $data = array(); - if($metaStore != false){ + if ($metaStore != false) { $data = $metaStore->retrieveMetadata(new AJXP_Node($this->getUrl()), "SABRE_DAV", false, AJXP_METADATA_SCOPE_GLOBAL); } if (!isset($data['properties'])) $data['properties'] = array(); @@ -217,7 +224,8 @@ protected function getResourceData(){ /** * @return MetaStoreProvider|bool */ - protected function getMetastore(){ + protected function getMetastore() + { $metaStore = AJXP_PluginsService::getInstance()->getUniqueActivePluginForType("metastore"); if($metaStore === false) return false; $metaStore->initMeta($this->getAccessDriver()); diff --git a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_NodeLeaf.php b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_NodeLeaf.php index 4a312d9549..58ef050bba 100755 --- a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_NodeLeaf.php +++ b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_NodeLeaf.php @@ -47,8 +47,8 @@ class AJXP_Sabre_NodeLeaf extends AJXP_Sabre_Node implements Sabre\DAV\IFile * @param resource $data * @return string|null */ - function put($data){ - + public function put($data) + { // Warning, passed by ref $p = $this->path; @@ -71,7 +71,8 @@ function put($data){ * * @return mixed */ - function get(){ + public function get() + { $ajxpNode = new AJXP_Node($this->getUrl()); AJXP_Controller::applyHook("node.read", array(&$ajxpNode)); return fopen($this->getUrl(), "r"); @@ -84,12 +85,12 @@ function get(){ * * @return void|string */ - function getContentType(){ - + public function getContentType() + { //Get mimetype with fileinfo PECL extension $fp = fopen($this->getUrl(), "r"); $fileMime = null; - if(class_exists("finfo")) { + if (class_exists("finfo")) { $finfo = new finfo(FILEINFO_MIME); $fileMime = $finfo->buffer(fread($fp, 100)); } elseif (function_exists("mime_content_type")) { @@ -101,7 +102,7 @@ function getContentType(){ else { $regex = "/^([\w\+\-\.\/]+)\s+(\w+\s)*($fileExt\s)/i"; $lines = file( AJXP_CONF_PATH ."/mime.types"); - foreach($lines as $line) { + foreach ($lines as $line) { if(substr($line, 0, 1) == '#') continue; // skip comments $line = rtrim($line) . " "; @@ -114,8 +115,7 @@ function getContentType(){ fclose($fp); return $fileMime; /* - if ( $this->options->useMimeExts && ezcBaseFeatures::hasExtensionSupport( 'fileinfo' ) ) - { + if ( $this->options->useMimeExts && ezcBaseFeatures::hasExtensionSupport( 'fileinfo' ) ) { $fInfo = new fInfo( FILEINFO_MIME ); $mimeType = $fInfo->file( $this->getUrl() ); @@ -145,7 +145,8 @@ function getContentType(){ * * @return String|null */ - function getETag(){ + public function getETag() + { clearstatcache(); return '"'.md5( $this->path @@ -159,7 +160,8 @@ function getETag(){ * * @return int */ - function getSize(){ + public function getSize() + { return filesize($this->getUrl()); } diff --git a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_RootCollection.php b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_RootCollection.php index 5faaa823ea..da247f32f1 100755 --- a/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_RootCollection.php +++ b/core/src/core/classes/sabredav/ajaxplorer/class.AJXP_Sabre_RootCollection.php @@ -27,17 +27,17 @@ class AJXP_Sabre_RootCollection extends Sabre\DAV\SimpleCollection { - function getChildren(){ - + public function getChildren() + { $this->children = array(); $u = AuthService::getLoggedUser(); - if($u != null){ + if ($u != null) { $repos = ConfService::getAccessibleRepositories($u); // Refilter to make sure the driver is an AjxpWebdavProvider - foreach($repos as $repository){ + foreach ($repos as $repository) { $accessType = $repository->getAccessType(); $driver = AJXP_PluginsService::getInstance()->getPluginByTypeName("access", $accessType); - if(is_a($driver, "AjxpWrapperProvider")){ + if (is_a($driver, "AjxpWrapperProvider")) { $this->children[$repository->getSlug()] = new Sabre\DAV\SimpleCollection($repository->getSlug()); } } @@ -45,12 +45,14 @@ function getChildren(){ return $this->children; } - function childExists($name){ + public function childExists($name) + { $c = $this->getChildren(); return array_key_exists($name, $c); } - function getChild($name){ + public function getChild($name) + { $c = $this->getChildren(); return $c[$name]; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/AbstractBackend.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/AbstractBackend.php index 6121dca2ee..16bf861935 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/AbstractBackend.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/AbstractBackend.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class AbstractBackend implements BackendInterface { - +abstract class AbstractBackend implements BackendInterface +{ /** * Updates properties for a calendar. * @@ -52,8 +52,8 @@ abstract class AbstractBackend implements BackendInterface { * @param array $mutations * @return bool|array */ - public function updateCalendar($calendarId, array $mutations) { - + public function updateCalendar($calendarId, array $mutations) + { return false; } @@ -107,14 +107,14 @@ public function updateCalendar($calendarId, array $mutations) { * @param array $filters * @return array */ - public function calendarQuery($calendarId, array $filters) { - + public function calendarQuery($calendarId, array $filters) + { $result = array(); $objects = $this->getCalendarObjects($calendarId); $validator = new \Sabre\CalDAV\CalendarQueryValidator(); - foreach($objects as $object) { + foreach ($objects as $object) { if ($this->validateFilterForObject($object, $filters)) { $result[] = $object['uri']; @@ -134,8 +134,8 @@ public function calendarQuery($calendarId, array $filters) { * @param array $filters * @return bool */ - protected function validateFilterForObject(array $object, array $filters) { - + protected function validateFilterForObject(array $object, array $filters) + { // Unfortunately, setting the 'calendardata' here is optional. If // it was excluded, we actually need another call to get this as // well. diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/BackendInterface.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/BackendInterface.php index bec845367b..fd30fd3510 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/BackendInterface.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/BackendInterface.php @@ -4,13 +4,13 @@ /** * Every CalDAV backend must at least implement this interface. - * + * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface BackendInterface { - +interface BackendInterface +{ /** * Returns a list of calendars for a principal. * @@ -79,7 +79,7 @@ public function createCalendar($principalUri,$calendarUri,array $properties); * @param array $mutations * @return bool|array */ - public function updateCalendar($calendarId, array $mutations); + public function updateCalendar($calendarId, array $mutations); /** * Delete a calendar and all it's objects @@ -226,6 +226,6 @@ public function deleteCalendarObject($calendarId,$objectUri); * @param array $filters * @return array */ - public function calendarQuery($calendarId, array $filters); + public function calendarQuery($calendarId, array $filters); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/NotificationSupport.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/NotificationSupport.php index 38cd24d74c..0ec87bf302 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/NotificationSupport.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/NotificationSupport.php @@ -20,8 +20,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface NotificationSupport extends BackendInterface { - +interface NotificationSupport extends BackendInterface +{ /** * Returns a list of notifications for a given principal url. * diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/PDO.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/PDO.php index f0fbd7411e..ff74daabb0 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/PDO.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/PDO.php @@ -16,8 +16,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class PDO extends AbstractBackend { - +class PDO extends AbstractBackend +{ /** * We need to specify a max date, because we need to stop *somewhere* * @@ -72,8 +72,8 @@ class PDO extends AbstractBackend { * @param string $calendarTableName * @param string $calendarObjectTableName */ - public function __construct(\PDO $pdo, $calendarTableName = 'calendars', $calendarObjectTableName = 'calendarobjects') { - + public function __construct(\PDO $pdo, $calendarTableName = 'calendars', $calendarObjectTableName = 'calendarobjects') + { $this->pdo = $pdo; $this->calendarTableName = $calendarTableName; $this->calendarObjectTableName = $calendarObjectTableName; @@ -97,8 +97,8 @@ public function __construct(\PDO $pdo, $calendarTableName = 'calendars', $calend * @param string $principalUri * @return array */ - public function getCalendarsForUser($principalUri) { - + public function getCalendarsForUser($principalUri) + { $fields = array_values($this->propertyMap); $fields[] = 'id'; $fields[] = 'uri'; @@ -113,7 +113,7 @@ public function getCalendarsForUser($principalUri) { $stmt->execute(array($principalUri)); $calendars = array(); - while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { $components = array(); if ($row['components']) { @@ -130,7 +130,7 @@ public function getCalendarsForUser($principalUri) { ); - foreach($this->propertyMap as $xmlName=>$dbName) { + foreach ($this->propertyMap as $xmlName=>$dbName) { $calendar[$xmlName] = $row[$dbName]; } @@ -153,8 +153,8 @@ public function getCalendarsForUser($principalUri) { * @param array $properties * @return string */ - public function createCalendar($principalUri, $calendarUri, array $properties) { - + public function createCalendar($principalUri, $calendarUri, array $properties) + { $fieldNames = array( 'principaluri', 'uri', @@ -184,7 +184,7 @@ public function createCalendar($principalUri, $calendarUri, array $properties) { $values[':transparent'] = $properties[$transp]->getValue()==='transparent'; } - foreach($this->propertyMap as $xmlName=>$dbName) { + foreach ($this->propertyMap as $xmlName=>$dbName) { if (isset($properties[$xmlName])) { $values[':' . $dbName] = $properties[$xmlName]; @@ -235,8 +235,8 @@ public function createCalendar($principalUri, $calendarUri, array $properties) { * @param array $mutations * @return bool|array */ - public function updateCalendar($calendarId, array $mutations) { - + public function updateCalendar($calendarId, array $mutations) + { $newValues = array(); $result = array( 200 => array(), // Ok @@ -246,9 +246,9 @@ public function updateCalendar($calendarId, array $mutations) { $hasError = false; - foreach($mutations as $propertyName=>$propertyValue) { + foreach ($mutations as $propertyName=>$propertyValue) { - switch($propertyName) { + switch ($propertyName) { case '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp' : $fieldName = 'transparent'; $newValues[$fieldName] = $propertyValue->getValue()==='transparent'; @@ -272,12 +272,12 @@ public function updateCalendar($calendarId, array $mutations) { // If there were any errors we need to fail the request if ($hasError) { // Properties has the remaining properties - foreach($mutations as $propertyName=>$propertyValue) { + foreach ($mutations as $propertyName=>$propertyValue) { $result[424][$propertyName] = null; } // Removing unused statuscodes for cleanliness - foreach($result as $status=>$properties) { + foreach ($result as $status=>$properties) { if (is_array($properties) && count($properties)===0) unset($result[$status]); } @@ -289,7 +289,7 @@ public function updateCalendar($calendarId, array $mutations) { // Now we're generating the sql query. $valuesSql = array(); - foreach($newValues as $fieldName=>$value) { + foreach ($newValues as $fieldName=>$value) { $valuesSql[] = $fieldName . ' = ?'; } $valuesSql[] = 'ctag = ctag + 1'; @@ -308,8 +308,8 @@ public function updateCalendar($calendarId, array $mutations) { * @param string $calendarId * @return void */ - public function deleteCalendar($calendarId) { - + public function deleteCalendar($calendarId) + { $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?'); $stmt->execute(array($calendarId)); @@ -345,20 +345,20 @@ public function deleteCalendar($calendarId) { * @param string $calendarId * @return array */ - public function getCalendarObjects($calendarId) { - + public function getCalendarObjects($calendarId) + { $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?'); $stmt->execute(array($calendarId)); $result = array(); - foreach($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { + foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { $result[] = array( 'id' => $row['id'], 'uri' => $row['uri'], 'lastmodified' => $row['lastmodified'], 'etag' => '"' . $row['etag'] . '"', 'calendarid' => $row['calendarid'], - 'size' => (int)$row['size'], + 'size' => (int) $row['size'], ); } @@ -378,8 +378,8 @@ public function getCalendarObjects($calendarId) { * @param string $objectUri * @return array */ - public function getCalendarObject($calendarId,$objectUri) { - + public function getCalendarObject($calendarId,$objectUri) + { $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, calendardata FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?'); $stmt->execute(array($calendarId, $objectUri)); $row = $stmt->fetch(\PDO::FETCH_ASSOC); @@ -392,7 +392,7 @@ public function getCalendarObject($calendarId,$objectUri) { 'lastmodified' => $row['lastmodified'], 'etag' => '"' . $row['etag'] . '"', 'calendarid' => $row['calendarid'], - 'size' => (int)$row['size'], + 'size' => (int) $row['size'], 'calendardata' => $row['calendardata'], ); @@ -415,8 +415,8 @@ public function getCalendarObject($calendarId,$objectUri) { * @param string $calendarData * @return string|null */ - public function createCalendarObject($calendarId,$objectUri,$calendarData) { - + public function createCalendarObject($calendarId,$objectUri,$calendarData) + { $extraData = $this->getDenormalizedData($calendarData); $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarObjectTableName.' (calendarid, uri, calendardata, lastmodified, etag, size, componenttype, firstoccurence, lastoccurence) VALUES (?,?,?,?,?,?,?,?,?)'); @@ -454,8 +454,8 @@ public function createCalendarObject($calendarId,$objectUri,$calendarData) { * @param string $calendarData * @return string|null */ - public function updateCalendarObject($calendarId,$objectUri,$calendarData) { - + public function updateCalendarObject($calendarId,$objectUri,$calendarData) + { $extraData = $this->getDenormalizedData($calendarData); $stmt = $this->pdo->prepare('UPDATE '.$this->calendarObjectTableName.' SET calendardata = ?, lastmodified = ?, etag = ?, size = ?, componenttype = ?, firstoccurence = ?, lastoccurence = ? WHERE calendarid = ? AND uri = ?'); @@ -481,14 +481,14 @@ public function updateCalendarObject($calendarId,$objectUri,$calendarData) { * @param string $calendarData * @return array */ - protected function getDenormalizedData($calendarData) { - + protected function getDenormalizedData($calendarData) + { $vObject = VObject\Reader::read($calendarData); $componentType = null; $component = null; $firstOccurence = null; $lastOccurence = null; - foreach($vObject->getComponents() as $component) { + foreach ($vObject->getComponents() as $component) { if ($component->name!=='VTIMEZONE') { $componentType = $component->name; break; @@ -515,13 +515,13 @@ protected function getDenormalizedData($calendarData) { $lastOccurence = $firstOccurence; } } else { - $it = new VObject\RecurrenceIterator($vObject, (string)$component->UID); + $it = new VObject\RecurrenceIterator($vObject, (string) $component->UID); $maxDate = new \DateTime(self::MAX_DATE); if ($it->isInfinite()) { $lastOccurence = $maxDate->getTimeStamp(); } else { $end = $it->getDtEnd(); - while($it->valid() && $end < $maxDate) { + while ($it->valid() && $end < $maxDate) { $end = $it->getDtEnd(); $it->next(); @@ -549,8 +549,8 @@ protected function getDenormalizedData($calendarData) { * @param string $objectUri * @return void */ - public function deleteCalendarObject($calendarId,$objectUri) { - + public function deleteCalendarObject($calendarId,$objectUri) + { $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?'); $stmt->execute(array($calendarId,$objectUri)); $stmt = $this->pdo->prepare('UPDATE '. $this->calendarTableName .' SET ctag = ctag + 1 WHERE id = ?'); @@ -610,8 +610,8 @@ public function deleteCalendarObject($calendarId,$objectUri) { * @param array $filters * @return array */ - public function calendarQuery($calendarId, array $filters) { - + public function calendarQuery($calendarId, array $filters) + { $result = array(); $validator = new \Sabre\CalDAV\CalendarQueryValidator(); @@ -673,7 +673,7 @@ public function calendarQuery($calendarId, array $filters) { $stmt->execute($values); $result = array(); - while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { if ($requirePostFilter) { if (!$this->validateFilterForObject($row, $filters)) { continue; diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/SharingSupport.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/SharingSupport.php index e2562d825b..aaaa97bd52 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/SharingSupport.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Backend/SharingSupport.php @@ -169,8 +169,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface SharingSupport extends NotificationSupport { - +interface SharingSupport extends NotificationSupport +{ /** * Updates the list of shares. * @@ -194,7 +194,7 @@ interface SharingSupport extends NotificationSupport { * @param array $remove * @return void */ - function updateShares($calendarId, array $add, array $remove); + public function updateShares($calendarId, array $add, array $remove); /** * Returns the list of people whom this calendar is shared with. @@ -214,7 +214,7 @@ function updateShares($calendarId, array $add, array $remove); * @param mixed $calendarId * @return array */ - function getShares($calendarId); + public function getShares($calendarId); /** * This method is called when a user replied to a request to share. @@ -229,7 +229,7 @@ function getShares($calendarId); * @param string $summary A description of the reply * @return null|string */ - function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null); + public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null); /** * Publishes a calendar @@ -238,6 +238,6 @@ function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null); * @param bool $value * @return void */ - function setPublishStatus($calendarId, $value); + public function setPublishStatus($calendarId, $value); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Calendar.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Calendar.php index 47354e52e1..2ddda6e3a3 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Calendar.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Calendar.php @@ -15,8 +15,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Calendar implements ICalendar, DAV\IProperties, DAVACL\IACL { - +class Calendar implements ICalendar, DAV\IProperties, DAVACL\IACL +{ /** * This is an array with calendar information * @@ -37,8 +37,8 @@ class Calendar implements ICalendar, DAV\IProperties, DAVACL\IACL { * @param Backend\BackendInterface $caldavBackend * @param array $calendarInfo */ - public function __construct(Backend\BackendInterface $caldavBackend, $calendarInfo) { - + public function __construct(Backend\BackendInterface $caldavBackend, $calendarInfo) + { $this->caldavBackend = $caldavBackend; $this->calendarInfo = $calendarInfo; @@ -49,8 +49,8 @@ public function __construct(Backend\BackendInterface $caldavBackend, $calendarIn * * @return string */ - public function getName() { - + public function getName() + { return $this->calendarInfo['uri']; } @@ -61,8 +61,8 @@ public function getName() { * @param array $mutations * @return array */ - public function updateProperties($mutations) { - + public function updateProperties($mutations) + { return $this->caldavBackend->updateCalendar($this->calendarInfo['id'],$mutations); } @@ -73,11 +73,11 @@ public function updateProperties($mutations) { * @param array $requestedProperties * @return array */ - public function getProperties($requestedProperties) { - + public function getProperties($requestedProperties) + { $response = array(); - foreach($requestedProperties as $prop) switch($prop) { + foreach ($requestedProperties as $prop) switch ($prop) { case '{urn:ietf:params:xml:ns:caldav}supported-calendar-data' : $response[$prop] = new Property\SupportedCalendarData(); @@ -105,15 +105,15 @@ public function getProperties($requestedProperties) { * @param string $name * @return \Sabre\CalDAV\ICalendarObject */ - public function getChild($name) { - + public function getChild($name) + { $obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'],$name); if (!$obj) throw new DAV\Exception\NotFound('Calendar object not found'); $obj['acl'] = $this->getACL(); // Removing the irrelivant - foreach($obj['acl'] as $key=>$acl) { + foreach ($obj['acl'] as $key=>$acl) { if ($acl['privilege'] === '{' . Plugin::NS_CALDAV . '}read-free-busy') { unset($obj['acl'][$key]); } @@ -128,14 +128,14 @@ public function getChild($name) { * * @return array */ - public function getChildren() { - + public function getChildren() + { $objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id']); $children = array(); - foreach($objs as $obj) { + foreach ($objs as $obj) { $obj['acl'] = $this->getACL(); // Removing the irrelivant - foreach($obj['acl'] as $key=>$acl) { + foreach ($obj['acl'] as $key=>$acl) { if ($acl['privilege'] === '{' . Plugin::NS_CALDAV . '}read-free-busy') { unset($obj['acl'][$key]); } @@ -152,8 +152,8 @@ public function getChildren() { * @param string $name * @return bool */ - public function childExists($name) { - + public function childExists($name) + { $obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'],$name); if (!$obj) return false; @@ -170,8 +170,8 @@ public function childExists($name) { * @param string $name * @return void */ - public function createDirectory($name) { - + public function createDirectory($name) + { throw new DAV\Exception\MethodNotAllowed('Creating collections in calendar objects is not allowed'); } @@ -185,8 +185,8 @@ public function createDirectory($name) { * @param resource $calendarData * @return string|null */ - public function createFile($name,$calendarData = null) { - + public function createFile($name,$calendarData = null) + { if (is_resource($calendarData)) { $calendarData = stream_get_contents($calendarData); } @@ -199,8 +199,8 @@ public function createFile($name,$calendarData = null) { * * @return void */ - public function delete() { - + public function delete() + { $this->caldavBackend->deleteCalendar($this->calendarInfo['id']); } @@ -212,8 +212,8 @@ public function delete() { * @param string $newName * @return void */ - public function setName($newName) { - + public function setName($newName) + { throw new DAV\Exception\MethodNotAllowed('Renaming calendars is not yet supported'); } @@ -223,8 +223,8 @@ public function setName($newName) { * * @return void */ - public function getLastModified() { - + public function getLastModified() + { return null; } @@ -236,8 +236,8 @@ public function getLastModified() { * * @return string|null */ - public function getOwner() { - + public function getOwner() + { return $this->calendarInfo['principaluri']; } @@ -249,8 +249,8 @@ public function getOwner() { * * @return string|null */ - public function getGroup() { - + public function getGroup() + { return null; } @@ -267,8 +267,8 @@ public function getGroup() { * * @return array */ - public function getACL() { - + public function getACL() + { return array( array( 'privilege' => '{DAV:}read', @@ -313,8 +313,8 @@ public function getACL() { * @param array $acl * @return void */ - public function setACL(array $acl) { - + public function setACL(array $acl) + { throw new DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported'); } @@ -331,13 +331,13 @@ public function setACL(array $acl) { * * @return array|null */ - public function getSupportedPrivilegeSet() { - + public function getSupportedPrivilegeSet() + { $default = DAVACL\Plugin::getDefaultSupportedPrivilegeSet(); // We need to inject 'read-free-busy' in the tree, aggregated under // {DAV:}read. - foreach($default['aggregates'] as &$agg) { + foreach ($default['aggregates'] as &$agg) { if ($agg['privilege'] !== '{DAV:}read') continue; @@ -367,8 +367,8 @@ public function getSupportedPrivilegeSet() { * @param array $filters * @return array */ - public function calendarQuery(array $filters) { - + public function calendarQuery(array $filters) + { return $this->caldavBackend->calendarQuery($this->calendarInfo['id'], $filters); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarObject.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarObject.php index 8103a85255..096fc9ea2f 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarObject.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarObject.php @@ -9,8 +9,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\DAVACL\IACL { - +class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\DAVACL\IACL +{ /** * Sabre\CalDAV\Backend\BackendInterface * @@ -39,8 +39,8 @@ class CalendarObject extends \Sabre\DAV\File implements ICalendarObject, \Sabre\ * @param array $calendarInfo * @param array $objectData */ - public function __construct(Backend\BackendInterface $caldavBackend,array $calendarInfo,array $objectData) { - + public function __construct(Backend\BackendInterface $caldavBackend,array $calendarInfo,array $objectData) + { $this->caldavBackend = $caldavBackend; if (!isset($objectData['calendarid'])) { @@ -60,8 +60,8 @@ public function __construct(Backend\BackendInterface $caldavBackend,array $calen * * @return string */ - public function getName() { - + public function getName() + { return $this->objectData['uri']; } @@ -71,8 +71,8 @@ public function getName() { * * @return string */ - public function get() { - + public function get() + { // Pre-populating the 'calendardata' is optional, if we don't have it // already we fetch it from the backend. if (!isset($this->objectData['calendardata'])) { @@ -88,8 +88,8 @@ public function get() { * @param string|resource $calendarData * @return string */ - public function put($calendarData) { - + public function put($calendarData) + { if (is_resource($calendarData)) { $calendarData = stream_get_contents($calendarData); } @@ -106,8 +106,8 @@ public function put($calendarData) { * * @return void */ - public function delete() { - + public function delete() + { $this->caldavBackend->deleteCalendarObject($this->calendarInfo['id'],$this->objectData['uri']); } @@ -117,8 +117,8 @@ public function delete() { * * @return string */ - public function getContentType() { - + public function getContentType() + { return 'text/calendar; charset=utf-8'; } @@ -130,8 +130,8 @@ public function getContentType() { * * @return string */ - public function getETag() { - + public function getETag() + { if (isset($this->objectData['etag'])) { return $this->objectData['etag']; } else { @@ -145,8 +145,8 @@ public function getETag() { * * @return int */ - public function getLastModified() { - + public function getLastModified() + { return $this->objectData['lastmodified']; } @@ -156,8 +156,8 @@ public function getLastModified() { * * @return int */ - public function getSize() { - + public function getSize() + { if (array_key_exists('size',$this->objectData)) { return $this->objectData['size']; } else { @@ -173,8 +173,8 @@ public function getSize() { * * @return string|null */ - public function getOwner() { - + public function getOwner() + { return $this->calendarInfo['principaluri']; } @@ -186,8 +186,8 @@ public function getOwner() { * * @return string|null */ - public function getGroup() { - + public function getGroup() + { return null; } @@ -204,8 +204,8 @@ public function getGroup() { * * @return array */ - public function getACL() { - + public function getACL() + { // An alternative acl may be specified in the object data. if (isset($this->objectData['acl'])) { return $this->objectData['acl']; @@ -251,8 +251,8 @@ public function getACL() { * @param array $acl * @return void */ - public function setACL(array $acl) { - + public function setACL(array $acl) + { throw new \Sabre\DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported'); } @@ -269,11 +269,10 @@ public function setACL(array $acl) { * * @return array|null */ - public function getSupportedPrivilegeSet() { - + public function getSupportedPrivilegeSet() + { return null; } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarQueryParser.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarQueryParser.php index ea0419f306..1caebd64c1 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarQueryParser.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarQueryParser.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class CalendarQueryParser { - +class CalendarQueryParser +{ /** * List of requested properties the client wanted * @@ -64,8 +64,8 @@ class CalendarQueryParser { * * @param \DOMDocument $dom */ - public function __construct(\DOMDocument $dom) { - + public function __construct(\DOMDocument $dom) + { $this->dom = $dom; $this->xpath = new \DOMXPath($dom); $this->xpath->registerNameSpace('cal',Plugin::NS_CALDAV); @@ -78,8 +78,8 @@ public function __construct(\DOMDocument $dom) { * * @return void */ - public function parse() { - + public function parse() + { $filterNode = null; $filter = $this->xpath->query('/cal:calendar-query/cal:filter'); @@ -109,12 +109,12 @@ public function parse() { * @param \DOMElement $parentNode * @return array */ - protected function parseCompFilters(\DOMElement $parentNode) { - + protected function parseCompFilters(\DOMElement $parentNode) + { $compFilterNodes = $this->xpath->query('cal:comp-filter', $parentNode); $result = array(); - for($ii=0; $ii < $compFilterNodes->length; $ii++) { + for ($ii=0; $ii < $compFilterNodes->length; $ii++) { $compFilterNode = $compFilterNodes->item($ii); @@ -149,8 +149,8 @@ protected function parseCompFilters(\DOMElement $parentNode) { * @param \DOMElement $parentNode * @return array */ - protected function parsePropFilters(\DOMElement $parentNode) { - + protected function parsePropFilters(\DOMElement $parentNode) + { $propFilterNodes = $this->xpath->query('cal:prop-filter', $parentNode); $result = array(); @@ -178,12 +178,12 @@ protected function parsePropFilters(\DOMElement $parentNode) { * @param \DOMElement $parentNode * @return array */ - protected function parseParamFilters(\DOMElement $parentNode) { - + protected function parseParamFilters(\DOMElement $parentNode) + { $paramFilterNodes = $this->xpath->query('cal:param-filter', $parentNode); $result = array(); - for($ii=0;$ii<$paramFilterNodes->length;$ii++) { + for ($ii=0;$ii<$paramFilterNodes->length;$ii++) { $paramFilterNode = $paramFilterNodes->item($ii); $paramFilter = array(); @@ -205,8 +205,8 @@ protected function parseParamFilters(\DOMElement $parentNode) { * @param \DOMElement $parentNode * @return array|null */ - protected function parseTextMatch(\DOMElement $parentNode) { - + protected function parseTextMatch(\DOMElement $parentNode) + { $textMatchNodes = $this->xpath->query('cal:text-match', $parentNode); if ($textMatchNodes->length === 0) @@ -232,8 +232,8 @@ protected function parseTextMatch(\DOMElement $parentNode) { * @param \DOMElement $parentNode * @return array|null */ - protected function parseTimeRange(\DOMElement $parentNode) { - + protected function parseTimeRange(\DOMElement $parentNode) + { $timeRangeNodes = $this->xpath->query('cal:time-range', $parentNode); if ($timeRangeNodes->length === 0) { return null; @@ -269,16 +269,16 @@ protected function parseTimeRange(\DOMElement $parentNode) { * @param \DOMElement $parentNode * @return void */ - protected function parseExpand(\DOMElement $parentNode) { - + protected function parseExpand(\DOMElement $parentNode) + { $start = $parentNode->getAttribute('start'); - if(!$start) { + if (!$start) { throw new \Sabre\DAV\Exception\BadRequest('The "start" attribute is required for the CALDAV:expand element'); } $start = VObject\DateTimeParser::parseDateTime($start); $end = $parentNode->getAttribute('end'); - if(!$end) { + if (!$end) { throw new \Sabre\DAV\Exception\BadRequest('The "end" attribute is required for the CALDAV:expand element'); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarQueryValidator.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarQueryValidator.php index 7d4b2cfdf8..3d0fb1b32e 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarQueryValidator.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarQueryValidator.php @@ -18,8 +18,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class CalendarQueryValidator { - +class CalendarQueryValidator +{ /** * Verify if a list of filters applies to the calendar data object * @@ -29,8 +29,8 @@ class CalendarQueryValidator { * @param array $filters * @return bool */ - public function validate(VObject\Component $vObject,array $filters) { - + public function validate(VObject\Component $vObject,array $filters) + { // The top level object is always a component filter. // We'll parse it manually, as it's pretty simple. if ($vObject->name !== $filters['name']) { @@ -55,9 +55,9 @@ public function validate(VObject\Component $vObject,array $filters) { * @param array $filters * @return bool */ - protected function validateCompFilters(VObject\Component $parent, array $filters) { - - foreach($filters as $filter) { + protected function validateCompFilters(VObject\Component $parent, array $filters) + { + foreach ($filters as $filter) { $isDefined = isset($parent->$filter['name']); @@ -75,7 +75,7 @@ protected function validateCompFilters(VObject\Component $parent, array $filters } if ($filter['time-range']) { - foreach($parent->$filter['name'] as $subComponent) { + foreach ($parent->$filter['name'] as $subComponent) { if ($this->validateTimeRange($subComponent, $filter['time-range']['start'], $filter['time-range']['end'])) { continue 2; } @@ -89,7 +89,7 @@ protected function validateCompFilters(VObject\Component $parent, array $filters // If there are sub-filters, we need to find at least one component // for which the subfilters hold true. - foreach($parent->$filter['name'] as $subComponent) { + foreach ($parent->$filter['name'] as $subComponent) { if ( $this->validateCompFilters($subComponent, $filter['comp-filters']) && @@ -124,9 +124,9 @@ protected function validateCompFilters(VObject\Component $parent, array $filters * @param array $filters * @return bool */ - protected function validatePropFilters(VObject\Component $parent, array $filters) { - - foreach($filters as $filter) { + protected function validatePropFilters(VObject\Component $parent, array $filters) + { + foreach ($filters as $filter) { $isDefined = isset($parent->$filter['name']); @@ -144,7 +144,7 @@ protected function validatePropFilters(VObject\Component $parent, array $filters } if ($filter['time-range']) { - foreach($parent->$filter['name'] as $subComponent) { + foreach ($parent->$filter['name'] as $subComponent) { if ($this->validateTimeRange($subComponent, $filter['time-range']['start'], $filter['time-range']['end'])) { continue 2; } @@ -158,7 +158,7 @@ protected function validatePropFilters(VObject\Component $parent, array $filters // If there are sub-filters, we need to find at least one property // for which the subfilters hold true. - foreach($parent->$filter['name'] as $subComponent) { + foreach ($parent->$filter['name'] as $subComponent) { if( $this->validateParamFilters($subComponent, $filter['param-filters']) && @@ -194,9 +194,9 @@ protected function validatePropFilters(VObject\Component $parent, array $filters * @param array $filters * @return bool */ - protected function validateParamFilters(VObject\Property $parent, array $filters) { - - foreach($filters as $filter) { + protected function validateParamFilters(VObject\Property $parent, array $filters) + { + foreach ($filters as $filter) { $isDefined = isset($parent[$filter['name']]); @@ -219,9 +219,9 @@ protected function validateParamFilters(VObject\Property $parent, array $filters // If there are sub-filters, we need to find at least one parameter // for which the subfilters hold true. - foreach($parent[$filter['name']] as $subParam) { + foreach ($parent[$filter['name']] as $subParam) { - if($this->validateTextMatch($subParam,$filter['text-match'])) { + if ($this->validateTextMatch($subParam,$filter['text-match'])) { // We had a match, so this param-filter succeeds continue 2; } @@ -250,9 +250,9 @@ protected function validateParamFilters(VObject\Property $parent, array $filters * @param array $textMatch * @return bool */ - protected function validateTextMatch(VObject\Node $parent, array $textMatch) { - - $value = (string)$parent; + protected function validateTextMatch(VObject\Node $parent, array $textMatch) + { + $value = (string) $parent; $isMatching = \Sabre\DAV\StringUtil::textMatch($value, $textMatch['value'], $textMatch['collation']); @@ -271,8 +271,8 @@ protected function validateTextMatch(VObject\Node $parent, array $textMatch) { * @param DateTime $end * @return bool */ - protected function validateTimeRange(VObject\Node $component, $start, $end) { - + protected function validateTimeRange(VObject\Node $component, $start, $end) + { if (is_null($start)) { $start = new DateTime('1900-01-01'); } @@ -280,7 +280,7 @@ protected function validateTimeRange(VObject\Node $component, $start, $end) { $end = new DateTime('3000-01-01'); } - switch($component->name) { + switch ($component->name) { case 'VEVENT' : case 'VTODO' : @@ -299,8 +299,8 @@ protected function validateTimeRange(VObject\Node $component, $start, $end) { if ($component->parent->name === 'VEVENT' && $component->parent->RRULE) { // Fire up the iterator! - $it = new VObject\RecurrenceIterator($component->parent->parent, (string)$component->parent->UID); - while($it->valid()) { + $it = new VObject\RecurrenceIterator($component->parent->parent, (string) $component->parent->UID); + while ($it->valid()) { $expandedEvent = $it->getEventObject(); // We need to check from these expanded alarms, which @@ -308,14 +308,14 @@ protected function validateTimeRange(VObject\Node $component, $start, $end) { // determine if we can 'give up' expanding events. $firstAlarm = null; if ($expandedEvent->VALARM !== null) { - foreach($expandedEvent->VALARM as $expandedAlarm) { + foreach ($expandedEvent->VALARM as $expandedAlarm) { $effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime(); if ($expandedAlarm->isInTimeRange($start, $end)) { return true; } - if ((string)$expandedAlarm->TRIGGER['VALUE'] === 'DATE-TIME') { + if ((string) $expandedAlarm->TRIGGER['VALUE'] === 'DATE-TIME') { // This is an alarm with a non-relative trigger // time, likely created by a buggy client. The // implication is that every alarm in this diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarRootNode.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarRootNode.php index 5cfd82b2e2..e86064cd5a 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarRootNode.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/CalendarRootNode.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class CalendarRootNode extends \Sabre\DAVACL\AbstractPrincipalCollection { - +class CalendarRootNode extends \Sabre\DAVACL\AbstractPrincipalCollection +{ /** * CalDAV backend * @@ -37,8 +37,8 @@ class CalendarRootNode extends \Sabre\DAVACL\AbstractPrincipalCollection { * @param Backend\BackendInterface $caldavBackend * @param string $principalPrefix */ - public function __construct(PrincipalBackend\BackendInterface $principalBackend,Backend\BackendInterface $caldavBackend, $principalPrefix = 'principals') { - + public function __construct(PrincipalBackend\BackendInterface $principalBackend,Backend\BackendInterface $caldavBackend, $principalPrefix = 'principals') + { parent::__construct($principalBackend, $principalPrefix); $this->caldavBackend = $caldavBackend; @@ -52,8 +52,8 @@ public function __construct(PrincipalBackend\BackendInterface $principalBackend, * * @return string */ - public function getName() { - + public function getName() + { return Plugin::CALENDAR_ROOT; } @@ -68,8 +68,8 @@ public function getName() { * @param array $principal * @return \Sabre\DAV\INode */ - public function getChildForPrincipal(array $principal) { - + public function getChildForPrincipal(array $principal) + { return new UserCalendars($this->caldavBackend, $principal); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Exception/InvalidComponentType.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Exception/InvalidComponentType.php index 0b2b2848b5..1403e04564 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Exception/InvalidComponentType.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Exception/InvalidComponentType.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class InvalidComponentType extends DAV\Exception\Forbidden { - +class InvalidComponentType extends DAV\Exception\Forbidden +{ /** * Adds in extra information in the xml response. * @@ -23,8 +23,8 @@ class InvalidComponentType extends DAV\Exception\Forbidden { * @param \DOMElement $errorNode * @return void */ - public function serialize(DAV\Server $server, \DOMElement $errorNode) { - + public function serialize(DAV\Server $server, \DOMElement $errorNode) + { $doc = $errorNode->ownerDocument; $np = $doc->createElementNS(CalDAV\Plugin::NS_CALDAV,'cal:supported-calendar-component'); diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICSExportPlugin.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICSExportPlugin.php index 93380d358f..527f06c56c 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICSExportPlugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICSExportPlugin.php @@ -16,8 +16,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class ICSExportPlugin extends DAV\ServerPlugin { - +class ICSExportPlugin extends DAV\ServerPlugin +{ /** * Reference to Server class * @@ -31,8 +31,8 @@ class ICSExportPlugin extends DAV\ServerPlugin { * @param \Sabre\DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { $this->server = $server; $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'), 90); @@ -46,8 +46,8 @@ public function initialize(DAV\Server $server) { * @param string $uri * @return bool */ - public function beforeMethod($method, $uri) { - + public function beforeMethod($method, $uri) + { if ($method!='GET') return; if ($this->server->httpRequest->getQueryString()!='export') return; @@ -83,8 +83,8 @@ public function beforeMethod($method, $uri) { * @param array $nodes * @return string */ - public function generateICS(array $nodes) { - + public function generateICS(array $nodes) + { $calendar = new VObject\Component('vcalendar'); $calendar->version = '2.0'; if (DAV\Server::$exposeVersion) { @@ -99,7 +99,7 @@ public function generateICS(array $nodes) { $timezones = array(); $objects = array(); - foreach($nodes as $node) { + foreach ($nodes as $node) { if (!isset($node[200]['{' . Plugin::NS_CALDAV . '}calendar-data'])) { continue; @@ -108,9 +108,9 @@ public function generateICS(array $nodes) { $nodeComp = VObject\Reader::read($nodeData); - foreach($nodeComp->children() as $child) { + foreach ($nodeComp->children() as $child) { - switch($child->name) { + switch ($child->name) { case 'VEVENT' : case 'VTODO' : case 'VJOURNAL' : @@ -120,7 +120,7 @@ public function generateICS(array $nodes) { // VTIMEZONE is special, because we need to filter out the duplicates case 'VTIMEZONE' : // Naively just checking tzid. - if (in_array((string)$child->TZID, $collectedTimezones)) continue; + if (in_array((string) $child->TZID, $collectedTimezones)) continue; $timezones[] = $child; $collectedTimezones[] = $child->TZID; diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICalendar.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICalendar.php index 2ff986766d..fafa8d848d 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICalendar.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICalendar.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface ICalendar extends DAV\ICollection { - +interface ICalendar extends DAV\ICollection +{ /** * Performs a calendar-query on the contents of this calendar. * diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICalendarObject.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICalendarObject.php index deb9c1dd48..7df5fcce49 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICalendarObject.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ICalendarObject.php @@ -12,10 +12,9 @@ * Calendar objects are resources such as Events, Todo's or Journals. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface ICalendarObject extends DAV\IFile { - +interface ICalendarObject extends DAV\IFile +{ } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/IShareableCalendar.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/IShareableCalendar.php index 1c98b56bd1..9dca98c0d3 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/IShareableCalendar.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/IShareableCalendar.php @@ -9,8 +9,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IShareableCalendar extends ICalendar { - +interface IShareableCalendar extends ICalendar +{ /** * Updates the list of shares. * @@ -29,7 +29,7 @@ interface IShareableCalendar extends ICalendar { * @param array $remove * @return void */ - function updateShares(array $add, array $remove); + public function updateShares(array $add, array $remove); /** * Returns the list of people whom this calendar is shared with. @@ -43,6 +43,6 @@ function updateShares(array $add, array $remove); * * @return array */ - function getShares(); + public function getShares(); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ISharedCalendar.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ISharedCalendar.php index 25b0e2042e..61c96a9381 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ISharedCalendar.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ISharedCalendar.php @@ -9,15 +9,15 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface ISharedCalendar extends ICalendar { - +interface ISharedCalendar extends ICalendar +{ /** * This method should return the url of the owners' copy of the shared * calendar. * * @return string */ - function getSharedUrl(); + public function getSharedUrl(); /** * Returns the list of people whom this calendar is shared with. @@ -31,6 +31,6 @@ function getSharedUrl(); * * @return array */ - function getShares(); + public function getShares(); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Collection.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Collection.php index d21f7aba39..ec337bf8eb 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Collection.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Collection.php @@ -20,8 +20,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Collection extends DAV\Collection implements ICollection, DAVACL\IACL { - +class Collection extends DAV\Collection implements ICollection, DAVACL\IACL +{ /** * The notification backend * @@ -42,8 +42,8 @@ class Collection extends DAV\Collection implements ICollection, DAVACL\IACL { * @param CalDAV\Backend\NotificationSupport $caldavBackend * @param string $principalUri */ - public function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $principalUri) { - + public function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $principalUri) + { $this->caldavBackend = $caldavBackend; $this->principalUri = $principalUri; @@ -54,12 +54,12 @@ public function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $ * * @return array */ - public function getChildren() { - + public function getChildren() + { $children = array(); $notifications = $this->caldavBackend->getNotificationsForPrincipal($this->principalUri); - foreach($notifications as $notification) { + foreach ($notifications as $notification) { $children[] = new Node( $this->caldavBackend, @@ -77,8 +77,8 @@ public function getChildren() { * * @return string */ - public function getName() { - + public function getName() + { return 'notifications'; } @@ -90,8 +90,8 @@ public function getName() { * * @return string|null */ - public function getOwner() { - + public function getOwner() + { return $this->principalUri; } @@ -103,8 +103,8 @@ public function getOwner() { * * @return string|null */ - public function getGroup() { - + public function getGroup() + { return null; } @@ -121,8 +121,8 @@ public function getGroup() { * * @return array */ - public function getACL() { - + public function getACL() + { return array( array( 'principal' => $this->getOwner(), @@ -146,8 +146,8 @@ public function getACL() { * @param array $acl * @return void */ - public function setACL(array $acl) { - + public function setACL(array $acl) + { throw new DAV\Exception\NotImplemented('Updating ACLs is not implemented here'); } @@ -164,8 +164,8 @@ public function setACL(array $acl) { * * @return array|null */ - public function getSupportedPrivilegeSet() { - + public function getSupportedPrivilegeSet() + { return null; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/ICollection.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/ICollection.php index 3e28e3040a..e383f6e3cc 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/ICollection.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/ICollection.php @@ -18,7 +18,6 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface ICollection extends DAV\ICollection { - - +interface ICollection extends DAV\ICollection +{ } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/INode.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/INode.php index 7d8367f57d..f618d0b794 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/INode.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/INode.php @@ -16,15 +16,15 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface INode { - +interface INode +{ /** * This method must return an xml element, using the * Sabre\CalDAV\Notifications\INotificationType classes. * * @return INotificationType */ - function getNotificationType(); + public function getNotificationType(); /** * Returns the etag for the notification. @@ -33,6 +33,6 @@ function getNotificationType(); * * @return string */ - function getETag(); + public function getETag(); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/INotificationType.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/INotificationType.php index 245e53f6ee..dd91e7ae49 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/INotificationType.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/INotificationType.php @@ -10,8 +10,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface INotificationType extends DAV\PropertyInterface { - +interface INotificationType extends DAV\PropertyInterface +{ /** * This method serializes the entire notification, as it is used in the * response body. @@ -20,7 +20,7 @@ interface INotificationType extends DAV\PropertyInterface { * @param \DOMElement $node * @return void */ - function serializeBody(DAV\Server $server, \DOMElement $node); + public function serializeBody(DAV\Server $server, \DOMElement $node); /** * Returns a unique id for this notification @@ -30,7 +30,7 @@ function serializeBody(DAV\Server $server, \DOMElement $node); * * @return string */ - function getId(); + public function getId(); /** * Returns the ETag for this notification. @@ -39,6 +39,6 @@ function getId(); * * @return string */ - function getETag(); + public function getETag(); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Node.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Node.php index 5ef34d24d6..a571fb4b8f 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Node.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Node.php @@ -17,8 +17,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Node extends DAV\File implements INode, DAVACL\IACL { - +class Node extends DAV\File implements INode, DAVACL\IACL +{ /** * The notification backend * @@ -47,8 +47,8 @@ class Node extends DAV\File implements INode, DAVACL\IACL { * @param string $principalUri * @param CalDAV\Notifications\INotificationType $notification */ - public function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $principalUri, INotificationType $notification) { - + public function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $principalUri, INotificationType $notification) + { $this->caldavBackend = $caldavBackend; $this->principalUri = $principalUri; $this->notification = $notification; @@ -60,8 +60,8 @@ public function __construct(CalDAV\Backend\NotificationSupport $caldavBackend, $ * * @return id */ - public function getName() { - + public function getName() + { return $this->notification->getId() . '.xml'; } @@ -73,8 +73,8 @@ public function getName() { * * @return string */ - public function getETag() { - + public function getETag() + { return $this->notification->getETag(); } @@ -85,8 +85,8 @@ public function getETag() { * * @return INotificationType */ - public function getNotificationType() { - + public function getNotificationType() + { return $this->notification; } @@ -96,8 +96,8 @@ public function getNotificationType() { * * @return void */ - public function delete() { - + public function delete() + { $this->caldavBackend->deleteNotification($this->getOwner(), $this->notification); } @@ -109,8 +109,8 @@ public function delete() { * * @return string|null */ - public function getOwner() { - + public function getOwner() + { return $this->principalUri; } @@ -122,8 +122,8 @@ public function getOwner() { * * @return string|null */ - public function getGroup() { - + public function getGroup() + { return null; } @@ -140,8 +140,8 @@ public function getGroup() { * * @return array */ - public function getACL() { - + public function getACL() + { return array( array( 'principal' => $this->getOwner(), @@ -165,8 +165,8 @@ public function getACL() { * @param array $acl * @return void */ - public function setACL(array $acl) { - + public function setACL(array $acl) + { throw new DAV\Exception\NotImplemented('Updating ACLs is not implemented here'); } @@ -183,8 +183,8 @@ public function setACL(array $acl) { * * @return array|null */ - public function getSupportedPrivilegeSet() { - + public function getSupportedPrivilegeSet() + { return null; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/Invite.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/Invite.php index 65207f4647..944a04e0b4 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/Invite.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/Invite.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Invite extends DAV\Property implements CalDAV\Notifications\INotificationType { - +class Invite extends DAV\Property implements CalDAV\Notifications\INotificationType +{ /** * A unique id for the message * @@ -134,8 +134,8 @@ class Invite extends DAV\Property implements CalDAV\Notifications\INotificationT * * @param array $values All the options */ - public function __construct(array $values) { - + public function __construct(array $values) + { $required = array( 'id', 'etag', @@ -146,13 +146,13 @@ public function __construct(array $values) { 'hostUrl', 'organizer', ); - foreach($required as $item) { + foreach ($required as $item) { if (!isset($values[$item])) { throw new \InvalidArgumentException($item . ' is a required constructor option'); } } - foreach($values as $key=>$value) { + foreach ($values as $key=>$value) { if (!property_exists($this, $key)) { throw new \InvalidArgumentException('Unknown option: ' . $key); } @@ -171,8 +171,8 @@ public function __construct(array $values) { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server, \DOMElement $node) { - + public function serialize(DAV\Server $server, \DOMElement $node) + { $prop = $node->ownerDocument->createElement('cs:invite-notification'); $node->appendChild($prop); @@ -186,8 +186,8 @@ public function serialize(DAV\Server $server, \DOMElement $node) { * @param \DOMElement $node * @return void */ - public function serializeBody(DAV\Server $server, \DOMElement $node) { - + public function serializeBody(DAV\Server $server, \DOMElement $node) + { $doc = $node->ownerDocument; $dt = $doc->createElement('cs:dtstamp'); @@ -207,7 +207,7 @@ public function serializeBody(DAV\Server $server, \DOMElement $node) { $prop->appendChild($href); $nodeName = null; - switch($this->type) { + switch ($this->type) { case SharingPlugin::STATUS_ACCEPTED : $nodeName = 'cs:invite-accepted'; @@ -302,8 +302,8 @@ public function serializeBody(DAV\Server $server, \DOMElement $node) { * * @return string */ - public function getId() { - + public function getId() + { return $this->id; } @@ -315,8 +315,8 @@ public function getId() { * * @return string */ - public function getETag() { - + public function getETag() + { return $this->etag; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/InviteReply.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/InviteReply.php index dce3e17a4b..2650ebfcf7 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/InviteReply.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/InviteReply.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class InviteReply extends DAV\Property implements CalDAV\Notifications\INotificationType { - +class InviteReply extends DAV\Property implements CalDAV\Notifications\INotificationType +{ /** * A unique id for the message * @@ -87,8 +87,8 @@ class InviteReply extends DAV\Property implements CalDAV\Notifications\INotifica * * summary - Description of the share, can be the same as the * calendar, but may also be modified (optional). */ - public function __construct(array $values) { - + public function __construct(array $values) + { $required = array( 'id', 'etag', @@ -98,13 +98,13 @@ public function __construct(array $values) { 'type', 'hostUrl', ); - foreach($required as $item) { + foreach ($required as $item) { if (!isset($values[$item])) { throw new \InvalidArgumentException($item . ' is a required constructor option'); } } - foreach($values as $key=>$value) { + foreach ($values as $key=>$value) { if (!property_exists($this, $key)) { throw new \InvalidArgumentException('Unknown option: ' . $key); } @@ -123,8 +123,8 @@ public function __construct(array $values) { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server, \DOMElement $node) { - + public function serialize(DAV\Server $server, \DOMElement $node) + { $prop = $node->ownerDocument->createElement('cs:invite-reply'); $node->appendChild($prop); @@ -138,8 +138,8 @@ public function serialize(DAV\Server $server, \DOMElement $node) { * @param \DOMElement $node * @return void */ - public function serializeBody(DAV\Server $server, \DOMElement $node) { - + public function serializeBody(DAV\Server $server, \DOMElement $node) + { $doc = $node->ownerDocument; $dt = $doc->createElement('cs:dtstamp'); @@ -163,7 +163,7 @@ public function serializeBody(DAV\Server $server, \DOMElement $node) { $prop->appendChild($href); $nodeName = null; - switch($this->type) { + switch ($this->type) { case SharingPlugin::STATUS_ACCEPTED : $nodeName = 'cs:invite-accepted'; @@ -197,8 +197,8 @@ public function serializeBody(DAV\Server $server, \DOMElement $node) { * * @return string */ - public function getId() { - + public function getId() + { return $this->id; } @@ -210,8 +210,8 @@ public function getId() { * * @return string */ - public function getETag() { - + public function getETag() + { return $this->etag; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/SystemStatus.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/SystemStatus.php index 3b8dfa20f8..af9c8a8a44 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/SystemStatus.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Notifications/Notification/SystemStatus.php @@ -15,8 +15,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SystemStatus extends DAV\Property implements CalDAV\Notifications\INotificationType { - +class SystemStatus extends DAV\Property implements CalDAV\Notifications\INotificationType +{ const TYPE_LOW = 1; const TYPE_MEDIUM = 2; const TYPE_HIGH = 3; @@ -68,8 +68,8 @@ class SystemStatus extends DAV\Property implements CalDAV\Notifications\INotific * @param string $description * @param string $href */ - public function __construct($id, $etag, $type = self::TYPE_HIGH, $description = null, $href = null) { - + public function __construct($id, $etag, $type = self::TYPE_HIGH, $description = null, $href = null) + { $this->id = $id; $this->type = $type; $this->description = $description; @@ -88,9 +88,9 @@ public function __construct($id, $etag, $type = self::TYPE_HIGH, $description = * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server, \DOMElement $node) { - - switch($this->type) { + public function serialize(DAV\Server $server, \DOMElement $node) + { + switch ($this->type) { case self::TYPE_LOW : $type = 'low'; break; @@ -118,9 +118,9 @@ public function serialize(DAV\Server $server, \DOMElement $node) { * @param \DOMElement $node * @return void */ - public function serializeBody(DAV\Server $server, \DOMElement $node) { - - switch($this->type) { + public function serializeBody(DAV\Server $server, \DOMElement $node) + { + switch ($this->type) { case self::TYPE_LOW : $type = 'low'; break; @@ -161,8 +161,8 @@ public function serializeBody(DAV\Server $server, \DOMElement $node) { * * @return string */ - public function getId() { - + public function getId() + { return $this->id; } @@ -174,8 +174,8 @@ public function getId() { * * @return string */ - public function getETag() { - + public function getETag() + { return $this->etag; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Plugin.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Plugin.php index 2c29935b19..db61c6c7d8 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Plugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Plugin.php @@ -16,8 +16,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Plugin extends DAV\ServerPlugin { - +class Plugin extends DAV\ServerPlugin +{ /** * This is the official CalDAV namespace */ @@ -62,8 +62,8 @@ class Plugin extends DAV\ServerPlugin { * @param Schedule\IMip $imipHandler * @return void */ - public function setIMipHandler(Schedule\IMip $imipHandler) { - + public function setIMipHandler(Schedule\IMip $imipHandler) + { $this->imipHandler = $imipHandler; } @@ -78,8 +78,8 @@ public function setIMipHandler(Schedule\IMip $imipHandler) { * @param string $uri * @return array */ - public function getHTTPMethods($uri) { - + public function getHTTPMethods($uri) + { // The MKCALENDAR is only available on unmapped uri's, whose // parents extend IExtendedCollection list($parent, $name) = DAV\URLUtil::splitPath($uri); @@ -102,8 +102,8 @@ public function getHTTPMethods($uri) { * * @return array */ - public function getFeatures() { - + public function getFeatures() + { return array('calendar-access', 'calendar-proxy'); } @@ -116,8 +116,8 @@ public function getFeatures() { * * @return string */ - public function getPluginName() { - + public function getPluginName() + { return 'caldav'; } @@ -132,8 +132,8 @@ public function getPluginName() { * @param string $uri * @return array */ - public function getSupportedReportSet($uri) { - + public function getSupportedReportSet($uri) + { $node = $this->server->tree->getNodeForPath($uri); $reports = array(); @@ -154,8 +154,8 @@ public function getSupportedReportSet($uri) { * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { $this->server = $server; $server->subscribeEvent('unknownMethod',array($this,'unknownMethod')); @@ -216,8 +216,8 @@ public function initialize(DAV\Server $server) { * @param string $uri * @return bool */ - public function unknownMethod($method, $uri) { - + public function unknownMethod($method, $uri) + { switch ($method) { case 'MKCALENDAR' : $this->httpMkCalendar($uri); @@ -255,9 +255,9 @@ public function unknownMethod($method, $uri) { * @param \DOMNode $dom * @return bool */ - public function report($reportName,$dom) { - - switch($reportName) { + public function report($reportName,$dom) + { + switch ($reportName) { case '{'.self::NS_CALDAV.'}calendar-multiget' : $this->calendarMultiGetReport($dom); return false; @@ -280,8 +280,8 @@ public function report($reportName,$dom) { * @param string $uri * @return void */ - public function httpMkCalendar($uri) { - + public function httpMkCalendar($uri) + { // Due to unforgivable bugs in iCal, we're completely disabling MKCALENDAR support // for clients matching iCal in the user agent //$ua = $this->server->httpRequest->getHeader('User-Agent'); @@ -296,10 +296,10 @@ public function httpMkCalendar($uri) { $dom = DAV\XMLUtil::loadDOMDocument($body); - foreach($dom->firstChild->childNodes as $child) { + foreach ($dom->firstChild->childNodes as $child) { if (DAV\XMLUtil::toClarkNotation($child)!=='{DAV:}set') continue; - foreach(DAV\XMLUtil::parseProperties($child,$this->server->propertyMap) as $k=>$prop) { + foreach (DAV\XMLUtil::parseProperties($child,$this->server->propertyMap) as $k=>$prop) { $properties[$k] = $prop; } @@ -327,8 +327,8 @@ public function httpMkCalendar($uri) { * @param array $returnedProperties * @return void */ - public function beforeGetProperties($path, DAV\INode $node, &$requestedProperties, &$returnedProperties) { - + public function beforeGetProperties($path, DAV\INode $node, &$requestedProperties, &$returnedProperties) + { if ($node instanceof DAVACL\IPrincipal) { // calendar-home-set property @@ -375,7 +375,7 @@ public function beforeGetProperties($path, DAV\INode $node, &$requestedPropertie $readList = array(); $writeList = array(); - foreach($membership as $group) { + foreach ($membership as $group) { $groupNode = $this->server->tree->getNodeForPath($group); @@ -455,8 +455,8 @@ public function beforeGetProperties($path, DAV\INode $node, &$requestedPropertie * @param \DOMNode $dom * @return void */ - public function calendarMultiGetReport($dom) { - + public function calendarMultiGetReport($dom) + { $properties = array_keys(DAV\XMLUtil::parseProperties($dom->firstChild)); $hrefElems = $dom->getElementsByTagNameNS('urn:DAV','href'); @@ -469,7 +469,7 @@ public function calendarMultiGetReport($dom) { $expandElem = $expand->item(0); $start = $expandElem->getAttribute('start'); $end = $expandElem->getAttribute('end'); - if(!$start || !$end) { + if (!$start || !$end) { throw new DAV\Exception\BadRequest('The "start" and "end" attributes are required for the CALDAV:expand element'); } $start = VObject\DateTimeParser::parseDateTime($start); @@ -487,7 +487,7 @@ public function calendarMultiGetReport($dom) { } - foreach($hrefElems as $elem) { + foreach ($hrefElems as $elem) { $uri = $this->server->calculateUri($elem->nodeValue); list($objProps) = $this->server->getPropertiesForPath($uri,$properties); @@ -519,8 +519,8 @@ public function calendarMultiGetReport($dom) { * @param \DOMNode $dom * @return void */ - public function calendarQueryReport($dom) { - + public function calendarQueryReport($dom) + { $parser = new CalendarQueryParser($dom); $parser->parse(); @@ -590,7 +590,7 @@ public function calendarQueryReport($dom) { $nodePaths = $node->calendarQuery($parser->filters); - foreach($nodePaths as $path) { + foreach ($nodePaths as $path) { list($properties) = $this->server->getPropertiesForPath($this->server->getRequestUri() . '/' . $path, $parser->requestedProperties); @@ -624,12 +624,12 @@ public function calendarQueryReport($dom) { * @param \DOMNode $dom * @return void */ - protected function freeBusyQueryReport(\DOMNode $dom) { - + protected function freeBusyQueryReport(\DOMNode $dom) + { $start = null; $end = null; - foreach($dom->firstChild->childNodes as $childNode) { + foreach ($dom->firstChild->childNodes as $childNode) { $clark = DAV\XMLUtil::toClarkNotation($childNode); if ($clark == '{' . self::NS_CALDAV . '}time-range') { @@ -712,8 +712,8 @@ protected function freeBusyQueryReport(\DOMNode $dom) { * @param resource $data * @return void */ - public function beforeWriteContent($path, DAV\IFile $node, &$data) { - + public function beforeWriteContent($path, DAV\IFile $node, &$data) + { if (!$node instanceof ICalendarObject) return; @@ -732,8 +732,8 @@ public function beforeWriteContent($path, DAV\IFile $node, &$data) { * @param DAV\ICollection $parentNode * @return void */ - public function beforeCreateFile($path, &$data, DAV\ICollection $parentNode) { - + public function beforeCreateFile($path, &$data, DAV\ICollection $parentNode) + { if (!$parentNode instanceof Calendar) return; @@ -751,8 +751,8 @@ public function beforeCreateFile($path, &$data, DAV\ICollection $parentNode) { * @param string $path * @return void */ - public function beforeMethod($method, $path) { - + public function beforeMethod($method, $path) + { if ($method!=='GET') return; try { @@ -770,7 +770,7 @@ public function beforeMethod($method, $path) { $dom->formatOutput = true; $root = $dom->createElement('cs:notification'); - foreach($this->server->xmlNamespaces as $namespace => $prefix) { + foreach ($this->server->xmlNamespaces as $namespace => $prefix) { $root->setAttribute('xmlns:' . $prefix, $namespace); } @@ -795,8 +795,8 @@ public function beforeMethod($method, $path) { * @param string $path * @return void */ - protected function validateICalendar(&$data, $path) { - + protected function validateICalendar(&$data, $path) + { // If it's a stream, we convert it to a string first. if (is_resource($data)) { $data = stream_get_contents($data); @@ -826,8 +826,8 @@ protected function validateICalendar(&$data, $path) { $foundType = null; $foundUID = null; - foreach($vobj->getComponents() as $component) { - switch($component->name) { + foreach ($vobj->getComponents() as $component) { + switch ($component->name) { case 'VTIMEZONE' : continue 2; case 'VEVENT' : @@ -841,12 +841,12 @@ protected function validateICalendar(&$data, $path) { if (!isset($component->UID)) { throw new DAV\Exception\BadRequest('Every ' . $component->name . ' component must have an UID'); } - $foundUID = (string)$component->UID; + $foundUID = (string) $component->UID; } else { if ($foundType !== $component->name) { throw new DAV\Exception\BadRequest('A calendar object must only contain 1 component. We found a ' . $component->name . ' as well as a ' . $foundType); } - if ($foundUID !== (string)$component->UID) { + if ($foundUID !== (string) $component->UID) { throw new DAV\Exception\BadRequest('Every ' . $component->name . ' in this object must have identical UIDs'); } } @@ -876,8 +876,8 @@ protected function validateICalendar(&$data, $path) { * @param string $outboxUri * @return void */ - public function outboxRequest(Schedule\IOutbox $outboxNode, $outboxUri) { - + public function outboxRequest(Schedule\IOutbox $outboxNode, $outboxUri) + { // Parsing the request body try { $vObject = VObject\Reader::read($this->server->httpRequest->getBody(true)); @@ -889,7 +889,7 @@ public function outboxRequest(Schedule\IOutbox $outboxNode, $outboxUri) { // component. The combination of both determines what type of request // this is. $componentType = null; - foreach($vObject->getComponents() as $component) { + foreach ($vObject->getComponents() as $component) { if ($component->name !== 'VTIMEZONE') { $componentType = $component->name; break; @@ -900,7 +900,7 @@ public function outboxRequest(Schedule\IOutbox $outboxNode, $outboxUri) { } // Validating the METHOD - $method = strtoupper((string)$vObject->METHOD); + $method = strtoupper((string) $vObject->METHOD); if (!$method) { throw new DAV\Exception\BadRequest('A METHOD property must be specified in iTIP messages'); } @@ -936,8 +936,8 @@ public function outboxRequest(Schedule\IOutbox $outboxNode, $outboxUri) { * * @return void */ - protected function handleEventNotification(Schedule\IOutbox $outboxNode, VObject\Component $vObject) { - + protected function handleEventNotification(Schedule\IOutbox $outboxNode, VObject\Component $vObject) + { $originator = $this->server->httpRequest->getHeader('Originator'); $recipients = $this->server->httpRequest->getHeader('Recipient'); @@ -949,7 +949,7 @@ protected function handleEventNotification(Schedule\IOutbox $outboxNode, VObject } $recipients = explode(',',$recipients); - foreach($recipients as $k=>$recipient) { + foreach ($recipients as $k=>$recipient) { $recipient = trim($recipient); if (!preg_match('/^mailto:(.*)@(.*)$/i', $recipient)) { @@ -972,7 +972,7 @@ protected function handleEventNotification(Schedule\IOutbox $outboxNode, VObject } $found = false; - foreach($addresses as $address) { + foreach ($addresses as $address) { // Trimming the / on both sides, just in case.. if (rtrim(strtolower($originator),'/') === rtrim(strtolower($address),'/')) { @@ -989,7 +989,7 @@ protected function handleEventNotification(Schedule\IOutbox $outboxNode, VObject // If the Originator header was a url, and not a mailto: address.. // we're going to try to pull the mailto: from the vobject body. if (strtolower(substr($originator,0,7)) !== 'mailto:') { - $originator = (string)$vObject->VEVENT->ORGANIZER; + $originator = (string) $vObject->VEVENT->ORGANIZER; } if (strtolower(substr($originator,0,7)) !== 'mailto:') { @@ -1024,10 +1024,10 @@ protected function handleEventNotification(Schedule\IOutbox $outboxNode, VObject * @param array $recipients * @param VObject\Component $vObject * @param string $principal Principal url - * @return array + * @return array */ - protected function iMIPMessage($originator, array $recipients, VObject\Component $vObject, $principal) { - + protected function iMIPMessage($originator, array $recipients, VObject\Component $vObject, $principal) + { if (!$this->imipHandler) { $resultStatus = '5.2;This server does not support this operation'; } else { @@ -1036,7 +1036,7 @@ protected function iMIPMessage($originator, array $recipients, VObject\Component } $result = array(); - foreach($recipients as $recipient) { + foreach ($recipients as $recipient) { $result[$recipient] = $resultStatus; } @@ -1054,20 +1054,20 @@ protected function iMIPMessage($originator, array $recipients, VObject\Component * @param array $recipients * @return string */ - public function generateScheduleResponse(array $recipients) { - + public function generateScheduleResponse(array $recipients) + { $dom = new \DOMDocument('1.0','utf-8'); $dom->formatOutput = true; $xscheduleResponse = $dom->createElement('cal:schedule-response'); $dom->appendChild($xscheduleResponse); - foreach($this->server->xmlNamespaces as $namespace=>$prefix) { + foreach ($this->server->xmlNamespaces as $namespace=>$prefix) { $xscheduleResponse->setAttribute('xmlns:' . $prefix, $namespace); } - foreach($recipients as $recipient=>$status) { + foreach ($recipients as $recipient=>$status) { $xresponse = $dom->createElement('cal:response'); $xrecipient = $dom->createElement('cal:recipient'); @@ -1094,12 +1094,12 @@ public function generateScheduleResponse(array $recipients) { * @param string $request * @return string */ - protected function handleFreeBusyRequest(Schedule\IOutbox $outbox, VObject\Component $vObject) { - + protected function handleFreeBusyRequest(Schedule\IOutbox $outbox, VObject\Component $vObject) + { $vFreeBusy = $vObject->VFREEBUSY; $organizer = $vFreeBusy->organizer; - $organizer = (string)$organizer; + $organizer = (string) $organizer; // Validating if the organizer matches the owner of the inbox. $owner = $outbox->getOwner(); @@ -1118,8 +1118,8 @@ protected function handleFreeBusyRequest(Schedule\IOutbox $outbox, VObject\Compo } $attendees = array(); - foreach($vFreeBusy->ATTENDEE as $attendee) { - $attendees[]= (string)$attendee; + foreach ($vFreeBusy->ATTENDEE as $attendee) { + $attendees[]= (string) $attendee; } @@ -1131,21 +1131,21 @@ protected function handleFreeBusyRequest(Schedule\IOutbox $outbox, VObject\Compo $endRange = $vFreeBusy->DTEND->getDateTime(); $results = array(); - foreach($attendees as $attendee) { + foreach ($attendees as $attendee) { $results[] = $this->getFreeBusyForEmail($attendee, $startRange, $endRange, $vObject); } $dom = new \DOMDocument('1.0','utf-8'); $dom->formatOutput = true; $scheduleResponse = $dom->createElement('cal:schedule-response'); - foreach($this->server->xmlNamespaces as $namespace=>$prefix) { + foreach ($this->server->xmlNamespaces as $namespace=>$prefix) { $scheduleResponse->setAttribute('xmlns:' . $prefix,$namespace); } $dom->appendChild($scheduleResponse); - foreach($results as $result) { + foreach ($results as $result) { $response = $dom->createElement('cal:response'); $recipient = $dom->createElement('cal:recipient'); @@ -1193,8 +1193,8 @@ protected function handleFreeBusyRequest(Schedule\IOutbox $outbox, VObject\Compo * @param VObject\Component $request * @return array */ - protected function getFreeBusyForEmail($email, \DateTime $start, \DateTime $end, VObject\Component $request) { - + protected function getFreeBusyForEmail($email, \DateTime $start, \DateTime $end, VObject\Component $request) + { $caldavNS = '{' . Plugin::NS_CALDAV . '}'; $aclPlugin = $this->server->getPlugin('acl'); @@ -1225,7 +1225,7 @@ protected function getFreeBusyForEmail($email, \DateTime $start, \DateTime $end, // Grabbing the calendar list $objects = array(); - foreach($this->server->tree->getNodeForPath($homeSet)->getChildren() as $node) { + foreach ($this->server->tree->getNodeForPath($homeSet)->getChildren() as $node) { if (!$node instanceof ICalendar) { continue; } @@ -1274,7 +1274,7 @@ protected function getFreeBusyForEmail($email, \DateTime $start, \DateTime $end, $result = $generator->getResult(); $vcalendar->VFREEBUSY->ATTENDEE = 'mailto:' . $email; - $vcalendar->VFREEBUSY->UID = (string)$request->VFREEBUSY->UID; + $vcalendar->VFREEBUSY->UID = (string) $request->VFREEBUSY->UID; $vcalendar->VFREEBUSY->ORGANIZER = clone $request->VFREEBUSY->ORGANIZER; return array( @@ -1293,8 +1293,8 @@ protected function getFreeBusyForEmail($email, \DateTime $start, \DateTime $end, * @param string $output * @return bool */ - public function htmlActionsPanel(DAV\INode $node, &$output) { - + public function htmlActionsPanel(DAV\INode $node, &$output) + { if (!$node instanceof UserCalendars) return; @@ -1320,8 +1320,8 @@ public function htmlActionsPanel(DAV\INode $node, &$output) { * @param array $postVars * @return bool */ - public function browserPostAction($uri, $action, array $postVars) { - + public function browserPostAction($uri, $action, array $postVars) + { if ($action!=='mkcalendar') return; diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/Collection.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/Collection.php index b4a20998c4..2f502ac5e2 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/Collection.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/Collection.php @@ -12,19 +12,19 @@ * specification. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Collection extends DAVACL\AbstractPrincipalCollection { - +class Collection extends DAVACL\AbstractPrincipalCollection +{ /** * Returns a child object based on principal information * * @param array $principalInfo * @return User */ - public function getChildForPrincipal(array $principalInfo) { - + public function getChildForPrincipal(array $principalInfo) + { return new User($this->principalBackend, $principalInfo); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/IProxyRead.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/IProxyRead.php index 756715af36..c02679fb29 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/IProxyRead.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/IProxyRead.php @@ -14,6 +14,6 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IProxyRead extends DAVACL\IPrincipal { - +interface IProxyRead extends DAVACL\IPrincipal +{ } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/IProxyWrite.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/IProxyWrite.php index 59e4878996..c719fa4a7b 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/IProxyWrite.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/IProxyWrite.php @@ -14,6 +14,6 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IProxyWrite extends DAVACL\IPrincipal { - +interface IProxyWrite extends DAVACL\IPrincipal +{ } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/ProxyRead.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/ProxyRead.php index 080f848d96..bb10cdce2e 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/ProxyRead.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/ProxyRead.php @@ -12,11 +12,11 @@ * instantiated by User. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class ProxyRead implements IProxyRead { - +class ProxyRead implements IProxyRead +{ /** * Principal information from the parent principal. * @@ -39,8 +39,8 @@ class ProxyRead implements IProxyRead { * @param DAVACL\PrincipalBackend\BackendInterface $principalBackend * @param array $principalInfo */ - public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, array $principalInfo) { - + public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, array $principalInfo) + { $this->principalInfo = $principalInfo; $this->principalBackend = $principalBackend; @@ -51,8 +51,8 @@ public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalB * * @return string */ - public function getName() { - + public function getName() + { return 'calendar-proxy-read'; } @@ -62,8 +62,8 @@ public function getName() { * * @return null */ - public function getLastModified() { - + public function getLastModified() + { return null; } @@ -74,8 +74,8 @@ public function getLastModified() { * @throws DAV\Exception\Forbidden * @return void */ - public function delete() { - + public function delete() + { throw new DAV\Exception\Forbidden('Permission denied to delete node'); } @@ -87,8 +87,8 @@ public function delete() { * @param string $name The new name * @return void */ - public function setName($name) { - + public function setName($name) + { throw new DAV\Exception\Forbidden('Permission denied to rename file'); } @@ -101,8 +101,8 @@ public function setName($name) { * * @return array */ - public function getAlternateUriSet() { - + public function getAlternateUriSet() + { return array(); } @@ -112,8 +112,8 @@ public function getAlternateUriSet() { * * @return string */ - public function getPrincipalUrl() { - + public function getPrincipalUrl() + { return $this->principalInfo['uri'] . '/' . $this->getName(); } @@ -126,8 +126,8 @@ public function getPrincipalUrl() { * * @return array */ - public function getGroupMemberSet() { - + public function getGroupMemberSet() + { return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl()); } @@ -140,8 +140,8 @@ public function getGroupMemberSet() { * * @return array */ - public function getGroupMembership() { - + public function getGroupMembership() + { return $this->principalBackend->getGroupMembership($this->getPrincipalUrl()); } @@ -157,8 +157,8 @@ public function getGroupMembership() { * @param array $principals * @return void */ - public function setGroupMemberSet(array $principals) { - + public function setGroupMemberSet(array $principals) + { $this->principalBackend->setGroupMemberSet($this->getPrincipalUrl(), $principals); } @@ -171,8 +171,8 @@ public function setGroupMemberSet(array $principals) { * * @return string */ - public function getDisplayName() { - + public function getDisplayName() + { return $this->getName(); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/ProxyWrite.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/ProxyWrite.php index c9332b3fc6..cdf82344da 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/ProxyWrite.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/ProxyWrite.php @@ -12,11 +12,11 @@ * instantiated by User. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class ProxyWrite implements IProxyWrite { - +class ProxyWrite implements IProxyWrite +{ /** * Parent principal information * @@ -39,8 +39,8 @@ class ProxyWrite implements IProxyWrite { * @param DAVACL\PrincipalBackend\BackendInterface $principalBackend * @param array $principalInfo */ - public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, array $principalInfo) { - + public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend, array $principalInfo) + { $this->principalInfo = $principalInfo; $this->principalBackend = $principalBackend; @@ -51,8 +51,8 @@ public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalB * * @return string */ - public function getName() { - + public function getName() + { return 'calendar-proxy-write'; } @@ -62,8 +62,8 @@ public function getName() { * * @return null */ - public function getLastModified() { - + public function getLastModified() + { return null; } @@ -74,8 +74,8 @@ public function getLastModified() { * @throws DAV\Exception\Forbidden * @return void */ - public function delete() { - + public function delete() + { throw new DAV\Exception\Forbidden('Permission denied to delete node'); } @@ -87,8 +87,8 @@ public function delete() { * @param string $name The new name * @return void */ - public function setName($name) { - + public function setName($name) + { throw new DAV\Exception\Forbidden('Permission denied to rename file'); } @@ -101,8 +101,8 @@ public function setName($name) { * * @return array */ - public function getAlternateUriSet() { - + public function getAlternateUriSet() + { return array(); } @@ -112,8 +112,8 @@ public function getAlternateUriSet() { * * @return string */ - public function getPrincipalUrl() { - + public function getPrincipalUrl() + { return $this->principalInfo['uri'] . '/' . $this->getName(); } @@ -126,8 +126,8 @@ public function getPrincipalUrl() { * * @return array */ - public function getGroupMemberSet() { - + public function getGroupMemberSet() + { return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl()); } @@ -140,8 +140,8 @@ public function getGroupMemberSet() { * * @return array */ - public function getGroupMembership() { - + public function getGroupMembership() + { return $this->principalBackend->getGroupMembership($this->getPrincipalUrl()); } @@ -157,8 +157,8 @@ public function getGroupMembership() { * @param array $principals * @return void */ - public function setGroupMemberSet(array $principals) { - + public function setGroupMemberSet(array $principals) + { $this->principalBackend->setGroupMemberSet($this->getPrincipalUrl(), $principals); } @@ -171,8 +171,8 @@ public function setGroupMemberSet(array $principals) { * * @return string */ - public function getDisplayName() { - + public function getDisplayName() + { return $this->getName(); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/User.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/User.php index eee2554572..b6536c3869 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/User.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Principal/User.php @@ -12,11 +12,11 @@ * principals. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class User extends DAVACL\Principal implements DAV\ICollection { - +class User extends DAVACL\Principal implements DAV\ICollection +{ /** * Creates a new file in the directory * @@ -25,8 +25,8 @@ class User extends DAVACL\Principal implements DAV\ICollection { * @throws DAV\Exception\Forbidden * @return void */ - public function createFile($name, $data = null) { - + public function createFile($name, $data = null) + { throw new DAV\Exception\Forbidden('Permission denied to create file (filename ' . $name . ')'); } @@ -38,8 +38,8 @@ public function createFile($name, $data = null) { * @throws DAV\Exception\Forbidden * @return void */ - public function createDirectory($name) { - + public function createDirectory($name) + { throw new DAV\Exception\Forbidden('Permission denied to create directory'); } @@ -50,8 +50,8 @@ public function createDirectory($name) { * @param string $name * @return DAV\INode */ - public function getChild($name) { - + public function getChild($name) + { $principal = $this->principalBackend->getPrincipalByPath($this->getPrincipalURL() . '/' . $name); if (!$principal) { throw new DAV\Exception\NotFound('Node with name ' . $name . ' was not found'); @@ -71,8 +71,8 @@ public function getChild($name) { * * @return DAV\INode[] */ - public function getChildren() { - + public function getChildren() + { $r = array(); if ($this->principalBackend->getPrincipalByPath($this->getPrincipalURL() . '/calendar-proxy-read')) { $r[] = new ProxyRead($this->principalBackend, $this->principalProperties); @@ -91,8 +91,8 @@ public function getChildren() { * @param string $name * @return bool */ - public function childExists($name) { - + public function childExists($name) + { try { $this->getChild($name); return true; @@ -114,8 +114,8 @@ public function childExists($name) { * * @return array */ - public function getACL() { - + public function getACL() + { $acl = parent::getACL(); $acl[] = array( 'privilege' => '{DAV:}read', diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/AllowedSharingModes.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/AllowedSharingModes.php index 1db6af7e4d..4eb15a0c2b 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/AllowedSharingModes.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/AllowedSharingModes.php @@ -20,8 +20,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class AllowedSharingModes extends DAV\Property { - +class AllowedSharingModes extends DAV\Property +{ /** * Whether or not a calendar can be shared with another user * @@ -43,8 +43,8 @@ class AllowedSharingModes extends DAV\Property { * @param bool $canBePublished * @return void */ - public function __construct($canBeShared, $canBePublished) { - + public function __construct($canBeShared, $canBePublished) + { $this->canBeShared = $canBeShared; $this->canBePublished = $canBePublished; @@ -57,8 +57,8 @@ public function __construct($canBeShared, $canBePublished) { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server, \DOMElement $node) { - + public function serialize(DAV\Server $server, \DOMElement $node) + { $doc = $node->ownerDocument; if ($this->canBeShared) { $xcomp = $doc->createElement('cs:can-be-shared'); diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/Invite.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/Invite.php index 137cf7302b..d0eb833b06 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/Invite.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/Invite.php @@ -18,8 +18,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Invite extends DAV\Property { - +class Invite extends DAV\Property +{ /** * The list of users a calendar has been shared to. * @@ -61,8 +61,8 @@ class Invite extends DAV\Property { * * @param array $users */ - public function __construct(array $users, array $organizer = null) { - + public function __construct(array $users, array $organizer = null) + { $this->users = $users; $this->organizer = $organizer; @@ -73,8 +73,8 @@ public function __construct(array $users, array $organizer = null) { * * @return array */ - public function getValue() { - + public function getValue() + { return $this->users; } @@ -86,8 +86,8 @@ public function getValue() { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server,\DOMElement $node) { - + public function serialize(DAV\Server $server,\DOMElement $node) + { $doc = $node->ownerDocument; if (!is_null($this->organizer)) { @@ -119,7 +119,7 @@ public function serialize(DAV\Server $server,\DOMElement $node) { } - foreach($this->users as $user) { + foreach ($this->users as $user) { $xuser = $doc->createElement('cs:user'); @@ -133,7 +133,7 @@ public function serialize(DAV\Server $server,\DOMElement $node) { $xuser->appendChild($commonName); } - switch($user['status']) { + switch ($user['status']) { case SharingPlugin::STATUS_ACCEPTED : $status = $doc->createElement('cs:invite-accepted'); @@ -188,15 +188,15 @@ public function serialize(DAV\Server $server,\DOMElement $node) { * @param \DOMElement $prop * @return DAV\IProperty */ - static function unserialize(\DOMElement $prop) { - + public static function unserialize(\DOMElement $prop) + { $xpath = new \DOMXPath($prop->ownerDocument); $xpath->registerNamespace('cs', CalDAV\Plugin::NS_CALENDARSERVER); $xpath->registerNamespace('d', 'urn:DAV'); $users = array(); - foreach($xpath->query('cs:user', $prop) as $user) { + foreach ($xpath->query('cs:user', $prop) as $user) { $status = null; if ($xpath->evaluate('boolean(cs:invite-accepted)', $user)) { diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/ScheduleCalendarTransp.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/ScheduleCalendarTransp.php index 9b03ba48b7..051f6bfb22 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/ScheduleCalendarTransp.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/ScheduleCalendarTransp.php @@ -19,8 +19,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class ScheduleCalendarTransp extends DAV\Property { - +class ScheduleCalendarTransp extends DAV\Property +{ const TRANSPARENT = 'transparent'; const OPAQUE = 'opaque'; @@ -31,8 +31,8 @@ class ScheduleCalendarTransp extends DAV\Property { * * @param string $value */ - public function __construct($value) { - + public function __construct($value) + { if ($value !== self::TRANSPARENT && $value !== self::OPAQUE) { throw new \InvalidArgumentException('The value must either be specified as "transparent" or "opaque"'); } @@ -45,8 +45,8 @@ public function __construct($value) { * * @return string */ - public function getValue() { - + public function getValue() + { return $this->value; } @@ -58,10 +58,10 @@ public function getValue() { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server,\DOMElement $node) { - + public function serialize(DAV\Server $server,\DOMElement $node) + { $doc = $node->ownerDocument; - switch($this->value) { + switch ($this->value) { case self::TRANSPARENT : $xval = $doc->createElement('cal:transparent'); break; @@ -80,11 +80,11 @@ public function serialize(DAV\Server $server,\DOMElement $node) { * @param \DOMElement $node * @return ScheduleCalendarTransp */ - static function unserialize(\DOMElement $node) { - + public static function unserialize(\DOMElement $node) + { $value = null; - foreach($node->childNodes as $childNode) { - switch(DAV\XMLUtil::toClarkNotation($childNode)) { + foreach ($node->childNodes as $childNode) { + switch (DAV\XMLUtil::toClarkNotation($childNode)) { case '{' . CalDAV\Plugin::NS_CALDAV . '}opaque' : $value = self::OPAQUE; break; diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php index 2a9456dc7d..2b9dc45fc0 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php @@ -13,11 +13,11 @@ * such as VEVENT, VTODO * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SupportedCalendarComponentSet extends DAV\Property { - +class SupportedCalendarComponentSet extends DAV\Property +{ /** * List of supported components, such as "VEVENT, VTODO" * @@ -30,8 +30,8 @@ class SupportedCalendarComponentSet extends DAV\Property { * * @param array $components */ - public function __construct(array $components) { - + public function __construct(array $components) + { $this->components = $components; } @@ -41,8 +41,8 @@ public function __construct(array $components) { * * @return array */ - public function getValue() { - + public function getValue() + { return $this->components; } @@ -54,10 +54,10 @@ public function getValue() { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server,\DOMElement $node) { - + public function serialize(DAV\Server $server,\DOMElement $node) + { $doc = $node->ownerDocument; - foreach($this->components as $component) { + foreach ($this->components as $component) { $xcomp = $doc->createElement('cal:comp'); $xcomp->setAttribute('name',$component); @@ -73,10 +73,10 @@ public function serialize(DAV\Server $server,\DOMElement $node) { * @param \DOMElement $node * @return Property_SupportedCalendarComponentSet */ - static function unserialize(\DOMElement $node) { - + public static function unserialize(\DOMElement $node) + { $components = array(); - foreach($node->childNodes as $childNode) { + foreach ($node->childNodes as $childNode) { if (DAV\XMLUtil::toClarkNotation($childNode)==='{' . CalDAV\Plugin::NS_CALDAV . '}comp') { $components[] = $childNode->getAttribute('name'); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCalendarData.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCalendarData.php index a3a62a1aaa..0923cd832a 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCalendarData.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCalendarData.php @@ -12,11 +12,11 @@ * so the value is currently hardcoded. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SupportedCalendarData extends DAV\Property { - +class SupportedCalendarData extends DAV\Property +{ /** * Serializes the property in a DOMDocument * @@ -24,8 +24,8 @@ class SupportedCalendarData extends DAV\Property { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server,\DOMElement $node) { - + public function serialize(DAV\Server $server,\DOMElement $node) + { $doc = $node->ownerDocument; $prefix = isset($server->xmlNamespaces[Plugin::NS_CALDAV])?$server->xmlNamespaces[Plugin::NS_CALDAV]:'cal'; diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCollationSet.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCollationSet.php index ca0671a531..bb0caea506 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCollationSet.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Property/SupportedCollationSet.php @@ -10,11 +10,11 @@ * in the CalDAV namespace. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SupportedCollationSet extends DAV\Property { - +class SupportedCollationSet extends DAV\Property +{ /** * Serializes the property in a DOM document * @@ -22,8 +22,8 @@ class SupportedCollationSet extends DAV\Property { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server,\DOMElement $node) { - + public function serialize(DAV\Server $server,\DOMElement $node) + { $doc = $node->ownerDocument; $prefix = $node->lookupPrefix('urn:ietf:params:xml:ns:caldav'); diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/IMip.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/IMip.php index ef464bfc23..c9d88b2fb3 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/IMip.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/IMip.php @@ -19,8 +19,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class IMip { - +class IMip +{ /** * Email address used in From: header. * @@ -36,8 +36,8 @@ class IMip { * generally be some kind of no-reply email * address you own. */ - public function __construct($senderEmail) { - + public function __construct($senderEmail) + { $this->senderEmail = $senderEmail; } @@ -51,15 +51,15 @@ public function __construct($senderEmail) { * @param string $principal Principal Url of the originator * @return void */ - public function sendMessage($originator, array $recipients, VObject\Component $vObject, $principal) { - - foreach($recipients as $recipient) { + public function sendMessage($originator, array $recipients, VObject\Component $vObject, $principal) + { + foreach ($recipients as $recipient) { $to = $recipient; $replyTo = $originator; $subject = 'SabreDAV iTIP message'; - switch(strtoupper($vObject->METHOD)) { + switch (strtoupper($vObject->METHOD)) { case 'REPLY' : $subject = 'Response for: ' . $vObject->VEVENT->SUMMARY; break; @@ -74,7 +74,7 @@ public function sendMessage($originator, array $recipients, VObject\Component $v $headers = array(); $headers[] = 'Reply-To: ' . $replyTo; $headers[] = 'From: ' . $this->senderEmail; - $headers[] = 'Content-Type: text/calendar; method=' . (string)$vObject->method . '; charset=utf-8'; + $headers[] = 'Content-Type: text/calendar; method=' . (string) $vObject->method . '; charset=utf-8'; if (DAV\Server::$exposeVersion) { $headers[] = 'X-Sabre-Version: ' . DAV\Version::VERSION . '-' . DAV\Version::STABILITY; } @@ -99,9 +99,8 @@ public function sendMessage($originator, array $recipients, VObject\Component $v * @param array $headers List of headers * @return void */ - protected function mail($to, $subject, $body, array $headers) { - - + protected function mail($to, $subject, $body, array $headers) + { mail($to, $subject, $body, implode("\r\n", $headers)); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/IOutbox.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/IOutbox.php index 14e8abf31c..7e1c02eaab 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/IOutbox.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/IOutbox.php @@ -10,7 +10,6 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IOutbox extends \Sabre\DAV\ICollection, \Sabre\DAVACL\IACL { - - +interface IOutbox extends \Sabre\DAV\ICollection, \Sabre\DAVACL\IACL +{ } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/Outbox.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/Outbox.php index a1848ecdff..f6c77ebaeb 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/Outbox.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Schedule/Outbox.php @@ -16,8 +16,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Outbox extends DAV\Collection implements IOutbox { - +class Outbox extends DAV\Collection implements IOutbox +{ /** * The principal Uri * @@ -30,8 +30,8 @@ class Outbox extends DAV\Collection implements IOutbox { * * @param string $principalUri */ - public function __construct($principalUri) { - + public function __construct($principalUri) + { $this->principalUri = $principalUri; } @@ -43,8 +43,8 @@ public function __construct($principalUri) { * * @return string */ - public function getName() { - + public function getName() + { return 'outbox'; } @@ -54,8 +54,8 @@ public function getName() { * * @return \Sabre\DAV\INode[] */ - public function getChildren() { - + public function getChildren() + { return array(); } @@ -67,8 +67,8 @@ public function getChildren() { * * @return string|null */ - public function getOwner() { - + public function getOwner() + { return $this->principalUri; } @@ -80,8 +80,8 @@ public function getOwner() { * * @return string|null */ - public function getGroup() { - + public function getGroup() + { return null; } @@ -98,8 +98,8 @@ public function getGroup() { * * @return array */ - public function getACL() { - + public function getACL() + { return array( array( 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy', @@ -128,8 +128,8 @@ public function getACL() { * @param array $acl * @return void */ - public function setACL(array $acl) { - + public function setACL(array $acl) + { throw new DAV\Exception\MethodNotAllowed('You\'re not allowed to update the ACL'); } @@ -146,8 +146,8 @@ public function setACL(array $acl) { * * @return array|null */ - public function getSupportedPrivilegeSet() { - + public function getSupportedPrivilegeSet() + { $default = DAVACL\Plugin::getDefaultSupportedPrivilegeSet(); $default['aggregates'][] = array( 'privilege' => '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-query-freebusy', diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ShareableCalendar.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ShareableCalendar.php index db4867bb0a..ba826adc8d 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ShareableCalendar.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/ShareableCalendar.php @@ -10,8 +10,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class ShareableCalendar extends Calendar implements IShareableCalendar { - +class ShareableCalendar extends Calendar implements IShareableCalendar +{ /** * Updates the list of shares. * @@ -30,8 +30,8 @@ class ShareableCalendar extends Calendar implements IShareableCalendar { * @param array $remove * @return void */ - public function updateShares(array $add, array $remove) { - + public function updateShares(array $add, array $remove) + { $this->caldavBackend->updateShares($this->calendarInfo['id'], $add, $remove); } @@ -48,8 +48,8 @@ public function updateShares(array $add, array $remove) { * * @return array */ - public function getShares() { - + public function getShares() + { return $this->caldavBackend->getShares($this->calendarInfo['id']); } @@ -63,8 +63,8 @@ public function getShares() { * @param bool $value * @return void */ - public function setPublishStatus($value) { - + public function setPublishStatus($value) + { $this->caldavBackend->setPublishStatus($this->calendarInfo['id'], $value); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/SharedCalendar.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/SharedCalendar.php index 22b26fba22..013ad36be6 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/SharedCalendar.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/SharedCalendar.php @@ -11,22 +11,22 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SharedCalendar extends Calendar implements ISharedCalendar { - +class SharedCalendar extends Calendar implements ISharedCalendar +{ /** * Constructor * * @param Backend\BackendInterface $caldavBackend * @param array $calendarInfo */ - public function __construct(Backend\BackendInterface $caldavBackend, $calendarInfo) { - + public function __construct(Backend\BackendInterface $caldavBackend, $calendarInfo) + { $required = array( '{http://calendarserver.org/ns/}shared-url', '{http://sabredav.org/ns}owner-principal', '{http://sabredav.org/ns}read-only', ); - foreach($required as $r) { + foreach ($required as $r) { if (!isset($calendarInfo[$r])) { throw new \InvalidArgumentException('The ' . $r . ' property must be specified for SharedCalendar(s)'); } @@ -42,8 +42,8 @@ public function __construct(Backend\BackendInterface $caldavBackend, $calendarIn * * @return string */ - public function getSharedUrl() { - + public function getSharedUrl() + { return $this->calendarInfo['{http://calendarserver.org/ns/}shared-url']; } @@ -55,8 +55,8 @@ public function getSharedUrl() { * * @return string|null */ - public function getOwner() { - + public function getOwner() + { return $this->calendarInfo['{http://sabredav.org/ns}owner-principal']; } @@ -73,8 +73,8 @@ public function getOwner() { * * @return array */ - public function getACL() { - + public function getACL() + { // The top-level ACL only contains access information for the true // owner of the calendar, so we need to add the information for the // sharee. @@ -107,8 +107,8 @@ public function getACL() { * * @return array */ - public function getShares() { - + public function getShares() + { return $this->caldavBackend->getShares($this->calendarInfo['id']); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/SharingPlugin.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/SharingPlugin.php index fde50d48ad..caab76c1b7 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/SharingPlugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/SharingPlugin.php @@ -20,8 +20,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SharingPlugin extends DAV\ServerPlugin { - +class SharingPlugin extends DAV\ServerPlugin +{ /** * These are the various status constants used by sharing-messages. */ @@ -46,8 +46,8 @@ class SharingPlugin extends DAV\ServerPlugin { * * @return array */ - public function getFeatures() { - + public function getFeatures() + { return array('calendarserver-sharing'); } @@ -60,8 +60,8 @@ public function getFeatures() { * * @return string */ - public function getPluginName() { - + public function getPluginName() + { return 'caldav-sharing'; } @@ -77,8 +77,8 @@ public function getPluginName() { * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { $this->server = $server; $server->resourceTypeMapping['Sabre\\CalDAV\\ISharedCalendar'] = '{' . Plugin::NS_CALENDARSERVER . '}shared'; @@ -108,8 +108,8 @@ public function initialize(DAV\Server $server) { * @param array $returnedProperties * @return void */ - public function beforeGetProperties($path, DAV\INode $node, &$requestedProperties, &$returnedProperties) { - + public function beforeGetProperties($path, DAV\INode $node, &$requestedProperties, &$returnedProperties) + { if ($node instanceof IShareableCalendar) { if (($index = array_search('{' . Plugin::NS_CALENDARSERVER . '}invite', $requestedProperties))!==false) { @@ -187,8 +187,8 @@ public function beforeGetProperties($path, DAV\INode $node, &$requestedPropertie * @param DAV\INode $node * @return void */ - public function afterGetProperties($path, &$properties, DAV\INode $node) { - + public function afterGetProperties($path, &$properties, DAV\INode $node) + { if ($node instanceof IShareableCalendar) { if (isset($properties[200]['{DAV:}resourcetype'])) { if (count($node->getShares())>0) { @@ -223,8 +223,8 @@ public function afterGetProperties($path, &$properties, DAV\INode $node) { * @param DAV\INode $node * @return void */ - public function updateProperties(array &$mutations, array &$result, DAV\INode $node) { - + public function updateProperties(array &$mutations, array &$result, DAV\INode $node) + { if (!$node instanceof IShareableCalendar) return; @@ -237,7 +237,7 @@ public function updateProperties(array &$mutations, array &$result, DAV\INode $n $shares = $node->getShares(); $remove = array(); - foreach($shares as $share) { + foreach ($shares as $share) { $remove[] = $share['href']; } $node->updateShares(array(), $remove); @@ -260,8 +260,8 @@ public function updateProperties(array &$mutations, array &$result, DAV\INode $n * @param string $uri * @return null|bool */ - public function unknownMethod($method, $uri) { - + public function unknownMethod($method, $uri) + { if ($method!=='POST') { return; } @@ -293,7 +293,7 @@ public function unknownMethod($method, $uri) { $documentType = DAV\XMLUtil::toClarkNotation($dom->firstChild); - switch($documentType) { + switch ($documentType) { // Dealing with the 'share' document, which modified invitees on a // calendar. @@ -361,7 +361,7 @@ public function unknownMethod($method, $uri) { $dom->formatOutput = true; $root = $dom->createElement('cs:shared-as'); - foreach($this->server->xmlNamespaces as $namespace => $prefix) { + foreach ($this->server->xmlNamespaces as $namespace => $prefix) { $root->setAttribute('xmlns:' . $prefix, $namespace); } @@ -454,8 +454,8 @@ public function unknownMethod($method, $uri) { * @param \DOMDocument $dom * @return array */ - protected function parseShareRequest(\DOMDocument $dom) { - + protected function parseShareRequest(\DOMDocument $dom) + { $xpath = new \DOMXPath($dom); $xpath->registerNamespace('cs', Plugin::NS_CALENDARSERVER); $xpath->registerNamespace('d', 'urn:DAV'); @@ -463,7 +463,7 @@ protected function parseShareRequest(\DOMDocument $dom) { $set = array(); $elems = $xpath->query('cs:set'); - for($i=0; $i < $elems->length; $i++) { + for ($i=0; $i < $elems->length; $i++) { $xset = $elems->item($i); $set[] = array( @@ -478,7 +478,7 @@ protected function parseShareRequest(\DOMDocument $dom) { $remove = array(); $elems = $xpath->query('cs:remove'); - for($i=0; $i < $elems->length; $i++) { + for ($i=0; $i < $elems->length; $i++) { $xremove = $elems->item($i); $remove[] = $xpath->evaluate('string(d:href)', $xremove); @@ -502,8 +502,8 @@ protected function parseShareRequest(\DOMDocument $dom) { * @param \DOMDocument $dom * @return array */ - protected function parseInviteReplyRequest(\DOMDocument $dom) { - + protected function parseInviteReplyRequest(\DOMDocument $dom) + { $xpath = new \DOMXPath($dom); $xpath->registerNamespace('cs', Plugin::NS_CALENDARSERVER); $xpath->registerNamespace('d', 'urn:DAV'); diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/UserCalendars.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/UserCalendars.php index d03fb77a3c..02da425382 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/UserCalendars.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/UserCalendars.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class UserCalendars implements DAV\IExtendedCollection, DAVACL\IACL { - +class UserCalendars implements DAV\IExtendedCollection, DAVACL\IACL +{ /** * CalDAV backend * @@ -34,8 +34,8 @@ class UserCalendars implements DAV\IExtendedCollection, DAVACL\IACL { * @param Backend\BackendInterface $caldavBackend * @param mixed $userUri */ - public function __construct(Backend\BackendInterface $caldavBackend, $principalInfo) { - + public function __construct(Backend\BackendInterface $caldavBackend, $principalInfo) + { $this->caldavBackend = $caldavBackend; $this->principalInfo = $principalInfo; @@ -46,8 +46,8 @@ public function __construct(Backend\BackendInterface $caldavBackend, $principalI * * @return string */ - public function getName() { - + public function getName() + { list(,$name) = DAV\URLUtil::splitPath($this->principalInfo['uri']); return $name; @@ -59,8 +59,8 @@ public function getName() { * @param string $name * @return void */ - public function setName($name) { - + public function setName($name) + { throw new DAV\Exception\Forbidden(); } @@ -70,8 +70,8 @@ public function setName($name) { * * @return void */ - public function delete() { - + public function delete() + { throw new DAV\Exception\Forbidden(); } @@ -81,8 +81,8 @@ public function delete() { * * @return int */ - public function getLastModified() { - + public function getLastModified() + { return null; } @@ -96,8 +96,8 @@ public function getLastModified() { * @param resource $data * @return void */ - public function createFile($filename, $data=null) { - + public function createFile($filename, $data=null) + { throw new DAV\Exception\MethodNotAllowed('Creating new files in this collection is not supported'); } @@ -110,8 +110,8 @@ public function createFile($filename, $data=null) { * @param string $filename * @return void */ - public function createDirectory($filename) { - + public function createDirectory($filename) + { throw new DAV\Exception\MethodNotAllowed('Creating new collections in this collection is not supported'); } @@ -123,9 +123,9 @@ public function createDirectory($filename) { * @todo needs optimizing * @return Calendar */ - public function getChild($name) { - - foreach($this->getChildren() as $child) { + public function getChild($name) + { + foreach ($this->getChildren() as $child) { if ($name==$child->getName()) return $child; @@ -141,9 +141,9 @@ public function getChild($name) { * @todo needs optimizing * @return bool */ - public function childExists($name) { - - foreach($this->getChildren() as $child) { + public function childExists($name) + { + foreach ($this->getChildren() as $child) { if ($name==$child->getName()) return true; @@ -157,11 +157,11 @@ public function childExists($name) { * * @return array */ - public function getChildren() { - + public function getChildren() + { $calendars = $this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']); $objs = array(); - foreach($calendars as $calendar) { + foreach ($calendars as $calendar) { if ($this->caldavBackend instanceof Backend\SharingSupport) { if (isset($calendar['{http://calendarserver.org/ns/}shared-url'])) { $objs[] = new SharedCalendar($this->caldavBackend, $calendar); @@ -190,10 +190,10 @@ public function getChildren() { * @param array $properties * @return void */ - public function createExtendedCollection($name, array $resourceType, array $properties) { - + public function createExtendedCollection($name, array $resourceType, array $properties) + { $isCalendar = false; - foreach($resourceType as $rt) { + foreach ($resourceType as $rt) { switch ($rt) { case '{DAV:}collection' : case '{http://calendarserver.org/ns/}shared-owner' : @@ -220,8 +220,8 @@ public function createExtendedCollection($name, array $resourceType, array $prop * * @return string|null */ - public function getOwner() { - + public function getOwner() + { return $this->principalInfo['uri']; } @@ -233,8 +233,8 @@ public function getOwner() { * * @return string|null */ - public function getGroup() { - + public function getGroup() + { return null; } @@ -251,8 +251,8 @@ public function getGroup() { * * @return array */ - public function getACL() { - + public function getACL() + { return array( array( 'privilege' => '{DAV:}read', @@ -292,8 +292,8 @@ public function getACL() { * @param array $acl * @return void */ - public function setACL(array $acl) { - + public function setACL(array $acl) + { throw new DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported'); } @@ -310,8 +310,8 @@ public function setACL(array $acl) { * * @return array|null */ - public function getSupportedPrivilegeSet() { - + public function getSupportedPrivilegeSet() + { return null; } @@ -329,8 +329,8 @@ public function getSupportedPrivilegeSet() { * @param string $summary A description of the reply * @return null|string */ - public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null) { - + public function shareReply($href, $status, $calendarUri, $inReplyTo, $summary = null) + { if (!$this->caldavBackend instanceof Backend\SharingSupport) { throw new DAV\Exception\NotImplemented('Sharing support is not implemented by this backend.'); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Version.php b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Version.php index 01485af135..cbac08f474 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Version.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CalDAV/Version.php @@ -9,8 +9,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Version { - +class Version +{ /** * Full version number */ diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBook.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBook.php index 83ff621190..a8146c9043 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBook.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBook.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class AddressBook extends DAV\Collection implements IAddressBook, DAV\IProperties, DAVACL\IACL { - +class AddressBook extends DAV\Collection implements IAddressBook, DAV\IProperties, DAVACL\IACL +{ /** * This is an array with addressbook information * @@ -36,8 +36,8 @@ class AddressBook extends DAV\Collection implements IAddressBook, DAV\IPropertie * @param Backend\BackendInterface $carddavBackend * @param array $addressBookInfo */ - public function __construct(Backend\BackendInterface $carddavBackend, array $addressBookInfo) { - + public function __construct(Backend\BackendInterface $carddavBackend, array $addressBookInfo) + { $this->carddavBackend = $carddavBackend; $this->addressBookInfo = $addressBookInfo; @@ -48,8 +48,8 @@ public function __construct(Backend\BackendInterface $carddavBackend, array $add * * @return string */ - public function getName() { - + public function getName() + { return $this->addressBookInfo['uri']; } @@ -60,8 +60,8 @@ public function getName() { * @param string $name * @return \ICard */ - public function getChild($name) { - + public function getChild($name) + { $obj = $this->carddavBackend->getCard($this->addressBookInfo['id'],$name); if (!$obj) throw new DAV\Exception\NotFound('Card not found'); return new Card($this->carddavBackend,$this->addressBookInfo,$obj); @@ -73,11 +73,11 @@ public function getChild($name) { * * @return array */ - public function getChildren() { - + public function getChildren() + { $objs = $this->carddavBackend->getCards($this->addressBookInfo['id']); $children = array(); - foreach($objs as $obj) { + foreach ($objs as $obj) { $children[] = new Card($this->carddavBackend,$this->addressBookInfo,$obj); } return $children; @@ -92,8 +92,8 @@ public function getChildren() { * @param string $name * @return void */ - public function createDirectory($name) { - + public function createDirectory($name) + { throw new DAV\Exception\MethodNotAllowed('Creating collections in addressbooks is not allowed'); } @@ -109,8 +109,8 @@ public function createDirectory($name) { * @param resource $vcardData * @return string|null */ - public function createFile($name,$vcardData = null) { - + public function createFile($name,$vcardData = null) + { if (is_resource($vcardData)) { $vcardData = stream_get_contents($vcardData); } @@ -126,8 +126,8 @@ public function createFile($name,$vcardData = null) { * * @return void */ - public function delete() { - + public function delete() + { $this->carddavBackend->deleteAddressBook($this->addressBookInfo['id']); } @@ -138,8 +138,8 @@ public function delete() { * @param string $newName * @return void */ - public function setName($newName) { - + public function setName($newName) + { throw new DAV\Exception\MethodNotAllowed('Renaming addressbooks is not yet supported'); } @@ -149,8 +149,8 @@ public function setName($newName) { * * @return void */ - public function getLastModified() { - + public function getLastModified() + { return null; } @@ -190,8 +190,8 @@ public function getLastModified() { * @param array $mutations * @return bool|array */ - public function updateProperties($mutations) { - + public function updateProperties($mutations) + { return $this->carddavBackend->updateAddressBook($this->addressBookInfo['id'], $mutations); } @@ -207,10 +207,10 @@ public function updateProperties($mutations) { * @param array $properties * @return array */ - public function getProperties($properties) { - + public function getProperties($properties) + { $response = array(); - foreach($properties as $propertyName) { + foreach ($properties as $propertyName) { if (isset($this->addressBookInfo[$propertyName])) { @@ -231,8 +231,8 @@ public function getProperties($properties) { * * @return string|null */ - public function getOwner() { - + public function getOwner() + { return $this->addressBookInfo['principaluri']; } @@ -244,8 +244,8 @@ public function getOwner() { * * @return string|null */ - public function getGroup() { - + public function getGroup() + { return null; } @@ -262,8 +262,8 @@ public function getGroup() { * * @return array */ - public function getACL() { - + public function getACL() + { return array( array( 'privilege' => '{DAV:}read', @@ -288,8 +288,8 @@ public function getACL() { * @param array $acl * @return void */ - public function setACL(array $acl) { - + public function setACL(array $acl) + { throw new DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported'); } @@ -306,8 +306,8 @@ public function setACL(array $acl) { * * @return array|null */ - public function getSupportedPrivilegeSet() { - + public function getSupportedPrivilegeSet() + { return null; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBookQueryParser.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBookQueryParser.php index 503c97582a..cb448975a9 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBookQueryParser.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBookQueryParser.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class AddressBookQueryParser { - +class AddressBookQueryParser +{ const TEST_ANYOF = 'anyof'; const TEST_ALLOF = 'allof'; @@ -68,8 +68,8 @@ class AddressBookQueryParser { * * @param \DOMDocument $dom */ - public function __construct(\DOMDocument $dom) { - + public function __construct(\DOMDocument $dom) + { $this->dom = $dom; $this->xpath = new \DOMXPath($dom); @@ -82,8 +82,8 @@ public function __construct(\DOMDocument $dom) { * * @return void */ - public function parse() { - + public function parse() + { $filterNode = null; $limit = $this->xpath->evaluate('number(/card:addressbook-query/card:limit/card:nresults)'); @@ -114,7 +114,7 @@ public function parse() { $propFilters = array(); $propFilterNodes = $this->xpath->query('card:prop-filter', $filter); - for($ii=0; $ii < $propFilterNodes->length; $ii++) { + for ($ii=0; $ii < $propFilterNodes->length; $ii++) { $propFilters[] = $this->parsePropFilterNode($propFilterNodes->item($ii)); @@ -134,8 +134,8 @@ public function parse() { * @param \DOMElement $propFilterNode * @return array */ - protected function parsePropFilterNode(\DOMElement $propFilterNode) { - + protected function parsePropFilterNode(\DOMElement $propFilterNode) + { $propFilter = array(); $propFilter['name'] = $propFilterNode->getAttribute('name'); $propFilter['test'] = $propFilterNode->getAttribute('test'); @@ -148,7 +148,7 @@ protected function parsePropFilterNode(\DOMElement $propFilterNode) { $propFilter['param-filters'] = array(); - for($ii=0;$ii<$paramFilterNodes->length;$ii++) { + for ($ii=0;$ii<$paramFilterNodes->length;$ii++) { $propFilter['param-filters'][] = $this->parseParamFilterNode($paramFilterNodes->item($ii)); @@ -156,7 +156,7 @@ protected function parsePropFilterNode(\DOMElement $propFilterNode) { $propFilter['text-matches'] = array(); $textMatchNodes = $this->xpath->query('card:text-match', $propFilterNode); - for($ii=0;$ii<$textMatchNodes->length;$ii++) { + for ($ii=0;$ii<$textMatchNodes->length;$ii++) { $propFilter['text-matches'][] = $this->parseTextMatchNode($textMatchNodes->item($ii)); @@ -172,8 +172,8 @@ protected function parsePropFilterNode(\DOMElement $propFilterNode) { * @param \DOMElement $paramFilterNode * @return array */ - public function parseParamFilterNode(\DOMElement $paramFilterNode) { - + public function parseParamFilterNode(\DOMElement $paramFilterNode) + { $paramFilter = array(); $paramFilter['name'] = $paramFilterNode->getAttribute('name'); $paramFilter['is-not-defined'] = $this->xpath->query('card:is-not-defined', $paramFilterNode)->length>0; @@ -194,8 +194,8 @@ public function parseParamFilterNode(\DOMElement $paramFilterNode) { * @param \DOMElement $textMatchNode * @return array */ - public function parseTextMatchNode(\DOMElement $textMatchNode) { - + public function parseTextMatchNode(\DOMElement $textMatchNode) + { $matchType = $textMatchNode->getAttribute('match-type'); if (!$matchType) $matchType = 'contains'; diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBookRoot.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBookRoot.php index 42f8d17b40..b272e13887 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBookRoot.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/AddressBookRoot.php @@ -10,11 +10,11 @@ * This object lists a collection of users, which can contain addressbooks. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class AddressBookRoot extends DAVACL\AbstractPrincipalCollection { - +class AddressBookRoot extends DAVACL\AbstractPrincipalCollection +{ /** * Principal Backend * @@ -43,8 +43,8 @@ class AddressBookRoot extends DAVACL\AbstractPrincipalCollection { * @param Backend\BackendInterface $carddavBackend * @param string $principalPrefix */ - public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend,Backend\BackendInterface $carddavBackend, $principalPrefix = 'principals') { - + public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalBackend,Backend\BackendInterface $carddavBackend, $principalPrefix = 'principals') + { $this->carddavBackend = $carddavBackend; parent::__construct($principalBackend, $principalPrefix); @@ -55,8 +55,8 @@ public function __construct(DAVACL\PrincipalBackend\BackendInterface $principalB * * @return string */ - public function getName() { - + public function getName() + { return Plugin::ADDRESSBOOK_ROOT; } @@ -71,8 +71,8 @@ public function getName() { * @param array $principal * @return \Sabre\DAV\INode */ - public function getChildForPrincipal(array $principal) { - + public function getChildForPrincipal(array $principal) + { return new UserAddressBooks($this->carddavBackend, $principal['uri']); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/AbstractBackend.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/AbstractBackend.php index caf1e58341..958eb92779 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/AbstractBackend.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/AbstractBackend.php @@ -13,6 +13,6 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class AbstractBackend implements BackendInterface { - +abstract class AbstractBackend implements BackendInterface +{ } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/BackendInterface.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/BackendInterface.php index 1557618b28..e197af29a8 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/BackendInterface.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/BackendInterface.php @@ -15,8 +15,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface BackendInterface { - +interface BackendInterface +{ /** * Returns the list of addressbooks for a specific user. * diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/PDO.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/PDO.php index 4ce71bda2b..2620beac35 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/PDO.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Backend/PDO.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class PDO extends AbstractBackend { - +class PDO extends AbstractBackend +{ /** * PDO connection * @@ -40,8 +40,8 @@ class PDO extends AbstractBackend { * @param string $addressBooksTableName * @param string $cardsTableName */ - public function __construct(\PDO $pdo, $addressBooksTableName = 'addressbooks', $cardsTableName = 'cards') { - + public function __construct(\PDO $pdo, $addressBooksTableName = 'addressbooks', $cardsTableName = 'cards') + { $this->pdo = $pdo; $this->addressBooksTableName = $addressBooksTableName; $this->cardsTableName = $cardsTableName; @@ -54,14 +54,14 @@ public function __construct(\PDO $pdo, $addressBooksTableName = 'addressbooks', * @param string $principalUri * @return array */ - public function getAddressBooksForUser($principalUri) { - + public function getAddressBooksForUser($principalUri) + { $stmt = $this->pdo->prepare('SELECT id, uri, displayname, principaluri, description, ctag FROM '.$this->addressBooksTableName.' WHERE principaluri = ?'); $stmt->execute(array($principalUri)); $addressBooks = array(); - foreach($stmt->fetchAll() as $row) { + foreach ($stmt->fetchAll() as $row) { $addressBooks[] = array( 'id' => $row['id'], @@ -92,13 +92,13 @@ public function getAddressBooksForUser($principalUri) { * @see Sabre\DAV\IProperties::updateProperties * @return bool|array */ - public function updateAddressBook($addressBookId, array $mutations) { - + public function updateAddressBook($addressBookId, array $mutations) + { $updates = array(); - foreach($mutations as $property=>$newValue) { + foreach ($mutations as $property=>$newValue) { - switch($property) { + switch ($property) { case '{DAV:}displayname' : $updates['displayname'] = $newValue; break; @@ -119,7 +119,7 @@ public function updateAddressBook($addressBookId, array $mutations) { } $query = 'UPDATE ' . $this->addressBooksTableName . ' SET ctag = ctag + 1 '; - foreach($updates as $key=>$value) { + foreach ($updates as $key=>$value) { $query.=', `' . $key . '` = :' . $key . ' '; } $query.=' WHERE id = :addressbookid'; @@ -141,8 +141,8 @@ public function updateAddressBook($addressBookId, array $mutations) { * @param array $properties * @return void */ - public function createAddressBook($principalUri, $url, array $properties) { - + public function createAddressBook($principalUri, $url, array $properties) + { $values = array( 'displayname' => null, 'description' => null, @@ -150,9 +150,9 @@ public function createAddressBook($principalUri, $url, array $properties) { 'uri' => $url, ); - foreach($properties as $property=>$newValue) { + foreach ($properties as $property=>$newValue) { - switch($property) { + switch ($property) { case '{DAV:}displayname' : $values['displayname'] = $newValue; break; @@ -177,8 +177,8 @@ public function createAddressBook($principalUri, $url, array $properties) { * @param int $addressBookId * @return void */ - public function deleteAddressBook($addressBookId) { - + public function deleteAddressBook($addressBookId) + { $stmt = $this->pdo->prepare('DELETE FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?'); $stmt->execute(array($addressBookId)); @@ -206,8 +206,8 @@ public function deleteAddressBook($addressBookId) { * @param mixed $addressbookId * @return array */ - public function getCards($addressbookId) { - + public function getCards($addressbookId) + { $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified FROM ' . $this->cardsTableName . ' WHERE addressbookid = ?'); $stmt->execute(array($addressbookId)); @@ -226,8 +226,8 @@ public function getCards($addressbookId) { * @param string $cardUri * @return array */ - public function getCard($addressBookId, $cardUri) { - + public function getCard($addressBookId, $cardUri) + { $stmt = $this->pdo->prepare('SELECT id, carddata, uri, lastmodified FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri = ? LIMIT 1'); $stmt->execute(array($addressBookId, $cardUri)); @@ -262,8 +262,8 @@ public function getCard($addressBookId, $cardUri) { * @param string $cardData * @return string|null */ - public function createCard($addressBookId, $cardUri, $cardData) { - + public function createCard($addressBookId, $cardUri, $cardData) + { $stmt = $this->pdo->prepare('INSERT INTO ' . $this->cardsTableName . ' (carddata, uri, lastmodified, addressbookid) VALUES (?, ?, ?, ?)'); $result = $stmt->execute(array($cardData, $cardUri, time(), $addressBookId)); @@ -300,8 +300,8 @@ public function createCard($addressBookId, $cardUri, $cardData) { * @param string $cardData * @return string|null */ - public function updateCard($addressBookId, $cardUri, $cardData) { - + public function updateCard($addressBookId, $cardUri, $cardData) + { $stmt = $this->pdo->prepare('UPDATE ' . $this->cardsTableName . ' SET carddata = ?, lastmodified = ? WHERE uri = ? AND addressbookid =?'); $stmt->execute(array($cardData, time(), $cardUri, $addressBookId)); @@ -319,8 +319,8 @@ public function updateCard($addressBookId, $cardUri, $cardData) { * @param string $cardUri * @return bool */ - public function deleteCard($addressBookId, $cardUri) { - + public function deleteCard($addressBookId, $cardUri) + { $stmt = $this->pdo->prepare('DELETE FROM ' . $this->cardsTableName . ' WHERE addressbookid = ? AND uri = ?'); $stmt->execute(array($addressBookId, $cardUri)); diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Card.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Card.php index 267bd23ad4..144df7738b 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Card.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Card.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Card extends DAV\File implements ICard, DAVACL\IACL { - +class Card extends DAV\File implements ICard, DAVACL\IACL +{ /** * CardDAV backend * @@ -43,8 +43,8 @@ class Card extends DAV\File implements ICard, DAVACL\IACL { * @param array $addressBookInfo * @param array $cardData */ - public function __construct(Backend\BackendInterface $carddavBackend,array $addressBookInfo,array $cardData) { - + public function __construct(Backend\BackendInterface $carddavBackend,array $addressBookInfo,array $cardData) + { $this->carddavBackend = $carddavBackend; $this->addressBookInfo = $addressBookInfo; $this->cardData = $cardData; @@ -56,8 +56,8 @@ public function __construct(Backend\BackendInterface $carddavBackend,array $addr * * @return string */ - public function getName() { - + public function getName() + { return $this->cardData['uri']; } @@ -67,8 +67,8 @@ public function getName() { * * @return string */ - public function get() { - + public function get() + { // Pre-populating 'carddata' is optional. If we don't yet have it // already, we fetch it from the backend. if (!isset($this->cardData['carddata'])) { @@ -84,8 +84,8 @@ public function get() { * @param string $cardData * @return string|null */ - public function put($cardData) { - + public function put($cardData) + { if (is_resource($cardData)) $cardData = stream_get_contents($cardData); @@ -105,8 +105,8 @@ public function put($cardData) { * * @return void */ - public function delete() { - + public function delete() + { $this->carddavBackend->deleteCard($this->addressBookInfo['id'],$this->cardData['uri']); } @@ -116,8 +116,8 @@ public function delete() { * * @return string */ - public function getContentType() { - + public function getContentType() + { return 'text/x-vcard; charset=utf-8'; } @@ -127,8 +127,8 @@ public function getContentType() { * * @return string */ - public function getETag() { - + public function getETag() + { if (isset($this->cardData['etag'])) { return $this->cardData['etag']; } else { @@ -148,8 +148,8 @@ public function getETag() { * * @return int */ - public function getLastModified() { - + public function getLastModified() + { return isset($this->cardData['lastmodified'])?$this->cardData['lastmodified']:null; } @@ -159,8 +159,8 @@ public function getLastModified() { * * @return int */ - public function getSize() { - + public function getSize() + { if (array_key_exists('size', $this->cardData)) { return $this->cardData['size']; } else { @@ -176,8 +176,8 @@ public function getSize() { * * @return string|null */ - public function getOwner() { - + public function getOwner() + { return $this->addressBookInfo['principaluri']; } @@ -189,8 +189,8 @@ public function getOwner() { * * @return string|null */ - public function getGroup() { - + public function getGroup() + { return null; } @@ -207,8 +207,8 @@ public function getGroup() { * * @return array */ - public function getACL() { - + public function getACL() + { return array( array( 'privilege' => '{DAV:}read', @@ -232,8 +232,8 @@ public function getACL() { * @param array $acl * @return void */ - public function setACL(array $acl) { - + public function setACL(array $acl) + { throw new DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported'); } @@ -250,11 +250,10 @@ public function setACL(array $acl) { * * @return array|null */ - public function getSupportedPrivilegeSet() { - + public function getSupportedPrivilegeSet() + { return null; } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/IAddressBook.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/IAddressBook.php index d7fa3433ad..dae7bb6f9c 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/IAddressBook.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/IAddressBook.php @@ -10,11 +10,9 @@ * Implement this interface to allow a node to be recognized as an addressbook. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IAddressBook extends DAV\ICollection { - - - +interface IAddressBook extends DAV\ICollection +{ } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/ICard.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/ICard.php index 62c54c84a8..c136ee02c1 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/ICard.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/ICard.php @@ -11,10 +11,9 @@ * 'Cards'. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface ICard extends DAV\IFile { - +interface ICard extends DAV\IFile +{ } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/IDirectory.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/IDirectory.php index 1576b31b73..a9ee710ad6 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/IDirectory.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/IDirectory.php @@ -12,10 +12,9 @@ * - draft-daboo-carddav-directory-gateway * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IDirectory extends IAddressBook { - - +interface IDirectory extends IAddressBook +{ } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Plugin.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Plugin.php index 0921c9260d..ada2447768 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Plugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Plugin.php @@ -15,8 +15,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Plugin extends DAV\ServerPlugin { - +class Plugin extends DAV\ServerPlugin +{ /** * Url to the addressbooks */ @@ -48,8 +48,8 @@ class Plugin extends DAV\ServerPlugin { * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { /* Events */ $server->subscribeEvent('beforeGetProperties', array($this, 'beforeGetProperties')); $server->subscribeEvent('afterGetProperties', array($this, 'afterGetProperties')); @@ -86,8 +86,8 @@ public function initialize(DAV\Server $server) { * * @return array */ - public function getFeatures() { - + public function getFeatures() + { return array('addressbook'); } @@ -102,8 +102,8 @@ public function getFeatures() { * @param string $uri * @return array */ - public function getSupportedReportSet($uri) { - + public function getSupportedReportSet($uri) + { $node = $this->server->tree->getNodeForPath($uri); if ($node instanceof IAddressBook || $node instanceof ICard) { return array( @@ -125,8 +125,8 @@ public function getSupportedReportSet($uri) { * @param array $returnedProperties * @return void */ - public function beforeGetProperties($path, DAV\INode $node, array &$requestedProperties, array &$returnedProperties) { - + public function beforeGetProperties($path, DAV\INode $node, array &$requestedProperties, array &$returnedProperties) + { if ($node instanceof DAVACL\IPrincipal) { // calendar-home-set property @@ -193,8 +193,8 @@ public function beforeGetProperties($path, DAV\INode $node, array &$requestedPro * @param DAV\INode $node * @return bool */ - public function updateProperties(&$mutations, &$result, DAV\INode $node) { - + public function updateProperties(&$mutations, &$result, DAV\INode $node) + { if (!$node instanceof UserAddressBooks) { return true; } @@ -224,7 +224,7 @@ public function updateProperties(&$mutations, &$result, DAV\INode $node) { ); $closureResult = false; - foreach($innerResult as $status => $props) { + foreach ($innerResult as $status => $props) { if (is_array($props) && array_key_exists('{http://sabredav.org/ns}vcard-url', $props)) { $result[$status][$meCard] = null; $closureResult = ($status>=200 && $status<300); @@ -243,9 +243,9 @@ public function updateProperties(&$mutations, &$result, DAV\INode $node) { * @param \DOMNode $dom * @return bool */ - public function report($reportName,$dom) { - - switch($reportName) { + public function report($reportName,$dom) + { + switch ($reportName) { case '{'.self::NS_CARDDAV.'}addressbook-multiget' : $this->addressbookMultiGetReport($dom); return false; @@ -269,14 +269,14 @@ public function report($reportName,$dom) { * @param \DOMNode $dom * @return void */ - public function addressbookMultiGetReport($dom) { - + public function addressbookMultiGetReport($dom) + { $properties = array_keys(DAV\XMLUtil::parseProperties($dom->firstChild)); $hrefElems = $dom->getElementsByTagNameNS('urn:DAV','href'); $propertyList = array(); - foreach($hrefElems as $elem) { + foreach ($hrefElems as $elem) { $uri = $this->server->calculateUri($elem->nodeValue); list($propertyList[]) = $this->server->getPropertiesForPath($uri,$properties); @@ -303,8 +303,8 @@ public function addressbookMultiGetReport($dom) { * @param resource $data * @return void */ - public function beforeWriteContent($path, DAV\IFile $node, &$data) { - + public function beforeWriteContent($path, DAV\IFile $node, &$data) + { if (!$node instanceof ICard) return; @@ -323,8 +323,8 @@ public function beforeWriteContent($path, DAV\IFile $node, &$data) { * @param DAV\ICollection $parentNode * @return void */ - public function beforeCreateFile($path, &$data, DAV\ICollection $parentNode) { - + public function beforeCreateFile($path, &$data, DAV\ICollection $parentNode) + { if (!$parentNode instanceof IAddressBook) return; @@ -340,8 +340,8 @@ public function beforeCreateFile($path, &$data, DAV\ICollection $parentNode) { * @param resource|string $data * @return void */ - protected function validateVCard(&$data) { - + protected function validateVCard(&$data) + { // If it's a stream, we convert it to a string first. if (is_resource($data)) { $data = stream_get_contents($data); @@ -380,8 +380,8 @@ protected function validateVCard(&$data) { * @param \DOMNode $dom * @return void */ - protected function addressbookQueryReport($dom) { - + protected function addressbookQueryReport($dom) + { $query = new AddressBookQueryParser($dom); $query->parse(); @@ -396,7 +396,7 @@ protected function addressbookQueryReport($dom) { } $validNodes = array(); - foreach($candidateNodes as $node) { + foreach ($candidateNodes as $node) { if (!$node instanceof ICard) continue; @@ -420,7 +420,7 @@ protected function addressbookQueryReport($dom) { } $result = array(); - foreach($validNodes as $validNode) { + foreach ($validNodes as $validNode) { if ($depth==0) { $href = $this->server->getRequestUri(); @@ -449,13 +449,13 @@ protected function addressbookQueryReport($dom) { * @param string $test anyof or allof (which means OR or AND) * @return bool */ - public function validateFilters($vcardData, array $filters, $test) { - + public function validateFilters($vcardData, array $filters, $test) + { $vcard = VObject\Reader::read($vcardData); if (!$filters) return true; - foreach($filters as $filter) { + foreach ($filters as $filter) { $isDefined = isset($vcard->{$filter['name']}); if ($filter['is-not-defined']) { @@ -528,12 +528,12 @@ public function validateFilters($vcardData, array $filters, $test) { * @param string $test * @return bool */ - protected function validateParamFilters(array $vProperties, array $filters, $test) { - - foreach($filters as $filter) { + protected function validateParamFilters(array $vProperties, array $filters, $test) + { + foreach ($filters as $filter) { $isDefined = false; - foreach($vProperties as $vProperty) { + foreach ($vProperties as $vProperty) { $isDefined = isset($vProperty[$filter['name']]); if ($isDefined) break; } @@ -553,7 +553,7 @@ protected function validateParamFilters(array $vProperties, array $filters, $tes } else { $success = false; - foreach($vProperties as $vProperty) { + foreach ($vProperties as $vProperty) { // If we got all the way here, we'll need to validate the // text-match filter. $success = DAV\StringUtil::textMatch($vProperty[$filter['name']]->value, $filter['text-match']['value'], $filter['text-match']['collation'], $filter['text-match']['match-type']); @@ -593,12 +593,12 @@ protected function validateParamFilters(array $vProperties, array $filters, $tes * @param string $test * @return bool */ - protected function validateTextMatches(array $texts, array $filters, $test) { - - foreach($filters as $filter) { + protected function validateTextMatches(array $texts, array $filters, $test) + { + foreach ($filters as $filter) { $success = false; - foreach($texts as $haystack) { + foreach ($texts as $haystack) { $success = DAV\StringUtil::textMatch($haystack, $filter['value'], $filter['collation'], $filter['match-type']); // Breaking on the first match @@ -631,8 +631,8 @@ protected function validateTextMatches(array $texts, array $filters, $test) { * * @return bool */ - public function afterGetProperties($uri, &$properties) { - + public function afterGetProperties($uri, &$properties) + { // If the request was made using the SOGO connector, we must rewrite // the content-type property. By default SabreDAV will send back // text/x-vcard; charset=utf-8, but for SOGO we must strip that last @@ -659,8 +659,8 @@ public function afterGetProperties($uri, &$properties) { * @param string $output * @return bool */ - public function htmlActionsPanel(DAV\INode $node, &$output) { - + public function htmlActionsPanel(DAV\INode $node, &$output) + { if (!$node instanceof UserAddressBooks) return; @@ -686,8 +686,8 @@ public function htmlActionsPanel(DAV\INode $node, &$output) { * @param array $postVars * @return bool */ - public function browserPostAction($uri, $action, array $postVars) { - + public function browserPostAction($uri, $action, array $postVars) + { if ($action!=='mkaddressbook') return; diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Property/SupportedAddressData.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Property/SupportedAddressData.php index 647f34e250..65f061336a 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Property/SupportedAddressData.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Property/SupportedAddressData.php @@ -12,11 +12,11 @@ * in the CardDAV namespace. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SupportedAddressData extends DAV\Property { - +class SupportedAddressData extends DAV\Property +{ /** * supported versions * @@ -29,8 +29,8 @@ class SupportedAddressData extends DAV\Property { * * @param array|null $supportedData */ - public function __construct(array $supportedData = null) { - + public function __construct(array $supportedData = null) + { if (is_null($supportedData)) { $supportedData = array( array('contentType' => 'text/vcard', 'version' => '3.0'), @@ -49,8 +49,8 @@ public function __construct(array $supportedData = null) { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server,\DOMElement $node) { - + public function serialize(DAV\Server $server,\DOMElement $node) + { $doc = $node->ownerDocument; $prefix = @@ -58,7 +58,7 @@ public function serialize(DAV\Server $server,\DOMElement $node) { $server->xmlNamespaces[CardDAV\Plugin::NS_CARDDAV] : 'card'; - foreach($this->supportedData as $supported) { + foreach ($this->supportedData as $supported) { $caldata = $doc->createElementNS(CardDAV\Plugin::NS_CARDDAV, $prefix . ':address-data-type'); $caldata->setAttribute('content-type',$supported['contentType']); diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/UserAddressBooks.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/UserAddressBooks.php index 4d8020b7a0..c6d156a0b7 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/UserAddressBooks.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/UserAddressBooks.php @@ -11,11 +11,11 @@ * The UserAddressBooks collection contains a list of addressbooks associated with a user * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class UserAddressBooks extends DAV\Collection implements DAV\IExtendedCollection, DAVACL\IACL { - +class UserAddressBooks extends DAV\Collection implements DAV\IExtendedCollection, DAVACL\IACL +{ /** * Principal uri * @@ -36,8 +36,8 @@ class UserAddressBooks extends DAV\Collection implements DAV\IExtendedCollection * @param Backend\BackendInterface $carddavBackend * @param string $principalUri */ - public function __construct(Backend\BackendInterface $carddavBackend, $principalUri) { - + public function __construct(Backend\BackendInterface $carddavBackend, $principalUri) + { $this->carddavBackend = $carddavBackend; $this->principalUri = $principalUri; @@ -48,8 +48,8 @@ public function __construct(Backend\BackendInterface $carddavBackend, $principal * * @return string */ - public function getName() { - + public function getName() + { list(,$name) = DAV\URLUtil::splitPath($this->principalUri); return $name; @@ -61,8 +61,8 @@ public function getName() { * @param string $name * @return void */ - public function setName($name) { - + public function setName($name) + { throw new DAV\Exception\MethodNotAllowed(); } @@ -72,8 +72,8 @@ public function setName($name) { * * @return void */ - public function delete() { - + public function delete() + { throw new DAV\Exception\MethodNotAllowed(); } @@ -83,8 +83,8 @@ public function delete() { * * @return int */ - public function getLastModified() { - + public function getLastModified() + { return null; } @@ -98,8 +98,8 @@ public function getLastModified() { * @param resource $data * @return void */ - public function createFile($filename, $data=null) { - + public function createFile($filename, $data=null) + { throw new DAV\Exception\MethodNotAllowed('Creating new files in this collection is not supported'); } @@ -112,8 +112,8 @@ public function createFile($filename, $data=null) { * @param string $filename * @return void */ - public function createDirectory($filename) { - + public function createDirectory($filename) + { throw new DAV\Exception\MethodNotAllowed('Creating new collections in this collection is not supported'); } @@ -125,9 +125,9 @@ public function createDirectory($filename) { * @todo needs optimizing * @return \AddressBook */ - public function getChild($name) { - - foreach($this->getChildren() as $child) { + public function getChild($name) + { + foreach ($this->getChildren() as $child) { if ($name==$child->getName()) return $child; @@ -141,11 +141,11 @@ public function getChild($name) { * * @return array */ - public function getChildren() { - + public function getChildren() + { $addressbooks = $this->carddavBackend->getAddressbooksForUser($this->principalUri); $objs = array(); - foreach($addressbooks as $addressbook) { + foreach ($addressbooks as $addressbook) { $objs[] = new AddressBook($this->carddavBackend, $addressbook); } return $objs; @@ -160,8 +160,8 @@ public function getChildren() { * @param array $properties * @return void */ - public function createExtendedCollection($name, array $resourceType, array $properties) { - + public function createExtendedCollection($name, array $resourceType, array $properties) + { if (!in_array('{'.Plugin::NS_CARDDAV.'}addressbook',$resourceType) || count($resourceType)!==2) { throw new DAV\Exception\InvalidResourceType('Unknown resourceType for this collection'); } @@ -176,8 +176,8 @@ public function createExtendedCollection($name, array $resourceType, array $prop * * @return string|null */ - public function getOwner() { - + public function getOwner() + { return $this->principalUri; } @@ -189,8 +189,8 @@ public function getOwner() { * * @return string|null */ - public function getGroup() { - + public function getGroup() + { return null; } @@ -207,8 +207,8 @@ public function getGroup() { * * @return array */ - public function getACL() { - + public function getACL() + { return array( array( 'privilege' => '{DAV:}read', @@ -233,8 +233,8 @@ public function getACL() { * @param array $acl * @return void */ - public function setACL(array $acl) { - + public function setACL(array $acl) + { throw new DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported'); } @@ -251,8 +251,8 @@ public function setACL(array $acl) { * * @return array|null */ - public function getSupportedPrivilegeSet() { - + public function getSupportedPrivilegeSet() + { return null; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/VCFExportPlugin.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/VCFExportPlugin.php index 93db99f39c..9210377705 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/VCFExportPlugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/VCFExportPlugin.php @@ -17,8 +17,8 @@ * @author Thomas Tanghus (http://tanghus.net/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class VCFExportPlugin extends DAV\ServerPlugin { - +class VCFExportPlugin extends DAV\ServerPlugin +{ /** * Reference to Server class * @@ -32,8 +32,8 @@ class VCFExportPlugin extends DAV\ServerPlugin { * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { $this->server = $server; $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'), 90); @@ -47,8 +47,8 @@ public function initialize(DAV\Server $server) { * @param string $uri * @return bool */ - public function beforeMethod($method, $uri) { - + public function beforeMethod($method, $uri) + { if ($method!='GET') return; if ($this->server->httpRequest->getQueryString()!='export') return; @@ -84,11 +84,11 @@ public function beforeMethod($method, $uri) { * @param array $nodes * @return string */ - public function generateVCF(array $nodes) { - + public function generateVCF(array $nodes) + { $output = ""; - foreach($nodes as $node) { + foreach ($nodes as $node) { if (!isset($node[200]['{' . Plugin::NS_CARDDAV . '}address-data'])) { continue; diff --git a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Version.php b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Version.php index b4a5d5b6d5..e6311eac84 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Version.php +++ b/core/src/core/classes/sabredav/lib/Sabre/CardDAV/Version.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Version { - +class Version +{ /** * Full version number */ diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/AbstractBasic.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/AbstractBasic.php index 019e31d798..e7f99021c2 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/AbstractBasic.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/AbstractBasic.php @@ -17,8 +17,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class AbstractBasic implements BackendInterface { - +abstract class AbstractBasic implements BackendInterface +{ /** * This variable holds the currently logged in username. * @@ -45,7 +45,8 @@ abstract protected function validateUserPass($username, $password); * * @return string|null */ - public function getCurrentUser() { + public function getCurrentUser() + { return $this->currentUser; } @@ -61,8 +62,8 @@ public function getCurrentUser() { * @throws DAV\Exception\NotAuthenticated * @return bool */ - public function authenticate(DAV\Server $server, $realm) { - + public function authenticate(DAV\Server $server, $realm) + { $auth = new HTTP\BasicAuth(); $auth->setHTTPRequest($server->httpRequest); $auth->setHTTPResponse($server->httpResponse); @@ -84,4 +85,3 @@ public function authenticate(DAV\Server $server, $realm) { } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/AbstractDigest.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/AbstractDigest.php index 7712344997..da4e7419d5 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/AbstractDigest.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/AbstractDigest.php @@ -13,11 +13,11 @@ * the getDigestHash method * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class AbstractDigest implements BackendInterface { - +abstract class AbstractDigest implements BackendInterface +{ /** * This variable holds the currently logged in username. * @@ -47,8 +47,8 @@ abstract public function getDigestHash($realm, $username); * @throws DAV\Exception\NotAuthenticated * @return bool */ - public function authenticate(DAV\Server $server, $realm) { - + public function authenticate(DAV\Server $server, $realm) + { $digest = new HTTP\DigestAuth(); // Hooking up request and response objects @@ -92,8 +92,8 @@ public function authenticate(DAV\Server $server, $realm) { * * @return string|null */ - public function getCurrentUser() { - + public function getCurrentUser() + { return $this->currentUser; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/Apache.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/Apache.php index 96b0a420e0..e3992adedc 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/Apache.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/Apache.php @@ -12,11 +12,11 @@ * Make sure apache is properly configured for this to work. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Apache implements BackendInterface { - +class Apache implements BackendInterface +{ /** * Current apache user * @@ -34,8 +34,8 @@ class Apache implements BackendInterface { * @param string $realm * @return bool */ - public function authenticate(DAV\Server $server, $realm) { - + public function authenticate(DAV\Server $server, $realm) + { $remoteUser = $server->httpRequest->getRawServerValue('REMOTE_USER'); if (is_null($remoteUser)) { throw new DAV\Exception('We did not receive the $_SERVER[REMOTE_USER] property. This means that apache might have been misconfigured'); @@ -53,11 +53,10 @@ public function authenticate(DAV\Server $server, $realm) { * * @return array|null */ - public function getCurrentUser() { - + public function getCurrentUser() + { return $this->remoteUser; } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/BackendInterface.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/BackendInterface.php index 0924db2cd9..c944c4cba3 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/BackendInterface.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/BackendInterface.php @@ -6,11 +6,11 @@ * This is the base class for any authentication object. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface BackendInterface { - +interface BackendInterface +{ /** * Authenticates the user based on the current request. * @@ -21,7 +21,7 @@ interface BackendInterface { * @param string $realm * @return bool */ - function authenticate(\Sabre\DAV\Server $server,$realm); + public function authenticate(\Sabre\DAV\Server $server,$realm); /** * Returns information about the currently logged in username. @@ -30,7 +30,6 @@ function authenticate(\Sabre\DAV\Server $server,$realm); * * @return string|null */ - function getCurrentUser(); + public function getCurrentUser(); } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/File.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/File.php index ab6462a75e..d86e2bc9e7 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/File.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/File.php @@ -10,11 +10,11 @@ * The backend file must conform to Apache's htdigest format * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class File extends AbstractDigest { - +class File extends AbstractDigest +{ /** * List of users * @@ -29,8 +29,8 @@ class File extends AbstractDigest { * * @param string|null $filename */ - public function __construct($filename=null) { - + public function __construct($filename=null) + { if (!is_null($filename)) $this->loadFile($filename); @@ -43,9 +43,9 @@ public function __construct($filename=null) { * @param string $filename * @return void */ - public function loadFile($filename) { - - foreach(file($filename,FILE_IGNORE_NEW_LINES) as $line) { + public function loadFile($filename) + { + foreach (file($filename,FILE_IGNORE_NEW_LINES) as $line) { if (substr_count($line, ":") !== 2) throw new DAV\Exception('Malformed htdigest file. Every line should contain 2 colons'); @@ -68,8 +68,8 @@ public function loadFile($filename) { * @param string $username * @return string */ - public function getDigestHash($realm, $username) { - + public function getDigestHash($realm, $username) + { return isset($this->users[$realm . ':' . $username])?$this->users[$realm . ':' . $username]:false; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/PDO.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/PDO.php index 65f70c8ad5..f86e93dd8f 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/PDO.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Backend/PDO.php @@ -8,11 +8,11 @@ * The backend file must conform to Apache's htdigest format * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class PDO extends AbstractDigest { - +class PDO extends AbstractDigest +{ /** * Reference to PDO connection * @@ -36,8 +36,8 @@ class PDO extends AbstractDigest { * @param PDO $pdo * @param string $tableName The PDO table name to use */ - public function __construct(\PDO $pdo, $tableName = 'users') { - + public function __construct(\PDO $pdo, $tableName = 'users') + { $this->pdo = $pdo; $this->tableName = $tableName; @@ -50,8 +50,8 @@ public function __construct(\PDO $pdo, $tableName = 'users') { * @param string $username * @return string|null */ - public function getDigestHash($realm,$username) { - + public function getDigestHash($realm,$username) + { $stmt = $this->pdo->prepare('SELECT username, digesta1 FROM '.$this->tableName.' WHERE username = ?'); $stmt->execute(array($username)); $result = $stmt->fetchAll(); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Plugin.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Plugin.php index 8be8fb1f25..5b725a30f2 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Plugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Auth/Plugin.php @@ -16,8 +16,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Plugin extends DAV\ServerPlugin { - +class Plugin extends DAV\ServerPlugin +{ /** * Reference to main server object * @@ -45,8 +45,8 @@ class Plugin extends DAV\ServerPlugin { * @param Backend\BackendInterface $authBackend * @param string $realm */ - public function __construct(Backend\BackendInterface $authBackend, $realm) { - + public function __construct(Backend\BackendInterface $authBackend, $realm) + { $this->authBackend = $authBackend; $this->realm = $realm; @@ -58,8 +58,8 @@ public function __construct(Backend\BackendInterface $authBackend, $realm) { * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { $this->server = $server; $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'),10); @@ -73,8 +73,8 @@ public function initialize(DAV\Server $server) { * * @return string */ - public function getPluginName() { - + public function getPluginName() + { return 'auth'; } @@ -86,8 +86,8 @@ public function getPluginName() { * * @return string|null */ - public function getCurrentUser() { - + public function getCurrentUser() + { $userInfo = $this->authBackend->getCurrentUser(); if (!$userInfo) return null; @@ -103,8 +103,8 @@ public function getCurrentUser() { * @throws Sabre\DAV\Exception\NotAuthenticated * @return bool */ - public function beforeMethod($method, $uri) { - + public function beforeMethod($method, $uri) + { $this->authBackend->authenticate($this->server,$this->realm); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/GuessContentType.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/GuessContentType.php index 8c971e60fc..02ae19b3d1 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/GuessContentType.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/GuessContentType.php @@ -16,11 +16,11 @@ * on the file extension. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class GuessContentType extends DAV\ServerPlugin { - +class GuessContentType extends DAV\ServerPlugin +{ /** * List of recognized file extensions * @@ -50,8 +50,8 @@ class GuessContentType extends DAV\ServerPlugin { * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { // Using a relatively low priority (200) to allow other extensions // to set the content-type first. $server->subscribeEvent('afterGetProperties',array($this,'afterGetProperties'),200); @@ -65,8 +65,8 @@ public function initialize(DAV\Server $server) { * @param array $properties * @return void */ - public function afterGetProperties($path, &$properties) { - + public function afterGetProperties($path, &$properties) + { if (array_key_exists('{DAV:}getcontenttype', $properties[404])) { list(, $fileName) = DAV\URLUtil::splitPath($path); @@ -87,8 +87,8 @@ public function afterGetProperties($path, &$properties) { * @param string $fileName * @return string */ - protected function getContentType($fileName) { - + protected function getContentType($fileName) + { // Just grabbing the extension $extension = strtolower(substr($fileName,strrpos($fileName,'.')+1)); if (isset($this->extensionMap[$extension])) diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/MapGetToPropFind.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/MapGetToPropFind.php index 3247dce399..70ec574faa 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/MapGetToPropFind.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/MapGetToPropFind.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class MapGetToPropFind extends DAV\ServerPlugin { - +class MapGetToPropFind extends DAV\ServerPlugin +{ /** * reference to server class * @@ -29,8 +29,8 @@ class MapGetToPropFind extends DAV\ServerPlugin { * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { $this->server = $server; $this->server->subscribeEvent('beforeMethod',array($this,'httpGetInterceptor')); } @@ -42,8 +42,8 @@ public function initialize(DAV\Server $server) { * @param string $uri * @return bool */ - public function httpGetInterceptor($method, $uri) { - + public function httpGetInterceptor($method, $uri) + { if ($method!='GET') return true; $node = $this->server->tree->getNodeForPath($uri); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/Plugin.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/Plugin.php index da7e20a27a..8a89030304 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/Plugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Browser/Plugin.php @@ -17,8 +17,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Plugin extends DAV\ServerPlugin { - +class Plugin extends DAV\ServerPlugin +{ /** * List of default icons for nodes. * @@ -78,8 +78,8 @@ class Plugin extends DAV\ServerPlugin { * @param bool $enablePost * @param bool $enableAssets */ - public function __construct($enablePost=true, $enableAssets = true) { - + public function __construct($enablePost=true, $enableAssets = true) + { $this->enablePost = $enablePost; $this->enableAssets = $enableAssets; @@ -91,8 +91,8 @@ public function __construct($enablePost=true, $enableAssets = true) { * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { $this->server = $server; $this->server->subscribeEvent('beforeMethod',array($this,'httpGetInterceptor')); $this->server->subscribeEvent('onHTMLActionsPanel', array($this, 'htmlActionsPanel'),200); @@ -106,8 +106,8 @@ public function initialize(DAV\Server $server) { * @param string $uri * @return bool */ - public function httpGetInterceptor($method, $uri) { - + public function httpGetInterceptor($method, $uri) + { if ($method !== 'GET') return true; // We're not using straight-up $_GET, because we want everything to be @@ -148,8 +148,8 @@ public function httpGetInterceptor($method, $uri) { * @param string $uri * @return bool */ - public function httpPOSTHandler($method, $uri) { - + public function httpPOSTHandler($method, $uri) + { if ($method!='POST') return; $contentType = $this->server->httpRequest->getHeader('Content-Type'); list($contentType) = explode(';', $contentType); @@ -164,7 +164,7 @@ public function httpPOSTHandler($method, $uri) { if ($this->server->broadcastEvent('onBrowserPostAction', array($uri, $postVars['sabreAction'], $postVars))) { - switch($postVars['sabreAction']) { + switch ($postVars['sabreAction']) { case 'mkcol' : if (isset($postVars['name']) && trim($postVars['name'])) { @@ -204,8 +204,8 @@ public function httpPOSTHandler($method, $uri) { * @param string $value * @return string */ - public function escapeHTML($value) { - + public function escapeHTML($value) + { return htmlspecialchars($value,ENT_QUOTES,'UTF-8'); } @@ -216,8 +216,8 @@ public function escapeHTML($value) { * @param string $path * @return string */ - public function generateDirectoryIndex($path) { - + public function generateDirectoryIndex($path) + { $version = ''; if (DAV\Server::$exposeVersion) { $version = DAV\Version::VERSION ."-". DAV\Version::STABILITY; @@ -270,7 +270,7 @@ public function generateDirectoryIndex($path) { } - foreach($files as $file) { + foreach ($files as $file) { // This is the current directory, we can skip it if (rtrim($file['href'],'/')==$path) continue; @@ -286,10 +286,10 @@ public function generateDirectoryIndex($path) { // resourcetype can have multiple values if (!is_array($type)) $type = array($type); - foreach($type as $k=>$v) { + foreach ($type as $k=>$v) { // Some name mapping is preferred - switch($v) { + switch ($v) { case '{DAV:}collection' : $type[$k] = 'Collection'; break; @@ -327,7 +327,7 @@ public function generateDirectoryIndex($path) { } if (!$type) $type = 'Unknown'; - $size = isset($file[200]['{DAV:}getcontentlength'])?(int)$file[200]['{DAV:}getcontentlength']:''; + $size = isset($file[200]['{DAV:}getcontentlength'])?(int) $file[200]['{DAV:}getcontentlength']:''; $lastmodified = isset($file[200]['{DAV:}getlastmodified'])?$file[200]['{DAV:}getlastmodified']->getTime()->format(\DateTime::ATOM):''; $fullPath = DAV\URLUtil::encodePath('/' . trim($this->server->getBaseUri() . ($path?$path . '/':'') . $name,'/')); @@ -341,7 +341,7 @@ public function generateDirectoryIndex($path) { if ($this->enableAssets) { $node = $this->server->tree->getNodeForPath(($path?$path.'/':'') . $name); - foreach(array_reverse($this->iconMap) as $class=>$iconName) { + foreach (array_reverse($this->iconMap) as $class=>$iconName) { if ($node instanceof $class) { $icon = ''; @@ -393,8 +393,8 @@ public function generateDirectoryIndex($path) { * @param mixed $output * @return void */ - public function htmlActionsPanel(DAV\INode $node, &$output) { - + public function htmlActionsPanel(DAV\INode $node, &$output) + { if (!$node instanceof DAV\ICollection) return; @@ -427,8 +427,8 @@ public function htmlActionsPanel(DAV\INode $node, &$output) { * @param string $assetName * @return string */ - protected function getAssetUrl($assetName) { - + protected function getAssetUrl($assetName) + { return $this->server->getBaseUri() . '?sabreAction=asset&assetName=' . urlencode($assetName); } @@ -439,8 +439,8 @@ protected function getAssetUrl($assetName) { * @param string $assetName * @return string */ - protected function getLocalAssetPath($assetName) { - + protected function getLocalAssetPath($assetName) + { $assetDir = __DIR__ . '/assets/'; $path = $assetDir . $assetName; @@ -457,14 +457,14 @@ protected function getLocalAssetPath($assetName) { * @param string $assetName * @return void */ - protected function serveAsset($assetName) { - + protected function serveAsset($assetName) + { $assetPath = $this->getLocalAssetPath($assetName); if (!file_exists($assetPath)) { throw new DAV\Exception\NotFound('Could not find an asset with this name'); } // Rudimentary mime type detection - switch(strtolower(substr($assetPath,strpos($assetPath,'.')+1))) { + switch (strtolower(substr($assetPath,strpos($assetPath,'.')+1))) { case 'ico' : $mime = 'image/vnd.microsoft.icon'; diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Client.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Client.php index c316f449c6..dcd8ab1dbe 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Client.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Client.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Client { - +class Client +{ /** * The propertyMap is a key-value array. * @@ -78,8 +78,8 @@ class Client { * * @param array $settings */ - public function __construct(array $settings) { - + public function __construct(array $settings) + { if (!isset($settings['baseUri'])) { throw new \InvalidArgumentException('A baseUri must be provided'); } @@ -91,7 +91,7 @@ public function __construct(array $settings) { 'proxy', ); - foreach($validSettings as $validSetting) { + foreach ($validSettings as $validSetting) { if (isset($settings[$validSetting])) { $this->$validSetting = $settings[$validSetting]; } @@ -115,7 +115,8 @@ public function __construct(array $settings) { * * @param string $certificates */ - public function addTrustedCertificates($certificates) { + public function addTrustedCertificates($certificates) + { $this->trustedCertificates = $certificates; } @@ -124,7 +125,8 @@ public function addTrustedCertificates($certificates) { * * @param boolean $value */ - public function setVerifyPeer($value) { + public function setVerifyPeer($value) + { $this->verifyPeer = $value; } @@ -149,13 +151,13 @@ public function setVerifyPeer($value) { * @param int $depth * @return array */ - public function propFind($url, array $properties, $depth = 0) { - + public function propFind($url, array $properties, $depth = 0) + { $body = '' . "\n"; $body.= '' . "\n"; $body.= ' ' . "\n"; - foreach($properties as $property) { + foreach ($properties as $property) { list( $namespace, @@ -188,7 +190,7 @@ public function propFind($url, array $properties, $depth = 0) { } $newResult = array(); - foreach($result as $href => $statusList) { + foreach ($result as $href => $statusList) { $newResult[$href] = isset($statusList[200])?$statusList[200]:array(); @@ -211,12 +213,12 @@ public function propFind($url, array $properties, $depth = 0) { * @param array $properties * @return void */ - public function propPatch($url, array $properties) { - + public function propPatch($url, array $properties) + { $body = '' . "\n"; $body.= '' . "\n"; - foreach($properties as $propName => $propValue) { + foreach ($properties as $propName => $propValue) { list( $namespace, @@ -273,15 +275,15 @@ public function propPatch($url, array $properties) { * * @return array */ - public function options() { - + public function options() + { $result = $this->request('OPTIONS'); if (!isset($result['headers']['dav'])) { return array(); } $features = explode(',', $result['headers']['dav']); - foreach($features as &$v) { + foreach ($features as &$v) { $v = trim($v); } return $features; @@ -306,8 +308,8 @@ public function options() { * @param array $headers * @return array */ - public function request($method, $url = '', $body = null, $headers = array()) { - + public function request($method, $url = '', $body = null, $headers = array()) + { $url = $this->getAbsoluteUrl($url); $curlSettings = array( @@ -320,11 +322,11 @@ public function request($method, $url = '', $body = null, $headers = array()) { CURLOPT_MAXREDIRS => 5, ); - if($this->verifyPeer !== null) { + if ($this->verifyPeer !== null) { $curlSettings[CURLOPT_SSL_VERIFYPEER] = $this->verifyPeer; } - if($this->trustedCertificates) { + if ($this->trustedCertificates) { $curlSettings[CURLOPT_CAINFO] = $this->trustedCertificates; } @@ -348,7 +350,7 @@ public function request($method, $url = '', $body = null, $headers = array()) { // Adding HTTP headers $nHeaders = array(); - foreach($headers as $key=>$value) { + foreach ($headers as $key=>$value) { $nHeaders[] = $key . ': ' . $value; @@ -393,7 +395,7 @@ public function request($method, $url = '', $body = null, $headers = array()) { $headerBlob = explode("\r\n", $headerBlob); $headers = array(); - foreach($headerBlob as $header) { + foreach ($headerBlob as $header) { $parts = explode(':', $header, 2); if (count($parts)==2) { $headers[strtolower(trim($parts[0]))] = trim($parts[1]); @@ -456,8 +458,8 @@ public function request($method, $url = '', $body = null, $headers = array()) { * @return array */ // @codeCoverageIgnoreStart - protected function curlRequest($url, $settings) { - + protected function curlRequest($url, $settings) + { $curl = curl_init($url); curl_setopt_array($curl, $settings); @@ -478,8 +480,8 @@ protected function curlRequest($url, $settings) { * @param string $url * @return string */ - protected function getAbsoluteUrl($url) { - + protected function getAbsoluteUrl($url) + { // If the url starts with http:// or https://, the url is already absolute. if (preg_match('/^http(s?):\/\//', $url)) { return $url; @@ -522,8 +524,8 @@ protected function getAbsoluteUrl($url) { * @param string $body xml body * @return array */ - public function parseMultiStatus($body) { - + public function parseMultiStatus($body) + { $body = XMLUtil::convertDAVNamespace($body); $responseXML = simplexml_load_string($body, null, LIBXML_NOBLANKS | LIBXML_NOCDATA); @@ -535,18 +537,18 @@ public function parseMultiStatus($body) { $propResult = array(); - foreach($responseXML->xpath('d:response') as $response) { + foreach ($responseXML->xpath('d:response') as $response) { $response->registerXPathNamespace('d', 'urn:DAV'); $href = $response->xpath('d:href'); - $href = (string)$href[0]; + $href = (string) $href[0]; $properties = array(); - foreach($response->xpath('d:propstat') as $propStat) { + foreach ($response->xpath('d:propstat') as $propStat) { $propStat->registerXPathNamespace('d', 'urn:DAV'); $status = $propStat->xpath('d:status'); - list($httpVersion, $statusCode, $message) = explode(' ', (string)$status[0],3); + list($httpVersion, $statusCode, $message) = explode(' ', (string) $status[0],3); $properties[$statusCode] = XMLUtil::parseProperties(dom_import_simplexml($propStat), $this->propertyMap); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Collection.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Collection.php index b9c8bfd2cc..1388b4cffa 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Collection.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Collection.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class Collection extends Node implements ICollection { - +abstract class Collection extends Node implements ICollection +{ /** * Returns a child object, by its name. * @@ -28,9 +28,9 @@ abstract class Collection extends Node implements ICollection { * @throws Exception\NotFound * @return INode */ - public function getChild($name) { - - foreach($this->getChildren() as $child) { + public function getChild($name) + { + foreach ($this->getChildren() as $child) { if ($child->getName()==$name) return $child; @@ -47,14 +47,14 @@ public function getChild($name) { * @param string $name * @return bool */ - public function childExists($name) { - + public function childExists($name) + { try { $this->getChild($name); return true; - } catch(Exception\NotFound $e) { + } catch (Exception\NotFound $e) { return false; @@ -86,8 +86,8 @@ public function childExists($name) { * @param resource|string $data Initial payload * @return null|string */ - public function createFile($name, $data = null) { - + public function createFile($name, $data = null) + { throw new Exception\Forbidden('Permission denied to create file (filename ' . $name . ')'); } @@ -99,12 +99,11 @@ public function createFile($name, $data = null) { * @throws Exception\Forbidden * @return void */ - public function createDirectory($name) { - + public function createDirectory($name) + { throw new Exception\Forbidden('Permission denied to create directory'); } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception.php index 510a34920d..fcdb1c077a 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception.php @@ -6,7 +6,7 @@ * This is SabreDAV's base exception file, use this to implement your own exception. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ @@ -21,15 +21,15 @@ * This class also allows you to generate custom xml data for your exceptions. This will be displayed * in the 'error' element in the failing response. */ -class Exception extends \Exception { - +class Exception extends \Exception +{ /** * Returns the HTTP statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 500; } @@ -41,9 +41,8 @@ public function getHTTPCode() { * @param \DOMElement $errorNode * @return void */ - public function serialize(Server $server,\DOMElement $errorNode) { - - + public function serialize(Server $server,\DOMElement $errorNode) + { } /** @@ -54,11 +53,10 @@ public function serialize(Server $server,\DOMElement $errorNode) { * @param Server $server * @return array */ - public function getHTTPHeaders(Server $server) { - + public function getHTTPHeaders(Server $server) + { return array(); } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/BadRequest.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/BadRequest.php index 58c349583b..7c2d14e666 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/BadRequest.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/BadRequest.php @@ -9,18 +9,18 @@ * BadRequest * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class BadRequest extends \Sabre\DAV\Exception { - +class BadRequest extends \Sabre\DAV\Exception +{ /** * Returns the HTTP statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 400; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Conflict.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Conflict.php index 97c7f831ab..00cf016743 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Conflict.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Conflict.php @@ -9,18 +9,18 @@ * file or in a parent directory that doesn't exist. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Conflict extends \Sabre\DAV\Exception { - +class Conflict extends \Sabre\DAV\Exception +{ /** * Returns the HTTP statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 409; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ConflictingLock.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ConflictingLock.php index fba9b91ca5..bede6e1c01 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ConflictingLock.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ConflictingLock.php @@ -11,11 +11,11 @@ * was made, on a resource which was already locked * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class ConflictingLock extends Locked { - +class ConflictingLock extends Locked +{ /** * This method allows the exception to include additional information into the WebDAV error response * @@ -23,8 +23,8 @@ class ConflictingLock extends Locked { * @param \DOMElement $errorNode * @return void */ - public function serialize(DAV\Server $server, \DOMElement $errorNode) { - + public function serialize(DAV\Server $server, \DOMElement $errorNode) + { if ($this->lock) { $error = $errorNode->ownerDocument->createElementNS('DAV:','d:no-conflicting-lock'); $errorNode->appendChild($error); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/FileNotFound.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/FileNotFound.php index 469622022e..db1cc43542 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/FileNotFound.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/FileNotFound.php @@ -5,15 +5,14 @@ /** * FileNotFound * - * Deprecated: Warning, this class is deprecated and will be removed in a + * Deprecated: Warning, this class is deprecated and will be removed in a * future version of SabreDAV. Please use Sabre\DAV\Exception\NotFound instead. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @deprecated Use Sabre\DAV\Exception\NotFound instead * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class FileNotFound extends NotFound { - +class FileNotFound extends NotFound +{ } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Forbidden.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Forbidden.php index ecc773940b..b5f8b6b3ae 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Forbidden.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Forbidden.php @@ -8,18 +8,18 @@ * This exception is thrown whenever a user tries to do an operation he's not allowed to * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Forbidden extends \Sabre\DAV\Exception { - +class Forbidden extends \Sabre\DAV\Exception +{ /** * Returns the HTTP statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 403; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/InsufficientStorage.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/InsufficientStorage.php index 8476586963..84b791f17b 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/InsufficientStorage.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/InsufficientStorage.php @@ -8,18 +8,18 @@ * This Exception can be thrown, when for example a harddisk is full or a quota is exceeded * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class InsufficientStorage extends \Sabre\DAV\Exception { - +class InsufficientStorage extends \Sabre\DAV\Exception +{ /** * Returns the HTTP statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 507; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/InvalidResourceType.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/InvalidResourceType.php index d679e49074..ec09a3ed6c 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/InvalidResourceType.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/InvalidResourceType.php @@ -11,11 +11,11 @@ * See RFC5689 section 3.3 * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class InvalidResourceType extends Forbidden { - +class InvalidResourceType extends Forbidden +{ /** * This method allows the exception to include additional information into the WebDAV error response * @@ -23,8 +23,8 @@ class InvalidResourceType extends Forbidden { * @param \DOMElement $errorNode * @return void */ - public function serialize(\Sabre\DAV\Server $server,\DOMElement $errorNode) { - + public function serialize(\Sabre\DAV\Server $server,\DOMElement $errorNode) + { $error = $errorNode->ownerDocument->createElementNS('DAV:','d:valid-resourcetype'); $errorNode->appendChild($error); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php index dd590ae871..771cbfd84c 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php @@ -10,16 +10,16 @@ * This exception is thrown by UNLOCK if a supplied lock-token is invalid * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class LockTokenMatchesRequestUri extends Conflict { - +class LockTokenMatchesRequestUri extends Conflict +{ /** * Creates the exception */ - public function __construct() { - + public function __construct() + { $this->message = 'The locktoken supplied does not match any locks on this entity'; } @@ -31,8 +31,8 @@ public function __construct() { * @param \DOMElement $errorNode * @return void */ - public function serialize(DAV\Server $server,\DOMElement $errorNode) { - + public function serialize(DAV\Server $server,\DOMElement $errorNode) + { $error = $errorNode->ownerDocument->createElementNS('DAV:','d:lock-token-matches-request-uri'); $errorNode->appendChild($error); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Locked.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Locked.php index cd8f34c9b4..2d68690933 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Locked.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/Locked.php @@ -10,11 +10,11 @@ * The 423 is thrown when a client tried to access a resource that was locked, without supplying a valid lock token * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Locked extends DAV\Exception { - +class Locked extends DAV\Exception +{ /** * Lock information * @@ -30,8 +30,8 @@ class Locked extends DAV\Exception { * * @param DAV\Locks\LockInfo $lock */ - public function __construct(DAV\Locks\LockInfo $lock = null) { - + public function __construct(DAV\Locks\LockInfo $lock = null) + { $this->lock = $lock; } @@ -41,8 +41,8 @@ public function __construct(DAV\Locks\LockInfo $lock = null) { * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 423; } @@ -54,8 +54,8 @@ public function getHTTPCode() { * @param \DOMElement $errorNode * @return void */ - public function serialize(DAV\Server $server,\DOMElement $errorNode) { - + public function serialize(DAV\Server $server,\DOMElement $errorNode) + { if ($this->lock) { $error = $errorNode->ownerDocument->createElementNS('DAV:','d:lock-token-submitted'); $errorNode->appendChild($error); @@ -66,4 +66,3 @@ public function serialize(DAV\Server $server,\DOMElement $errorNode) { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/MethodNotAllowed.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/MethodNotAllowed.php index be4d9adb8f..337627064d 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/MethodNotAllowed.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/MethodNotAllowed.php @@ -8,18 +8,18 @@ * The 405 is thrown when a client tried to create a directory on an already existing directory * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class MethodNotAllowed extends \Sabre\DAV\Exception { - +class MethodNotAllowed extends \Sabre\DAV\Exception +{ /** * Returns the HTTP statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 405; } @@ -32,8 +32,8 @@ public function getHTTPCode() { * @param \Sabre\DAV\Server $server * @return array */ - public function getHTTPHeaders(\Sabre\DAV\Server $server) { - + public function getHTTPHeaders(\Sabre\DAV\Server $server) + { $methods = $server->getAllowedMethods($server->getRequestUri()); return array( diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotAuthenticated.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotAuthenticated.php index 08bb7c406e..ca7e7fbb57 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotAuthenticated.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotAuthenticated.php @@ -11,18 +11,18 @@ * authentication credentials. * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class NotAuthenticated extends DAV\Exception { - +class NotAuthenticated extends DAV\Exception +{ /** * Returns the HTTP statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 401; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotFound.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotFound.php index 0bce3db674..173658a152 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotFound.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotFound.php @@ -11,18 +11,17 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class NotFound extends \Sabre\DAV\Exception { - +class NotFound extends \Sabre\DAV\Exception +{ /** * Returns the HTTP statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 404; } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotImplemented.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotImplemented.php index c0d50a39be..a6625fbaad 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotImplemented.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/NotImplemented.php @@ -8,18 +8,18 @@ * This exception is thrown when the client tried to call an unsupported HTTP method or other feature * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class NotImplemented extends \Sabre\DAV\Exception { - +class NotImplemented extends \Sabre\DAV\Exception +{ /** * Returns the HTTP statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 501; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/PaymentRequired.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/PaymentRequired.php index 2ac719ba7b..e4acfe31aa 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/PaymentRequired.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/PaymentRequired.php @@ -14,15 +14,15 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class PaymentRequired extends DAV\Exception { - +class PaymentRequired extends DAV\Exception +{ /** * Returns the HTTP statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 402; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/PreconditionFailed.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/PreconditionFailed.php index f4af00306a..25889b9c54 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/PreconditionFailed.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/PreconditionFailed.php @@ -12,11 +12,11 @@ * request to not execute (the condition of the header failed) * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class PreconditionFailed extends DAV\Exception { - +class PreconditionFailed extends DAV\Exception +{ /** * When this exception is thrown, the header-name might be set. * @@ -33,8 +33,8 @@ class PreconditionFailed extends DAV\Exception { * @param string $message * @param string $header */ - public function __construct($message, $header=null) { - + public function __construct($message, $header=null) + { parent::__construct($message); $this->header = $header; @@ -45,8 +45,8 @@ public function __construct($message, $header=null) { * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 412; } @@ -58,8 +58,8 @@ public function getHTTPCode() { * @param \DOMElement $errorNode * @return void */ - public function serialize(DAV\Server $server,\DOMElement $errorNode) { - + public function serialize(DAV\Server $server,\DOMElement $errorNode) + { if ($this->header) { $prop = $errorNode->ownerDocument->createElement('s:header'); $prop->nodeValue = $this->header; diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ReportNotSupported.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ReportNotSupported.php index 9879505b72..fe3aa843e7 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ReportNotSupported.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ReportNotSupported.php @@ -10,11 +10,11 @@ * This exception is thrown when the client requested an unknown report through the REPORT method * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class ReportNotSupported extends Forbidden { - +class ReportNotSupported extends Forbidden +{ /** * This method allows the exception to include additional information into the WebDAV error response * @@ -22,8 +22,8 @@ class ReportNotSupported extends Forbidden { * @param \DOMElement $errorNode * @return void */ - public function serialize(DAV\Server $server,\DOMElement $errorNode) { - + public function serialize(DAV\Server $server,\DOMElement $errorNode) + { $error = $errorNode->ownerDocument->createElementNS('DAV:','d:supported-report'); $errorNode->appendChild($error); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php index 443633838d..4aecdae553 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php @@ -14,18 +14,17 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class RequestedRangeNotSatisfiable extends DAV\Exception { - +class RequestedRangeNotSatisfiable extends DAV\Exception +{ /** * returns the http statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 416; } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ServiceUnavailable.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ServiceUnavailable.php index de80858d4b..a1e3ccd29e 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ServiceUnavailable.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/ServiceUnavailable.php @@ -14,17 +14,17 @@ * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class ServiceUnavailable extends DAV\Exception { +class ServiceUnavailable extends DAV\Exception +{ + /** + * Returns the HTTP statuscode for this exception + * + * @return int + */ + public function getHTTPCode() + { + return 503; - /** - * Returns the HTTP statuscode for this exception - * - * @return int - */ - public function getHTTPCode() { - - return 503; - - } + } } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/UnsupportedMediaType.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/UnsupportedMediaType.php index dbe1debcfa..07dbb9d847 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/UnsupportedMediaType.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Exception/UnsupportedMediaType.php @@ -12,15 +12,15 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class UnsupportedMediaType extends \Sabre\DAV\Exception { - +class UnsupportedMediaType extends \Sabre\DAV\Exception +{ /** * returns the http statuscode for this exception * * @return int */ - public function getHTTPCode() { - + public function getHTTPCode() + { return 415; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/Directory.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/Directory.php index 3e292f3d4e..e55ebc44d5 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/Directory.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/Directory.php @@ -10,8 +10,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Directory extends Node implements DAV\ICollection, DAV\IQuota { - +class Directory extends Node implements DAV\ICollection, DAV\IQuota +{ /** * Creates a new file in the directory * @@ -36,8 +36,8 @@ class Directory extends Node implements DAV\ICollection, DAV\IQuota { * @param resource|string $data Initial payload * @return null|string */ - public function createFile($name, $data = null) { - + public function createFile($name, $data = null) + { $newPath = $this->path . '/' . $name; file_put_contents($newPath,$data); @@ -49,8 +49,8 @@ public function createFile($name, $data = null) { * @param string $name * @return void */ - public function createDirectory($name) { - + public function createDirectory($name) + { $newPath = $this->path . '/' . $name; mkdir($newPath); @@ -66,8 +66,8 @@ public function createDirectory($name) { * @throws DAV\Exception\NotFound * @return DAV\INode */ - public function getChild($name) { - + public function getChild($name) + { $path = $this->path . '/' . $name; if (!file_exists($path)) throw new DAV\Exception\NotFound('File with name ' . $path . ' could not be located'); @@ -89,8 +89,8 @@ public function getChild($name) { * * @return DAV\INode[] */ - public function getChildren() { - + public function getChildren() + { $nodes = array(); foreach(scandir($this->path) as $node) if($node!='.' && $node!='..') $nodes[] = $this->getChild($node); return $nodes; @@ -103,8 +103,8 @@ public function getChildren() { * @param string $name * @return bool */ - public function childExists($name) { - + public function childExists($name) + { $path = $this->path . '/' . $name; return file_exists($path); @@ -115,8 +115,8 @@ public function childExists($name) { * * @return void */ - public function delete() { - + public function delete() + { foreach($this->getChildren() as $child) $child->delete(); rmdir($this->path); @@ -127,8 +127,8 @@ public function delete() { * * @return array */ - public function getQuotaInfo() { - + public function getQuotaInfo() + { return array( disk_total_space($this->path)-disk_free_space($this->path), disk_free_space($this->path) @@ -137,4 +137,3 @@ public function getQuotaInfo() { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/File.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/File.php index 51883074c0..600100e0da 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/File.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/File.php @@ -11,16 +11,16 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class File extends Node implements DAV\IFile { - +class File extends Node implements DAV\IFile +{ /** * Updates the data * * @param resource $data * @return void */ - public function put($data) { - + public function put($data) + { file_put_contents($this->path,$data); } @@ -30,8 +30,8 @@ public function put($data) { * * @return string */ - public function get() { - + public function get() + { return fopen($this->path,'r'); } @@ -41,8 +41,8 @@ public function get() { * * @return void */ - public function delete() { - + public function delete() + { unlink($this->path); } @@ -52,8 +52,8 @@ public function delete() { * * @return int */ - public function getSize() { - + public function getSize() + { return filesize($this->path); } @@ -68,8 +68,8 @@ public function getSize() { * * @return mixed */ - public function getETag() { - + public function getETag() + { return null; } @@ -81,11 +81,10 @@ public function getETag() { * * @return mixed */ - public function getContentType() { - + public function getContentType() + { return null; } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/Node.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/Node.php index c30cef7230..4a1dc0e4f9 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/Node.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/FS/Node.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class Node implements DAV\INode { - +abstract class Node implements DAV\INode +{ /** * The path to the current node * @@ -27,8 +27,8 @@ abstract class Node implements DAV\INode { * * @param string $path */ - public function __construct($path) { - + public function __construct($path) + { $this->path = $path; } @@ -40,8 +40,8 @@ public function __construct($path) { * * @return string */ - public function getName() { - + public function getName() + { list(, $name) = DAV\URLUtil::splitPath($this->path); return $name; @@ -53,8 +53,8 @@ public function getName() { * @param string $name The new name * @return void */ - public function setName($name) { - + public function setName($name) + { list($parentPath, ) = DAV\URLUtil::splitPath($this->path); list(, $newName) = DAV\URLUtil::splitPath($name); @@ -72,11 +72,10 @@ public function setName($name) { * * @return int */ - public function getLastModified() { - + public function getLastModified() + { return filemtime($this->path); } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/Directory.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/Directory.php index 977f321382..b324be1c66 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/Directory.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/Directory.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Directory extends Node implements DAV\ICollection, DAV\IQuota { - +class Directory extends Node implements DAV\ICollection, DAV\IQuota +{ /** * Creates a new file in the directory * @@ -37,8 +37,8 @@ class Directory extends Node implements DAV\ICollection, DAV\IQuota { * @param resource|string $data Initial payload * @return null|string */ - public function createFile($name, $data = null) { - + public function createFile($name, $data = null) + { // We're not allowing dots if ($name=='.' || $name=='..') throw new DAV\Exception\Forbidden('Permission denied to . and ..'); $newPath = $this->path . '/' . $name; @@ -54,8 +54,8 @@ public function createFile($name, $data = null) { * @param string $name * @return void */ - public function createDirectory($name) { - + public function createDirectory($name) + { // We're not allowing dots if ($name=='.' || $name=='..') throw new DAV\Exception\Forbidden('Permission denied to . and ..'); $newPath = $this->path . '/' . $name; @@ -73,8 +73,8 @@ public function createDirectory($name) { * @throws DAV\Exception\NotFound * @return DAV\INode */ - public function getChild($name) { - + public function getChild($name) + { $path = $this->path . '/' . $name; if (!file_exists($path)) throw new DAV\Exception\NotFound('File could not be located'); @@ -98,8 +98,8 @@ public function getChild($name) { * @param string $name * @return bool */ - public function childExists($name) { - + public function childExists($name) + { if ($name=='.' || $name=='..') throw new DAV\Exception\Forbidden('Permission denied to . and ..'); @@ -113,8 +113,8 @@ public function childExists($name) { * * @return DAV\INode[] */ - public function getChildren() { - + public function getChildren() + { $nodes = array(); foreach(scandir($this->path) as $node) if($node!='.' && $node!='..' && $node!='.sabredav') $nodes[] = $this->getChild($node); return $nodes; @@ -126,8 +126,8 @@ public function getChildren() { * * @return bool */ - public function delete() { - + public function delete() + { // Deleting all children foreach($this->getChildren() as $child) $child->delete(); @@ -146,8 +146,8 @@ public function delete() { * * @return array */ - public function getQuotaInfo() { - + public function getQuotaInfo() + { return array( disk_total_space($this->path)-disk_free_space($this->path), disk_free_space($this->path) @@ -156,4 +156,3 @@ public function getQuotaInfo() { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/File.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/File.php index 85f3ec9e5a..548d51f6d3 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/File.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/File.php @@ -10,8 +10,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class File extends Node implements DAV\PartialUpdate\IFile { - +class File extends Node implements DAV\PartialUpdate\IFile +{ /** * Updates the data * @@ -20,8 +20,8 @@ class File extends Node implements DAV\PartialUpdate\IFile { * @param resource|string $data * @return string */ - public function put($data) { - + public function put($data) + { file_put_contents($this->path,$data); return '"' . md5_file($this->path) . '"'; @@ -37,8 +37,8 @@ public function put($data) { * param resource|string $data * @return void */ - public function putRange($data, $offset) { - + public function putRange($data, $offset) + { $f = fopen($this->path, 'c'); fseek($f,$offset-1); if (is_string($data)) { @@ -56,8 +56,8 @@ public function putRange($data, $offset) { * * @return resource */ - public function get() { - + public function get() + { return fopen($this->path,'r'); } @@ -67,8 +67,8 @@ public function get() { * * @return bool */ - public function delete() { - + public function delete() + { unlink($this->path); return parent::delete(); @@ -84,8 +84,8 @@ public function delete() { * * @return string|null */ - public function getETag() { - + public function getETag() + { return '"' . md5_file($this->path). '"'; } @@ -97,8 +97,8 @@ public function getETag() { * * @return string|null */ - public function getContentType() { - + public function getContentType() + { return null; } @@ -108,11 +108,10 @@ public function getContentType() { * * @return int */ - public function getSize() { - + public function getSize() + { return filesize($this->path); } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/Node.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/Node.php index 548f8ff101..e1bfad882e 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/Node.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/FSExt/Node.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class Node extends DAV\FS\Node implements DAV\IProperties { - +abstract class Node extends DAV\FS\Node implements DAV\IProperties +{ /** * Updates properties on this node, * @@ -22,11 +22,11 @@ abstract class Node extends DAV\FS\Node implements DAV\IProperties { * @see Sabre\DAV\IProperties::updateProperties * @return bool|array */ - public function updateProperties($properties) { - + public function updateProperties($properties) + { $resourceData = $this->getResourceData(); - foreach($properties as $propertyName=>$propertyValue) { + foreach ($properties as $propertyName=>$propertyValue) { // If it was null, we need to delete the property if (is_null($propertyValue)) { @@ -52,15 +52,15 @@ public function updateProperties($properties) { * @param array $properties * @return array */ - function getProperties($properties) { - + public function getProperties($properties) + { $resourceData = $this->getResourceData(); // if the array was empty, we need to return everything if (!$properties) return $resourceData['properties']; $props = array(); - foreach($properties as $property) { + foreach ($properties as $property) { if (isset($resourceData['properties'][$property])) $props[$property] = $resourceData['properties'][$property]; } @@ -73,8 +73,8 @@ function getProperties($properties) { * * @return string */ - protected function getResourceInfoPath() { - + protected function getResourceInfoPath() + { list($parentDir) = DAV\URLUtil::splitPath($this->path); return $parentDir . '/.sabredav'; @@ -85,8 +85,8 @@ protected function getResourceInfoPath() { * * @return array */ - protected function getResourceData() { - + protected function getResourceData() + { $path = $this->getResourceInfoPath(); if (!file_exists($path)) return array('properties' => array()); @@ -96,7 +96,7 @@ protected function getResourceData() { $data = ''; // Reading data until the eof - while(!feof($handle)) { + while (!feof($handle)) { $data.=fread($handle,8192); } @@ -121,8 +121,8 @@ protected function getResourceData() { * @param array $newData * @return void */ - protected function putResourceData(array $newData) { - + protected function putResourceData(array $newData) + { $path = $this->getResourceInfoPath(); // opening up the file, and creating a shared lock @@ -133,7 +133,7 @@ protected function putResourceData(array $newData) { rewind($handle); // Reading data until the eof - while(!feof($handle)) { + while (!feof($handle)) { $data.=fread($handle,8192); } @@ -154,8 +154,8 @@ protected function putResourceData(array $newData) { * @param string $name The new name * @return void */ - public function setName($name) { - + public function setName($name) + { list($parentPath, ) = DAV\URLUtil::splitPath($this->path); list(, $newName) = DAV\URLUtil::splitPath($name); $newPath = $parentPath . '/' . $newName; @@ -175,8 +175,8 @@ public function setName($name) { /** * @return bool */ - public function deleteResourceData() { - + public function deleteResourceData() + { // When we're deleting this node, we also need to delete any resource information $path = $this->getResourceInfoPath(); if (!file_exists($path)) return true; @@ -189,7 +189,7 @@ public function deleteResourceData() { rewind($handle); // Reading data until the eof - while(!feof($handle)) { + while (!feof($handle)) { $data.=fread($handle,8192); } @@ -204,11 +204,10 @@ public function deleteResourceData() { return true; } - public function delete() { - + public function delete() + { return $this->deleteResourceData(); } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/File.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/File.php index cebe0f8559..bb04c4aed7 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/File.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/File.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class File extends Node implements IFile { - +abstract class File extends Node implements IFile +{ /** * Updates the data * @@ -22,8 +22,8 @@ abstract class File extends Node implements IFile { * @param resource $data * @return void */ - public function put($data) { - + public function put($data) + { throw new Exception\Forbidden('Permission denied to change data'); } @@ -35,8 +35,8 @@ public function put($data) { * * @return mixed */ - public function get() { - + public function get() + { throw new Exception\Forbidden('Permission denied to read this file'); } @@ -46,8 +46,8 @@ public function get() { * * @return int */ - public function getSize() { - + public function getSize() + { return 0; } @@ -62,8 +62,8 @@ public function getSize() { * * @return string|null */ - public function getETag() { - + public function getETag() + { return null; } @@ -75,11 +75,10 @@ public function getETag() { * * @return string|null */ - public function getContentType() { - + public function getContentType() + { return null; } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/ICollection.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/ICollection.php index 99b556a404..1c5d098cde 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/ICollection.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/ICollection.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface ICollection extends INode { - +interface ICollection extends INode +{ /** * Creates a new file in the directory * @@ -37,7 +37,7 @@ interface ICollection extends INode { * @param resource|string $data Initial payload * @return null|string */ - function createFile($name, $data = null); + public function createFile($name, $data = null); /** * Creates a new subdirectory @@ -45,7 +45,7 @@ function createFile($name, $data = null); * @param string $name * @return void */ - function createDirectory($name); + public function createDirectory($name); /** * Returns a specific child node, referenced by its name @@ -56,14 +56,14 @@ function createDirectory($name); * @param string $name * @return DAV\INode */ - function getChild($name); + public function getChild($name); /** * Returns an array with all the child nodes * * @return DAV\INode[] */ - function getChildren(); + public function getChildren(); /** * Checks if a child-node with the specified name exists @@ -71,7 +71,6 @@ function getChildren(); * @param string $name * @return bool */ - function childExists($name); + public function childExists($name); } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/IExtendedCollection.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/IExtendedCollection.php index f093950ad2..9974526bac 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/IExtendedCollection.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/IExtendedCollection.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IExtendedCollection extends ICollection { - +interface IExtendedCollection extends ICollection +{ /** * Creates a new collection * @@ -22,7 +22,6 @@ interface IExtendedCollection extends ICollection { * @param array $properties * @return void */ - function createExtendedCollection($name, array $resourceType, array $properties); + public function createExtendedCollection($name, array $resourceType, array $properties); } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/IFile.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/IFile.php index 429d7dcf77..3a872cb96a 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/IFile.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/IFile.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IFile extends INode { - +interface IFile extends INode +{ /** * Updates the data * @@ -35,7 +35,7 @@ interface IFile extends INode { * @param resource $data * @return string|null */ - function put($data); + public function put($data); /** * Returns the data @@ -44,7 +44,7 @@ function put($data); * * @return mixed */ - function get(); + public function get(); /** * Returns the mime-type for a file @@ -53,7 +53,7 @@ function get(); * * @return string|null */ - function getContentType(); + public function getContentType(); /** * Returns the ETag for a file @@ -64,14 +64,13 @@ function getContentType(); * * @return void */ - function getETag(); + public function getETag(); /** * Returns the size of the node, in bytes * * @return int */ - function getSize(); + public function getSize(); } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/INode.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/INode.php index f09de25842..ec97cd7de0 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/INode.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/INode.php @@ -9,14 +9,14 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface INode { - +interface INode +{ /** * Deleted the current node * * @return void */ - function delete(); + public function delete(); /** * Returns the name of the node. @@ -25,7 +25,7 @@ function delete(); * * @return string */ - function getName(); + public function getName(); /** * Renames the node @@ -33,14 +33,13 @@ function getName(); * @param string $name The new name * @return void */ - function setName($name); + public function setName($name); /** * Returns the last modification time, as a unix timestamp * * @return int */ - function getLastModified(); + public function getLastModified(); } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/IProperties.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/IProperties.php index f279f662f0..01f05c4468 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/IProperties.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/IProperties.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IProperties extends INode { - +interface IProperties extends INode +{ /** * Updates properties on this node, * @@ -48,7 +48,7 @@ interface IProperties extends INode { * @param array $mutations * @return bool|array */ - function updateProperties($mutations); + public function updateProperties($mutations); /** * Returns a list of properties for this nodes. @@ -65,7 +65,6 @@ function updateProperties($mutations); * @param array $properties * @return void */ - function getProperties($properties); + public function getProperties($properties); } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/IQuota.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/IQuota.php index cfa85fee48..5395a31885 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/IQuota.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/IQuota.php @@ -13,15 +13,14 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IQuota extends ICollection { - +interface IQuota extends ICollection +{ /** * Returns the quota information * * This method MUST return an array with 2 values, the first being the total used space, * the second the available space (in bytes) */ - function getQuotaInfo(); + public function getQuotaInfo(); } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/AbstractBackend.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/AbstractBackend.php index 3ce204dd2d..b7c53c13b9 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/AbstractBackend.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/AbstractBackend.php @@ -15,7 +15,6 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class AbstractBackend implements BackendInterface { - +abstract class AbstractBackend implements BackendInterface +{ } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/BackendInterface.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/BackendInterface.php index a7272c1387..7d5abf6a02 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/BackendInterface.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/BackendInterface.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface BackendInterface { - +interface BackendInterface +{ /** * Returns a list of Sabre\DAV\Locks\LockInfo objects * @@ -48,4 +48,3 @@ public function lock($uri,Locks\LockInfo $lockInfo); public function unlock($uri,Locks\LockInfo $lockInfo); } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/FS.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/FS.php index a298ffe837..f356acbdb3 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/FS.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/FS.php @@ -21,8 +21,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class FS extends AbstractBackend { - +class FS extends AbstractBackend +{ /** * The default data directory * @@ -30,14 +30,14 @@ class FS extends AbstractBackend { */ private $dataDir; - public function __construct($dataDir) { - + public function __construct($dataDir) + { $this->dataDir = $dataDir; } - protected function getFileNameForUri($uri) { - + protected function getFileNameForUri($uri) + { return $this->dataDir . '/sabredav_' . md5($uri) . '.locks'; } @@ -56,12 +56,12 @@ protected function getFileNameForUri($uri) { * @param bool $returnChildLocks * @return array */ - public function getLocks($uri, $returnChildLocks) { - + public function getLocks($uri, $returnChildLocks) + { $lockList = array(); $currentPath = ''; - foreach(explode('/',$uri) as $uriPart) { + foreach (explode('/',$uri) as $uriPart) { // weird algorithm that can probably be improved, but we're traversing the path top down if ($currentPath) $currentPath.='/'; @@ -69,10 +69,10 @@ public function getLocks($uri, $returnChildLocks) { $uriLocks = $this->getData($currentPath); - foreach($uriLocks as $uriLock) { + foreach ($uriLocks as $uriLock) { // Unless we're on the leaf of the uri-tree we should ignore locks with depth 0 - if($uri==$currentPath || $uriLock->depth!=0) { + if ($uri==$currentPath || $uriLock->depth!=0) { $uriLock->uri = $currentPath; $lockList[] = $uriLock; } @@ -82,7 +82,7 @@ public function getLocks($uri, $returnChildLocks) { } // Checking if we can remove any of these locks - foreach($lockList as $k=>$lock) { + foreach ($lockList as $k=>$lock) { if (time() > $lock->timeout + $lock->created) unset($lockList[$k]); } return $lockList; @@ -96,14 +96,14 @@ public function getLocks($uri, $returnChildLocks) { * @param LockInfo $lockInfo * @return bool */ - public function lock($uri, LockInfo $lockInfo) { - + public function lock($uri, LockInfo $lockInfo) + { // We're making the lock timeout 30 minutes $lockInfo->timeout = 1800; $lockInfo->created = time(); $locks = $this->getLocks($uri,false); - foreach($locks as $k=>$lock) { + foreach ($locks as $k=>$lock) { if ($lock->token == $lockInfo->token) unset($locks[$k]); } $locks[] = $lockInfo; @@ -119,10 +119,10 @@ public function lock($uri, LockInfo $lockInfo) { * @param LockInfo $lockInfo * @return bool */ - public function unlock($uri, LockInfo $lockInfo) { - + public function unlock($uri, LockInfo $lockInfo) + { $locks = $this->getLocks($uri,false); - foreach($locks as $k=>$lock) { + foreach ($locks as $k=>$lock) { if ($lock->token == $lockInfo->token) { @@ -142,8 +142,8 @@ public function unlock($uri, LockInfo $lockInfo) { * @param string $uri * @return array */ - protected function getData($uri) { - + protected function getData($uri) + { $path = $this->getFilenameForUri($uri); if (!file_exists($path)) return array(); @@ -153,7 +153,7 @@ protected function getData($uri) { $data = ''; // Reading data until the eof - while(!feof($handle)) { + while (!feof($handle)) { $data.=fread($handle,8192); } @@ -174,8 +174,8 @@ protected function getData($uri) { * @param array $newData * @return void */ - protected function putData($uri,array $newData) { - + protected function putData($uri,array $newData) + { $path = $this->getFileNameForUri($uri); // opening up the file, and creating a shared lock @@ -190,4 +190,3 @@ protected function putData($uri,array $newData) { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/File.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/File.php index 6d7a3f9e92..eb59c6e19a 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/File.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/File.php @@ -16,8 +16,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class File extends AbstractBackend { - +class File extends AbstractBackend +{ /** * The storage file * @@ -30,8 +30,8 @@ class File extends AbstractBackend { * * @param string $locksFile path to file */ - public function __construct($locksFile) { - + public function __construct($locksFile) + { $this->locksFile = $locksFile; } @@ -49,13 +49,13 @@ public function __construct($locksFile) { * @param bool $returnChildLocks * @return array */ - public function getLocks($uri, $returnChildLocks) { - + public function getLocks($uri, $returnChildLocks) + { $newLocks = array(); $locks = $this->getData(); - foreach($locks as $lock) { + foreach ($locks as $lock) { if ($lock->uri === $uri || //deep locks on parents @@ -71,7 +71,7 @@ public function getLocks($uri, $returnChildLocks) { } // Checking if we can remove any of these locks - foreach($newLocks as $k=>$lock) { + foreach ($newLocks as $k=>$lock) { if (time() > $lock->timeout + $lock->created) unset($newLocks[$k]); } return $newLocks; @@ -85,8 +85,8 @@ public function getLocks($uri, $returnChildLocks) { * @param LockInfo $lockInfo * @return bool */ - public function lock($uri, LockInfo $lockInfo) { - + public function lock($uri, LockInfo $lockInfo) + { // We're making the lock timeout 30 minutes $lockInfo->timeout = 1800; $lockInfo->created = time(); @@ -94,7 +94,7 @@ public function lock($uri, LockInfo $lockInfo) { $locks = $this->getData(); - foreach($locks as $k=>$lock) { + foreach ($locks as $k=>$lock) { if ( ($lock->token == $lockInfo->token) || (time() > $lock->timeout + $lock->created) @@ -115,10 +115,10 @@ public function lock($uri, LockInfo $lockInfo) { * @param LockInfo $lockInfo * @return bool */ - public function unlock($uri, LockInfo $lockInfo) { - + public function unlock($uri, LockInfo $lockInfo) + { $locks = $this->getData(); - foreach($locks as $k=>$lock) { + foreach ($locks as $k=>$lock) { if ($lock->token == $lockInfo->token) { @@ -137,8 +137,8 @@ public function unlock($uri, LockInfo $lockInfo) { * * @return array */ - protected function getData() { - + protected function getData() + { if (!file_exists($this->locksFile)) return array(); // opening up the file, and creating a shared lock @@ -164,8 +164,8 @@ protected function getData() { * @param array $newData * @return void */ - protected function putData(array $newData) { - + protected function putData(array $newData) + { // opening up the file, and creating an exclusive lock $handle = fopen($this->locksFile,'a+'); flock($handle,LOCK_EX); @@ -180,4 +180,3 @@ protected function putData(array $newData) { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/PDO.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/PDO.php index 4f55a3f270..e649abaf6a 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/PDO.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Backend/PDO.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class PDO extends AbstractBackend { - +class PDO extends AbstractBackend +{ /** * The PDO connection object * @@ -36,8 +36,8 @@ class PDO extends AbstractBackend { * @param PDO $pdo * @param string $tableName */ - public function __construct(\PDO $pdo, $tableName = 'locks') { - + public function __construct(\PDO $pdo, $tableName = 'locks') + { $this->pdo = $pdo; $this->tableName = $tableName; @@ -56,8 +56,8 @@ public function __construct(\PDO $pdo, $tableName = 'locks') { * @param bool $returnChildLocks * @return array */ - public function getLocks($uri, $returnChildLocks) { - + public function getLocks($uri, $returnChildLocks) + { // NOTE: the following 10 lines or so could be easily replaced by // pure sql. MySQL's non-standard string concatenation prevents us // from doing this though. @@ -72,7 +72,7 @@ public function getLocks($uri, $returnChildLocks) { $currentPath=''; - foreach($uriParts as $part) { + foreach ($uriParts as $part) { if ($currentPath) $currentPath.='/'; $currentPath.=$part; @@ -95,7 +95,7 @@ public function getLocks($uri, $returnChildLocks) { $result = $stmt->fetchAll(); $lockList = array(); - foreach($result as $row) { + foreach ($result as $row) { $lockInfo = new LockInfo(); $lockInfo->owner = $row['owner']; @@ -120,8 +120,8 @@ public function getLocks($uri, $returnChildLocks) { * @param LockInfo $lockInfo * @return bool */ - public function lock($uri, LockInfo $lockInfo) { - + public function lock($uri, LockInfo $lockInfo) + { // We're making the lock timeout 30 minutes $lockInfo->timeout = 30*60; $lockInfo->created = time(); @@ -129,7 +129,7 @@ public function lock($uri, LockInfo $lockInfo) { $locks = $this->getLocks($uri,false); $exists = false; - foreach($locks as $lock) { + foreach ($locks as $lock) { if ($lock->token == $lockInfo->token) $exists = true; } @@ -154,8 +154,8 @@ public function lock($uri, LockInfo $lockInfo) { * @param LockInfo $lockInfo * @return bool */ - public function unlock($uri, LockInfo $lockInfo) { - + public function unlock($uri, LockInfo $lockInfo) + { $stmt = $this->pdo->prepare('DELETE FROM '.$this->tableName.' WHERE uri = ? AND token = ?'); $stmt->execute(array($uri,$lockInfo->token)); @@ -164,4 +164,3 @@ public function unlock($uri, LockInfo $lockInfo) { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/LockInfo.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/LockInfo.php index ec254d821c..bc136d49ec 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/LockInfo.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/LockInfo.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class LockInfo { - +class LockInfo +{ /** * A shared lock */ @@ -78,4 +78,3 @@ class LockInfo { public $uri; } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Plugin.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Plugin.php index 82b84ba056..9459431225 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Plugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Locks/Plugin.php @@ -18,8 +18,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Plugin extends DAV\ServerPlugin { - +class Plugin extends DAV\ServerPlugin +{ /** * locksBackend * @@ -39,8 +39,8 @@ class Plugin extends DAV\ServerPlugin { * * @param Backend\BackendInterface $locksBackend */ - public function __construct(Backend\BackendInterface $locksBackend = null) { - + public function __construct(Backend\BackendInterface $locksBackend = null) + { $this->locksBackend = $locksBackend; } @@ -53,8 +53,8 @@ public function __construct(Backend\BackendInterface $locksBackend = null) { * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { $this->server = $server; $server->subscribeEvent('unknownMethod',array($this,'unknownMethod')); $server->subscribeEvent('beforeMethod',array($this,'beforeMethod'),50); @@ -70,8 +70,8 @@ public function initialize(DAV\Server $server) { * * @return string */ - public function getPluginName() { - + public function getPluginName() + { return 'locks'; } @@ -86,9 +86,9 @@ public function getPluginName() { * @param string $uri * @return bool */ - public function unknownMethod($method, $uri) { - - switch($method) { + public function unknownMethod($method, $uri) + { + switch ($method) { case 'LOCK' : $this->httpLock($uri); return false; case 'UNLOCK' : $this->httpUnlock($uri); return false; @@ -105,11 +105,11 @@ public function unknownMethod($method, $uri) { * @param array $newProperties * @return bool */ - public function afterGetProperties($path, &$newProperties) { + public function afterGetProperties($path, &$newProperties) + { + foreach ($newProperties[404] as $propName=>$discard) { - foreach($newProperties[404] as $propName=>$discard) { - - switch($propName) { + switch ($propName) { case '{DAV:}supportedlock' : $val = false; @@ -142,9 +142,9 @@ public function afterGetProperties($path, &$newProperties) { * @param string $uri * @return bool */ - public function beforeMethod($method, $uri) { - - switch($method) { + public function beforeMethod($method, $uri) + { + switch ($method) { case 'DELETE' : $lastLock = null; @@ -190,8 +190,8 @@ public function beforeMethod($method, $uri) { * @param string $uri * @return array */ - public function getHTTPMethods($uri) { - + public function getHTTPMethods($uri) + { if ($this->locksBackend) return array('LOCK','UNLOCK'); @@ -207,8 +207,8 @@ public function getHTTPMethods($uri) { * * @return array */ - public function getFeatures() { - + public function getFeatures() + { return array(2); } @@ -226,8 +226,8 @@ public function getFeatures() { * @param bool $returnChildLocks * @return array */ - public function getLocks($uri, $returnChildLocks = false) { - + public function getLocks($uri, $returnChildLocks = false) + { $lockList = array(); if ($this->locksBackend) @@ -251,8 +251,8 @@ public function getLocks($uri, $returnChildLocks = false) { * @param string $uri * @return void */ - protected function httpLock($uri) { - + protected function httpLock($uri) + { $lastLock = null; if (!$this->validateLock($uri,$lastLock)) { @@ -326,8 +326,8 @@ protected function httpLock($uri) { * @param string $uri * @return void */ - protected function httpUnlock($uri) { - + protected function httpUnlock($uri) + { $lockToken = $this->server->httpRequest->getHeader('Lock-Token'); // If the locktoken header is not supplied, we need to throw a bad request exception @@ -339,7 +339,7 @@ protected function httpUnlock($uri) { // header if ($lockToken[0]!=='<') $lockToken = '<' . $lockToken . '>'; - foreach($locks as $lock) { + foreach ($locks as $lock) { if ('token . '>' == $lockToken) { @@ -367,8 +367,8 @@ protected function httpUnlock($uri) { * @param LockInfo $lockInfo * @return bool */ - public function lockNode($uri,LockInfo $lockInfo) { - + public function lockNode($uri,LockInfo $lockInfo) + { if (!$this->server->broadcastEvent('beforeLock',array($uri,$lockInfo))) return; if ($this->locksBackend) return $this->locksBackend->lock($uri,$lockInfo); @@ -385,8 +385,8 @@ public function lockNode($uri,LockInfo $lockInfo) { * @param LockInfo $lockInfo * @return bool */ - public function unlockNode($uri, LockInfo $lockInfo) { - + public function unlockNode($uri, LockInfo $lockInfo) + { if (!$this->server->broadcastEvent('beforeUnlock',array($uri,$lockInfo))) return; if ($this->locksBackend) return $this->locksBackend->unlock($uri,$lockInfo); @@ -400,13 +400,13 @@ public function unlockNode($uri, LockInfo $lockInfo) { * * @return int */ - public function getTimeoutHeader() { - + public function getTimeoutHeader() + { $header = $this->server->httpRequest->getHeader('Timeout'); if ($header) { - if (stripos($header,'second-')===0) $header = (int)(substr($header,7)); + if (stripos($header,'second-')===0) $header = (int) (substr($header,7)); else if (strtolower($header)=='infinite') $header = LockInfo::TIMEOUT_INFINITE; else throw new DAV\Exception\BadRequest('Invalid HTTP timeout header'); @@ -426,8 +426,8 @@ public function getTimeoutHeader() { * @param LockInfo $lockInfo * @return string */ - protected function generateLockResponse(LockInfo $lockInfo) { - + protected function generateLockResponse(LockInfo $lockInfo) + { $dom = new \DOMDocument('1.0','utf-8'); $dom->formatOutput = true; @@ -453,8 +453,8 @@ protected function generateLockResponse(LockInfo $lockInfo) { * @param bool $checkChildLocks If set to true, this function will also look for any locks set on child resources of the supplied urls. This is needed for for example deletion of entire trees. * @return bool */ - protected function validateLock($urls = null,&$lastLock = null, $checkChildLocks = false) { - + protected function validateLock($urls = null,&$lastLock = null, $checkChildLocks = false) + { if (is_null($urls)) { $urls = array($this->server->getRequestUri()); } elseif (is_string($urls)) { @@ -466,7 +466,7 @@ protected function validateLock($urls = null,&$lastLock = null, $checkChildLocks $conditions = $this->getIfConditions(); // We're going to loop through the urls and make sure all lock conditions are satisfied - foreach($urls as $url) { + foreach ($urls as $url) { $locks = $this->getLocks($url, $checkChildLocks); @@ -480,7 +480,7 @@ protected function validateLock($urls = null,&$lastLock = null, $checkChildLocks // If there were no locks or conditions, we go to the next url if (!$locks && !$conditions) continue; - foreach($conditions as $condition) { + foreach ($conditions as $condition) { if (!$condition['uri']) { $conditionUri = $this->server->getRequestUri(); @@ -493,7 +493,7 @@ protected function validateLock($urls = null,&$lastLock = null, $checkChildLocks // The tokens array contians arrays with 2 elements. 0=true/false for normal/not condition, 1=locktoken // At least 1 condition has to be satisfied - foreach($condition['tokens'] as $conditionToken) { + foreach ($condition['tokens'] as $conditionToken) { $etagValid = true; $lockValid = true; @@ -512,7 +512,7 @@ protected function validateLock($urls = null,&$lastLock = null, $checkChildLocks $lockValid = false; // Match all the locks - foreach($locks as $lockIndex=>$lock) { + foreach ($locks as $lockIndex=>$lock) { $lockToken = 'opaquelocktoken:' . $lock->token; @@ -577,8 +577,8 @@ protected function validateLock($urls = null,&$lastLock = null, $checkChildLocks * * @return array */ - public function getIfConditions() { - + public function getIfConditions() + { $header = $this->server->httpRequest->getHeader('If'); if (!$header) return array(); @@ -589,7 +589,7 @@ public function getIfConditions() { $conditions = array(); - foreach($matches as $match) { + foreach ($matches as $match) { $condition = array( 'uri' => $match['uri'], @@ -619,8 +619,8 @@ public function getIfConditions() { * @param string $body * @return DAV\Locks\LockInfo */ - protected function parseLockRequest($body) { - + protected function parseLockRequest($body) + { $xml = simplexml_load_string( DAV\XMLUtil::convertDAVNamespace($body), null, @@ -629,7 +629,7 @@ protected function parseLockRequest($body) { $lockInfo = new LockInfo(); $children = $xml->children("urn:DAV"); - $lockInfo->owner = (string)$children->owner; + $lockInfo->owner = (string) $children->owner; $lockInfo->token = DAV\UUIDUtil::getUUID(); $lockInfo->scope = count($xml->xpath('d:lockscope/d:exclusive'))>0 ? LockInfo::EXCLUSIVE : LockInfo::SHARED; diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Mount/Plugin.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Mount/Plugin.php index 15d6129136..0a779196df 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Mount/Plugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Mount/Plugin.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Plugin extends DAV\ServerPlugin { - +class Plugin extends DAV\ServerPlugin +{ /** * Reference to Server class * @@ -28,8 +28,8 @@ class Plugin extends DAV\ServerPlugin { * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { $this->server = $server; $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'), 90); @@ -43,8 +43,8 @@ public function initialize(DAV\Server $server) { * @param string $uri * @return bool */ - public function beforeMethod($method, $uri) { - + public function beforeMethod($method, $uri) + { if ($method!='GET') return; if ($this->server->httpRequest->getQueryString()!='mount') return; @@ -66,8 +66,8 @@ public function beforeMethod($method, $uri) { * @param string $uri absolute uri * @return void */ - public function davMount($uri) { - + public function davMount($uri) + { $this->server->httpResponse->sendStatus(200); $this->server->httpResponse->setHeader('Content-Type','application/davmount+xml'); ob_start(); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Node.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Node.php index c553844407..48ce08425b 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Node.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Node.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class Node implements INode { - +abstract class Node implements INode +{ /** * Returns the last modification time * @@ -20,8 +20,8 @@ abstract class Node implements INode { * * @return int */ - public function getLastModified() { - + public function getLastModified() + { return time(); } @@ -32,8 +32,8 @@ public function getLastModified() { * @throws Sabre\DAV\Exception\Forbidden * @return void */ - public function delete() { - + public function delete() + { throw new Exception\Forbidden('Permission denied to delete node'); } @@ -45,11 +45,10 @@ public function delete() { * @param string $name The new name * @return void */ - public function setName($name) { - + public function setName($name) + { throw new Exception\Forbidden('Permission denied to rename file'); } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/ObjectTree.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/ObjectTree.php index 45fb80e93c..b3feb44e4e 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/ObjectTree.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/ObjectTree.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class ObjectTree extends Tree { - +class ObjectTree extends Tree +{ /** * The root node * @@ -34,8 +34,8 @@ class ObjectTree extends Tree { * * @param ICollection $rootNode */ - public function __construct(ICollection $rootNode) { - + public function __construct(ICollection $rootNode) + { $this->rootNode = $rootNode; } @@ -46,8 +46,8 @@ public function __construct(ICollection $rootNode) { * @param string $path * @return INode */ - public function getNodeForPath($path) { - + public function getNodeForPath($path) + { $path = trim($path,'/'); if (isset($this->cache[$path])) return $this->cache[$path]; @@ -84,8 +84,8 @@ public function getNodeForPath($path) { * @param string $path * @return bool */ - public function nodeExists($path) { - + public function nodeExists($path) + { try { // The root always exists @@ -111,11 +111,11 @@ public function nodeExists($path) { * @param string $path * @return array */ - public function getChildren($path) { - + public function getChildren($path) + { $node = $this->getNodeForPath($path); $children = $node->getChildren(); - foreach($children as $child) { + foreach ($children as $child) { $this->cache[trim($path,'/') . '/' . $child->getName()] = $child; @@ -142,12 +142,12 @@ public function getChildren($path) { * @param string $path * @return void */ - public function markDirty($path) { - + public function markDirty($path) + { // We don't care enough about sub-paths // flushing the entire cache $path = trim($path,'/'); - foreach($this->cache as $nodePath=>$node) { + foreach ($this->cache as $nodePath=>$node) { if ($nodePath == $path || strpos($nodePath,$path.'/')===0) unset($this->cache[$nodePath]); @@ -156,4 +156,3 @@ public function markDirty($path) { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/PartialUpdate/IFile.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/PartialUpdate/IFile.php index 41a6feb16d..dd4f1ddb94 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/PartialUpdate/IFile.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/PartialUpdate/IFile.php @@ -13,8 +13,8 @@ * @author Jean-Tiare LE BIGOT (http://www.jtlebi.fr/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IFile extends DAV\IFile { - +interface IFile extends DAV\IFile +{ /** * Updates the data at a given offset * @@ -34,7 +34,6 @@ interface IFile extends DAV\IFile { * @param integer $offset * @return string|null */ - function putRange($data, $offset); + public function putRange($data, $offset); } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/PartialUpdate/Plugin.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/PartialUpdate/Plugin.php index b35627df31..d80f7f06ab 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/PartialUpdate/Plugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/PartialUpdate/Plugin.php @@ -18,8 +18,8 @@ * @author Jean-Tiare LE BIGOT (http://www.jtlebi.fr/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Plugin extends DAV\ServerPlugin { - +class Plugin extends DAV\ServerPlugin +{ /** * Reference to server * @@ -35,8 +35,8 @@ class Plugin extends DAV\ServerPlugin { * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { $this->server = $server; $server->subscribeEvent('unknownMethod',array($this,'unknownMethod')); @@ -50,8 +50,8 @@ public function initialize(DAV\Server $server) { * * @return string */ - public function getPluginName() { - + public function getPluginName() + { return 'partialupdate'; } @@ -66,10 +66,10 @@ public function getPluginName() { * @param string $uri * @return bool|null */ - public function unknownMethod($method, $uri) { + public function unknownMethod($method, $uri) + { + switch ($method) { - switch($method) { - case 'PATCH': return $this->httpPatch($uri); @@ -83,7 +83,7 @@ public function unknownMethod($method, $uri) { * * This method is passed a uri. It should only return HTTP methods that are * available for the specified uri. - * + * * We claim to support PATCH method (partial update) if and only if * - the node exist * - the node implements our partial update interface @@ -91,15 +91,15 @@ public function unknownMethod($method, $uri) { * @param string $uri * @return array */ - public function getHTTPMethods($uri) { - + public function getHTTPMethods($uri) + { $tree = $this->server->tree; - - if ($tree->nodeExists($uri) && + + if ($tree->nodeExists($uri) && $tree->getNodeForPath($uri) instanceof IFile) { return array('PATCH'); } - + return array(); } @@ -109,8 +109,8 @@ public function getHTTPMethods($uri) { * * @return array */ - public function getFeatures() { - + public function getFeatures() + { return array('sabredav-partialupdate'); } @@ -118,15 +118,15 @@ public function getFeatures() { /** * Patch an uri * - * The WebDAV patch request can be used to modify only a part of an + * The WebDAV patch request can be used to modify only a part of an * existing resource. If the resource does not exist yet and the first * offset is not 0, the request fails * * @param string $uri * @return void */ - protected function httpPatch($uri) { - + protected function httpPatch($uri) + { // Get the node. Will throw a 404 if not found $node = $this->server->tree->getNodeForPath($uri); if (!($node instanceof IFile)) { @@ -138,11 +138,11 @@ protected function httpPatch($uri) { if (!$range) { throw new DAV\Exception\BadRequest('No valid "X-Update-Range" found in the headers'); } - + $contentType = strtolower( $this->server->httpRequest->getHeader('Content-Type') ); - + if ($contentType != 'application/x-sabredav-partialupdate') { throw new DAV\Exception\UnsupportedMediaType('Unknown Content-Type header "' . $contentType . '"'); } @@ -177,7 +177,7 @@ protected function httpPatch($uri) { return false; } - + /** * Returns the HTTP custom range update header * @@ -192,8 +192,8 @@ protected function httpPatch($uri) { * * @return array|null */ - public function getHTTPUpdateRange() { - + public function getHTTPUpdateRange() + { $range = $this->server->httpRequest->getHeader('X-Update-Range'); if (is_null($range)) return null; diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property.php index a4cbbed7af..e13266ebc6 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class Property implements PropertyInterface { - +abstract class Property implements PropertyInterface +{ /** * Unserializes the property. * @@ -21,11 +21,10 @@ abstract class Property implements PropertyInterface { * @param \DOMElement $prop * @return DAV\IProperty */ - static function unserialize(\DOMElement $prop) { - + public static function unserialize(\DOMElement $prop) + { throw new Exception('Unserialize has not been implemented for this class'); } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/GetLastModified.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/GetLastModified.php index 4c66e24e0a..cd84856b5e 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/GetLastModified.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/GetLastModified.php @@ -18,8 +18,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class GetLastModified extends DAV\Property { - +class GetLastModified extends DAV\Property +{ /** * time * @@ -32,8 +32,8 @@ class GetLastModified extends DAV\Property { * * @param int|DateTime $time */ - public function __construct($time) { - + public function __construct($time) + { if ($time instanceof \DateTime) { $this->time = $time; } elseif (is_int($time) || ctype_digit($time)) { @@ -54,8 +54,8 @@ public function __construct($time) { * @param \DOMElement $prop * @return void */ - public function serialize(DAV\Server $server, \DOMElement $prop) { - + public function serialize(DAV\Server $server, \DOMElement $prop) + { $doc = $prop->ownerDocument; //$prop->setAttribute('xmlns:b','urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/'); //$prop->setAttribute('b:dt','dateTime.rfc1123'); @@ -68,11 +68,10 @@ public function serialize(DAV\Server $server, \DOMElement $prop) { * * @return \DateTime */ - public function getTime() { - + public function getTime() + { return $this->time; } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/Href.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/Href.php index 726f35ac79..41e1d504b4 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/Href.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/Href.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Href extends DAV\Property implements IHref { - +class Href extends DAV\Property implements IHref +{ /** * href * @@ -36,8 +36,8 @@ class Href extends DAV\Property implements IHref { * @param string $href * @param bool $autoPrefix */ - public function __construct($href, $autoPrefix = true) { - + public function __construct($href, $autoPrefix = true) + { $this->href = $href; $this->autoPrefix = $autoPrefix; @@ -48,8 +48,8 @@ public function __construct($href, $autoPrefix = true) { * * @return string */ - public function getHref() { - + public function getHref() + { return $this->href; } @@ -63,8 +63,8 @@ public function getHref() { * @param \DOMElement $dom * @return void */ - public function serialize(DAV\Server $server, \DOMElement $dom) { - + public function serialize(DAV\Server $server, \DOMElement $dom) + { $prefix = $server->xmlNamespaces['DAV:']; $elem = $dom->ownerDocument->createElement($prefix . ':href'); @@ -82,8 +82,8 @@ public function serialize(DAV\Server $server, \DOMElement $dom) { * @param \DOMElement $dom * @return DAV\Property\Href */ - static function unserialize(\DOMElement $dom) { - + public static function unserialize(\DOMElement $dom) + { if ($dom->firstChild && DAV\XMLUtil::toClarkNotation($dom->firstChild)==='{DAV:}href') { return new self($dom->firstChild->textContent,false); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/HrefList.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/HrefList.php index f27ee75503..a93aae3696 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/HrefList.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/HrefList.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class HrefList extends DAV\Property { - +class HrefList extends DAV\Property +{ /** * hrefs * @@ -35,8 +35,8 @@ class HrefList extends DAV\Property { * @param array $hrefs * @param bool $autoPrefix */ - public function __construct(array $hrefs, $autoPrefix = true) { - + public function __construct(array $hrefs, $autoPrefix = true) + { $this->hrefs = $hrefs; $this->autoPrefix = $autoPrefix; @@ -47,8 +47,8 @@ public function __construct(array $hrefs, $autoPrefix = true) { * * @return array */ - public function getHrefs() { - + public function getHrefs() + { return $this->hrefs; } @@ -62,11 +62,11 @@ public function getHrefs() { * @param \DOMElement $dom * @return void */ - public function serialize(DAV\Server $server,\DOMElement $dom) { - + public function serialize(DAV\Server $server,\DOMElement $dom) + { $prefix = $server->xmlNamespaces['DAV:']; - foreach($this->hrefs as $href) { + foreach ($this->hrefs as $href) { $elem = $dom->ownerDocument->createElement($prefix . ':href'); $elem->nodeValue = ($this->autoPrefix?$server->getBaseUri():'') . $href; $dom->appendChild($elem); @@ -83,10 +83,10 @@ public function serialize(DAV\Server $server,\DOMElement $dom) { * @param \DOMElement $dom * @return DAV\Property\HrefList */ - static function unserialize(\DOMElement $dom) { - + public static function unserialize(\DOMElement $dom) + { $hrefs = array(); - foreach($dom->childNodes as $child) { + foreach ($dom->childNodes as $child) { if (DAV\XMLUtil::toClarkNotation($child)==='{DAV:}href') { $hrefs[] = $child->textContent; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/IHref.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/IHref.php index 6fadb50792..1f549db654 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/IHref.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/IHref.php @@ -13,13 +13,13 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IHref { - +interface IHref +{ /** * getHref * * @return string */ - function getHref(); + public function getHref(); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/LockDiscovery.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/LockDiscovery.php index 0a29574416..a24fd114be 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/LockDiscovery.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/LockDiscovery.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class LockDiscovery extends DAV\Property { - +class LockDiscovery extends DAV\Property +{ /** * locks * @@ -35,7 +35,7 @@ class LockDiscovery extends DAV\Property { * It was reported that showing the lockroot in the response can break * Office 2000 compatibility. */ - static public $hideLockRoot = false; + public static $hideLockRoot = false; /** * __construct @@ -43,8 +43,8 @@ class LockDiscovery extends DAV\Property { * @param array $locks * @param bool $revealLockToken */ - public function __construct($locks, $revealLockToken = false) { - + public function __construct($locks, $revealLockToken = false) + { $this->locks = $locks; $this->revealLockToken = $revealLockToken; @@ -57,11 +57,11 @@ public function __construct($locks, $revealLockToken = false) { * @param \DOMElement $prop * @return void */ - public function serialize(DAV\Server $server, \DOMElement $prop) { - + public function serialize(DAV\Server $server, \DOMElement $prop) + { $doc = $prop->ownerDocument; - foreach($this->locks as $lock) { + foreach ($this->locks as $lock) { $activeLock = $doc->createElementNS('DAV:','d:activelock'); $prop->appendChild($activeLock); @@ -101,4 +101,3 @@ public function serialize(DAV\Server $server, \DOMElement $prop) { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/ResourceType.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/ResourceType.php index a0e6608c7c..5752c3a5e3 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/ResourceType.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/ResourceType.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class ResourceType extends DAV\Property { - +class ResourceType extends DAV\Property +{ /** * resourceType * @@ -28,8 +28,8 @@ class ResourceType extends DAV\Property { * * @param mixed $resourceType */ - public function __construct($resourceType = array()) { - + public function __construct($resourceType = array()) + { if ($resourceType === DAV\Server::NODE_FILE) $this->resourceType = array(); elseif ($resourceType === DAV\Server::NODE_DIRECTORY) @@ -48,12 +48,12 @@ public function __construct($resourceType = array()) { * @param \DOMElement $prop * @return void */ - public function serialize(DAV\Server $server, \DOMElement $prop) { - + public function serialize(DAV\Server $server, \DOMElement $prop) + { $propName = null; $rt = $this->resourceType; - foreach($rt as $resourceType) { + foreach ($rt as $resourceType) { if (preg_match('/^{([^}]*)}(.*)$/',$resourceType,$propName)) { if (isset($server->xmlNamespaces[$propName[1]])) { @@ -74,8 +74,8 @@ public function serialize(DAV\Server $server, \DOMElement $prop) { * * @return array */ - public function getValue() { - + public function getValue() + { return $this->resourceType; } @@ -86,8 +86,8 @@ public function getValue() { * @param string $type * @return bool */ - public function is($type) { - + public function is($type) + { return in_array($type, $this->resourceType); } @@ -98,8 +98,8 @@ public function is($type) { * @param string $type * @return void */ - public function add($type) { - + public function add($type) + { $this->resourceType[] = $type; $this->resourceType = array_unique($this->resourceType); @@ -111,10 +111,10 @@ public function add($type) { * @param \DOMElement $dom * @return DAV\Property\ResourceType */ - static public function unserialize(\DOMElement $dom) { - + public static function unserialize(\DOMElement $dom) + { $value = array(); - foreach($dom->childNodes as $child) { + foreach ($dom->childNodes as $child) { $value[] = DAV\XMLUtil::toClarkNotation($child); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/Response.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/Response.php index 29289ed9ab..01bce38bb7 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/Response.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/Response.php @@ -15,8 +15,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Response extends DAV\Property implements IHref { - +class Response extends DAV\Property implements IHref +{ /** * Url for the response * @@ -38,8 +38,8 @@ class Response extends DAV\Property implements IHref { * @param string $href * @param array $responseProperties */ - public function __construct($href, array $responseProperties) { - + public function __construct($href, array $responseProperties) + { $this->href = $href; $this->responseProperties = $responseProperties; @@ -50,8 +50,8 @@ public function __construct($href, array $responseProperties) { * * @return string */ - public function getHref() { - + public function getHref() + { return $this->href; } @@ -61,8 +61,8 @@ public function getHref() { * * @return array */ - public function getResponseProperties() { - + public function getResponseProperties() + { return $this->responseProperties; } @@ -74,8 +74,8 @@ public function getResponseProperties() { * @param \DOMElement $dom * @return void */ - public function serialize(DAV\Server $server, \DOMElement $dom) { - + public function serialize(DAV\Server $server, \DOMElement $dom) + { $document = $dom->ownerDocument; $properties = $this->responseProperties; @@ -91,7 +91,7 @@ public function serialize(DAV\Server $server, \DOMElement $dom) { // The properties variable is an array containing properties, grouped by // HTTP status - foreach($properties as $httpStatus=>$propertyGroup) { + foreach ($properties as $httpStatus=>$propertyGroup) { // The 'href' is also in this array, and it's special cased. // We will ignore it @@ -108,7 +108,7 @@ public function serialize(DAV\Server $server, \DOMElement $dom) { $nsList = $server->xmlNamespaces; - foreach($propertyGroup as $propertyName=>$propertyValue) { + foreach ($propertyGroup as $propertyName=>$propertyValue) { $propName = null; preg_match('/^{([^}]*)}(.*)$/',$propertyName,$propName); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/ResponseList.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/ResponseList.php index 2497d4fa90..f946e838e9 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/ResponseList.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/ResponseList.php @@ -15,8 +15,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class ResponseList extends DAV\Property { - +class ResponseList extends DAV\Property +{ /** * Response objects. * @@ -30,9 +30,9 @@ class ResponseList extends DAV\Property { * * @param array $responses; */ - public function __construct($responses) { - - foreach($responses as $response) { + public function __construct($responses) + { + foreach ($responses as $response) { if (!($response instanceof Response)) { throw new \InvalidArgumentException('You must pass an array of Sabre\DAV\Property\Response objects'); } @@ -48,9 +48,9 @@ public function __construct($responses) { * @param \DOMElement $dom * @return void */ - public function serialize(DAV\Server $server,\DOMElement $dom) { - - foreach($this->responses as $response) { + public function serialize(DAV\Server $server,\DOMElement $dom) + { + foreach ($this->responses as $response) { $response->serialize($server, $dom); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/SupportedLock.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/SupportedLock.php index 475c27c972..74be3d95d5 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/SupportedLock.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/SupportedLock.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SupportedLock extends DAV\Property { - +class SupportedLock extends DAV\Property +{ /** * supportsLocks * @@ -28,8 +28,8 @@ class SupportedLock extends DAV\Property { * * @param mixed $supportsLocks */ - public function __construct($supportsLocks) { - + public function __construct($supportsLocks) + { $this->supportsLocks = $supportsLocks; } @@ -41,8 +41,8 @@ public function __construct($supportsLocks) { * @param \DOMElement $prop * @return void */ - public function serialize(DAV\Server $server,\DOMElement $prop) { - + public function serialize(DAV\Server $server,\DOMElement $prop) + { $doc = $prop->ownerDocument; if (!$this->supportsLocks) return null; @@ -75,4 +75,3 @@ public function serialize(DAV\Server $server,\DOMElement $prop) { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/SupportedReportSet.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/SupportedReportSet.php index f460451cbf..3c1baa051c 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/SupportedReportSet.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Property/SupportedReportSet.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SupportedReportSet extends DAV\Property { - +class SupportedReportSet extends DAV\Property +{ /** * List of reports * @@ -33,8 +33,8 @@ class SupportedReportSet extends DAV\Property { * * @param mixed $reports */ - public function __construct($reports = null) { - + public function __construct($reports = null) + { if (!is_null($reports)) $this->addReport($reports); @@ -49,11 +49,11 @@ public function __construct($reports = null) { * @param mixed $report * @return void */ - public function addReport($report) { - + public function addReport($report) + { if (!is_array($report)) $report = array($report); - foreach($report as $r) { + foreach ($report as $r) { if (!preg_match('/^{([^}]*)}(.*)$/',$r)) throw new DAV\Exception('Reportname must be in clark-notation'); @@ -69,8 +69,8 @@ public function addReport($report) { * * @return array */ - public function getValue() { - + public function getValue() + { return $this->reports; } @@ -82,9 +82,9 @@ public function getValue() { * @param \DOMElement $prop * @return void */ - public function serialize(DAV\Server $server, \DOMElement $prop) { - - foreach($this->reports as $reportName) { + public function serialize(DAV\Server $server, \DOMElement $prop) + { + foreach ($this->reports as $reportName) { $supportedReport = $prop->ownerDocument->createElement('d:supported-report'); $prop->appendChild($supportedReport); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/PropertyInterface.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/PropertyInterface.php index af20f707a2..c8b1ce15aa 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/PropertyInterface.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/PropertyInterface.php @@ -11,11 +11,10 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface PropertyInterface { - +interface PropertyInterface +{ public function serialize(Server $server, \DOMElement $prop); - static function unserialize(\DOMElement $prop); + public static function unserialize(\DOMElement $prop); } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Server.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Server.php index da51bdbb4a..29cc040011 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Server.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Server.php @@ -10,8 +10,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Server { - +class Server +{ /** * Infinity is used for some request supporting the HTTP Depth header and indicates that the operation should traverse the entire tree */ @@ -147,7 +147,7 @@ class Server { * * @var bool */ - static public $exposeVersion = true; + public static $exposeVersion = true; /** * Sets up the server @@ -164,8 +164,8 @@ class Server { * * @param Tree|INode|array|null $treeOrNode The tree object */ - public function __construct($treeOrNode = null) { - + public function __construct($treeOrNode = null) + { if ($treeOrNode instanceof Tree) { $this->tree = $treeOrNode; } elseif ($treeOrNode instanceof INode) { @@ -174,7 +174,7 @@ public function __construct($treeOrNode = null) { // If it's an array, a list of nodes was passed, and we need to // create the root node. - foreach($treeOrNode as $node) { + foreach ($treeOrNode as $node) { if (!($node instanceof INode)) { throw new Exception('Invalid argument passed to constructor. If you\'re passing an array, all the values must implement Sabre\\DAV\\INode'); } @@ -199,8 +199,8 @@ public function __construct($treeOrNode = null) { * * @return void */ - public function exec() { - + public function exec() + { try { // If nginx (pre-1.2) is used as a proxy server, and SabreDAV as an @@ -245,7 +245,7 @@ public function exec() { $error->appendChild($DOM->createElement('s:sabredav-version',$h(Version::VERSION))); } - if($e instanceof Exception) { + if ($e instanceof Exception) { $httpCode = $e->getHTTPCode(); $e->serialize($this,$error); @@ -273,8 +273,8 @@ public function exec() { * @param string $uri * @return void */ - public function setBaseUri($uri) { - + public function setBaseUri($uri) + { // If the baseUri does not end with a slash, we must add it if ($uri[strlen($uri)-1]!=='/') $uri.='/'; @@ -288,8 +288,8 @@ public function setBaseUri($uri) { * * @return string */ - public function getBaseUri() { - + public function getBaseUri() + { if (is_null($this->baseUri)) $this->baseUri = $this->guessBaseUri(); return $this->baseUri; @@ -303,8 +303,8 @@ public function getBaseUri() { * * @return string */ - public function guessBaseUri() { - + public function guessBaseUri() + { $pathInfo = $this->httpRequest->getRawServerValue('PATH_INFO'); $uri = $this->httpRequest->getRawServerValue('REQUEST_URI'); @@ -323,7 +323,7 @@ public function guessBaseUri() { $decodedUri = URLUtil::decodePath($uri); // A simple sanity check: - if(substr($decodedUri,strlen($decodedUri)-strlen($pathInfo))===$pathInfo) { + if (substr($decodedUri,strlen($decodedUri)-strlen($pathInfo))===$pathInfo) { $baseUri = substr($decodedUri,0,strlen($decodedUri)-strlen($pathInfo)); return rtrim($baseUri,'/') . '/'; } @@ -345,8 +345,8 @@ public function guessBaseUri() { * @param ServerPlugin $plugin * @return void */ - public function addPlugin(ServerPlugin $plugin) { - + public function addPlugin(ServerPlugin $plugin) + { $this->plugins[$plugin->getPluginName()] = $plugin; $plugin->initialize($this); @@ -360,13 +360,13 @@ public function addPlugin(ServerPlugin $plugin) { * @param string $name * @return ServerPlugin */ - public function getPlugin($name) { - + public function getPlugin($name) + { if (isset($this->plugins[$name])) return $this->plugins[$name]; // This is a fallback and deprecated. - foreach($this->plugins as $plugin) { + foreach ($this->plugins as $plugin) { if (get_class($plugin)===$name) return $plugin; } @@ -379,8 +379,8 @@ public function getPlugin($name) { * * @return array */ - public function getPlugins() { - + public function getPlugins() + { return $this->plugins; } @@ -402,8 +402,8 @@ public function getPlugins() { * @param int $priority * @return void */ - public function subscribeEvent($event, $callback, $priority = 100) { - + public function subscribeEvent($event, $callback, $priority = 100) + { if (!isset($this->eventSubscriptions[$event])) { $this->eventSubscriptions[$event] = array(); } @@ -424,11 +424,11 @@ public function subscribeEvent($event, $callback, $priority = 100) { * @param array $arguments * @return bool */ - public function broadcastEvent($eventName,$arguments = array()) { - + public function broadcastEvent($eventName,$arguments = array()) + { if (isset($this->eventSubscriptions[$eventName])) { - foreach($this->eventSubscriptions[$eventName] as $subscriber) { + foreach ($this->eventSubscriptions[$eventName] as $subscriber) { $result = call_user_func_array($subscriber,$arguments); if ($result===false) return false; @@ -448,8 +448,8 @@ public function broadcastEvent($eventName,$arguments = array()) { * @param string $uri * @return void */ - public function invokeMethod($method, $uri) { - + public function invokeMethod($method, $uri) + { $method = strtoupper($method); if (!$this->broadcastEvent('beforeMethod',array($method, $uri))) return; @@ -492,8 +492,8 @@ public function invokeMethod($method, $uri) { * @param string $uri * @return void */ - protected function httpOptions($uri) { - + protected function httpOptions($uri) + { $methods = $this->getAllowedMethods($uri); $this->httpResponse->setHeader('Allow',strtoupper(implode(', ',$methods))); @@ -520,8 +520,8 @@ protected function httpOptions($uri) { * @param string $uri * @return bool */ - protected function httpGet($uri) { - + protected function httpGet($uri) + { $node = $this->tree->getNodeForPath($uri,0); if (!$this->checkPreconditions(true)) return false; @@ -658,8 +658,8 @@ protected function httpGet($uri) { * @param string $uri * @return void */ - protected function httpHead($uri) { - + protected function httpHead($uri) + { $node = $this->tree->getNodeForPath($uri); /* This information is only collection for File objects. * Ideally we want to throw 405 Method Not Allowed for every @@ -684,8 +684,8 @@ protected function httpHead($uri) { * @param string $uri * @return void */ - protected function httpDelete($uri) { - + protected function httpDelete($uri) + { if (!$this->broadcastEvent('beforeUnbind',array($uri))) return; $this->tree->delete($uri); $this->broadcastEvent('afterUnbind',array($uri)); @@ -711,8 +711,8 @@ protected function httpDelete($uri) { * @param string $uri * @return void */ - protected function httpPropfind($uri) { - + protected function httpPropfind($uri) + { $requestedProperties = $this->parsePropFindRequest($this->httpRequest->getBody(true)); $depth = $this->getHTTPDepth(1); @@ -750,8 +750,8 @@ protected function httpPropfind($uri) { * @param string $uri * @return void */ - protected function httpPropPatch($uri) { - + protected function httpPropPatch($uri) + { $newProperties = $this->parsePropPatchRequest($this->httpRequest->getBody(true)); $result = $this->updateProperties($uri, $newProperties); @@ -765,8 +765,8 @@ protected function httpPropPatch($uri) { // request was succesful, and don't need to return the // multi-status. $ok = true; - foreach($result as $code=>$prop) { - if ((int)$code > 299) { + foreach ($result as $code=>$prop) { + if ((int) $code > 299) { $ok = false; } } @@ -799,8 +799,8 @@ protected function httpPropPatch($uri) { * @param string $uri * @return bool */ - protected function httpPut($uri) { - + protected function httpPut($uri) + { $body = $this->httpRequest->getBody(); // Intercepting Content-Range @@ -920,8 +920,8 @@ protected function httpPut($uri) { * @param string $uri * @return void */ - protected function httpMkcol($uri) { - + protected function httpMkcol($uri) + { $requestBody = $this->httpRequest->getBody(true); if ($requestBody) { @@ -943,7 +943,7 @@ protected function httpMkcol($uri) { } $properties = array(); - foreach($dom->firstChild->childNodes as $childNode) { + foreach ($dom->firstChild->childNodes as $childNode) { if (XMLUtil::toClarkNotation($childNode)!=='{DAV:}set') continue; $properties = array_merge($properties, XMLUtil::parseProperties($childNode, $this->propertyMap)); @@ -987,8 +987,8 @@ protected function httpMkcol($uri) { * @param string $uri * @return bool */ - protected function httpMove($uri) { - + protected function httpMove($uri) + { $moveInfo = $this->getCopyAndMoveInfo(); // If the destination is part of the source tree, we must fail @@ -1024,8 +1024,8 @@ protected function httpMove($uri) { * @param string $uri * @return bool */ - protected function httpCopy($uri) { - + protected function httpCopy($uri) + { $copyInfo = $this->getCopyAndMoveInfo(); // If the destination is part of the source tree, we must fail if ($copyInfo['destination']==$uri) @@ -1057,8 +1057,8 @@ protected function httpCopy($uri) { * @param string $uri * @return void */ - protected function httpReport($uri) { - + protected function httpReport($uri) + { $body = $this->httpRequest->getBody(true); $dom = XMLUtil::loadDOMDocument($body); @@ -1082,8 +1082,8 @@ protected function httpReport($uri) { * @param string $uri * @return array */ - public function getAllowedMethods($uri) { - + public function getAllowedMethods($uri) + { $methods = array( 'OPTIONS', 'GET', @@ -1117,8 +1117,8 @@ public function getAllowedMethods($uri) { * * @return string */ - public function getRequestUri() { - + public function getRequestUri() + { return $this->calculateUri($this->httpRequest->getUri()); } @@ -1130,8 +1130,8 @@ public function getRequestUri() { * @throws Exception\Forbidden A permission denied exception is thrown whenever there was an attempt to supply a uri outside of the base uri * @return string */ - public function calculateUri($uri) { - + public function calculateUri($uri) + { if ($uri[0]!='/' && strpos($uri,'://')) { $uri = parse_url($uri,PHP_URL_PATH); @@ -1167,8 +1167,8 @@ public function calculateUri($uri) { * @param mixed $default * @return int */ - public function getHTTPDepth($default = self::DEPTH_INFINITY) { - + public function getHTTPDepth($default = self::DEPTH_INFINITY) + { // If its not set, we'll grab the default $depth = $this->httpRequest->getHeader('Depth'); @@ -1180,7 +1180,7 @@ public function getHTTPDepth($default = self::DEPTH_INFINITY) { // If its an unknown value. we'll grab the default if (!ctype_digit($depth)) return $default; - return (int)$depth; + return (int) $depth; } @@ -1198,8 +1198,8 @@ public function getHTTPDepth($default = self::DEPTH_INFINITY) { * * @return array|null */ - public function getHTTPRange() { - + public function getHTTPRange() + { $range = $this->httpRequest->getHeader('range'); if (is_null($range)) return null; @@ -1242,8 +1242,8 @@ public function getHTTPRange() { * * @return array */ - public function getHTTPPrefer() { - + public function getHTTPPrefer() + { $result = array( 'return-asynch' => false, 'return-minimal' => false, @@ -1259,16 +1259,16 @@ public function getHTTPPrefer() { explode(',', $prefer) ); - foreach($parameters as $parameter) { + foreach ($parameters as $parameter) { // Right now our regex only supports the tokens actually // specified in the draft. We may need to expand this if new // tokens get registered. - if(!preg_match('/^(?P[a-z0-9-]+)(?:=(?P[0-9]+))?$/', $parameter, $matches)) { + if (!preg_match('/^(?P[a-z0-9-]+)(?:=(?P[0-9]+))?$/', $parameter, $matches)) { continue; } - switch($matches['token']) { + switch ($matches['token']) { case 'return-asynch' : case 'return-minimal' : @@ -1308,8 +1308,8 @@ public function getHTTPPrefer() { * * @return array */ - public function getCopyAndMoveInfo() { - + public function getCopyAndMoveInfo() + { // Collecting the relevant HTTP headers if (!$this->httpRequest->getHeader('Destination')) throw new Exception\BadRequest('The destination header was not supplied'); $destination = $this->calculateUri($this->httpRequest->getHeader('Destination')); @@ -1367,8 +1367,8 @@ public function getCopyAndMoveInfo() { * @param string $path * @param array $propertyNames */ - public function getProperties($path, $propertyNames) { - + public function getProperties($path, $propertyNames) + { $result = $this->getPropertiesForPath($path,$propertyNames,0); return $result[0][200]; @@ -1386,10 +1386,10 @@ public function getProperties($path, $propertyNames) { * @param array $propertyNames * @return array */ - public function getPropertiesForChildren($path, $propertyNames) { - + public function getPropertiesForChildren($path, $propertyNames) + { $result = array(); - foreach($this->getPropertiesForPath($path,$propertyNames,1) as $k=>$row) { + foreach ($this->getPropertiesForPath($path,$propertyNames,1) as $k=>$row) { // Skipping the parent path if ($k === 0) continue; @@ -1413,8 +1413,8 @@ public function getPropertiesForChildren($path, $propertyNames) { * @param string $path * @return array */ - public function getHTTPHeaders($path) { - + public function getHTTPHeaders($path) + { $propertyMap = array( '{DAV:}getcontenttype' => 'Content-Type', '{DAV:}getcontentlength' => 'Content-Length', @@ -1425,7 +1425,7 @@ public function getHTTPHeaders($path) { $properties = $this->getProperties($path,array_keys($propertyMap)); $headers = array(); - foreach($propertyMap as $property=>$header) { + foreach ($propertyMap as $property=>$header) { if (!isset($properties[$property])) continue; if (is_scalar($properties[$property])) { @@ -1456,8 +1456,8 @@ public function getHTTPHeaders($path) { * @param int $depth * @return array */ - public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0) { - + public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0) + { if ($depth!=0) $depth = 1; $path = rtrim($path,'/'); @@ -1478,7 +1478,7 @@ public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0 // sensible list. $allProperties = count($propertyNames)==0; - foreach($nodes as $myPath=>$node) { + foreach ($nodes as $myPath=>$node) { $currentPropertyNames = $propertyNames; @@ -1526,7 +1526,7 @@ public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0 // So as we loop through this list, we will only take the // properties that were actually requested and discard the // rest. - foreach($currentPropertyNames as $k=>$currentPropertyName) { + foreach ($currentPropertyNames as $k=>$currentPropertyName) { if (isset($nodeProperties[$currentPropertyName])) { unset($currentPropertyNames[$k]); $newProperties[200][$currentPropertyName] = $nodeProperties[$currentPropertyName]; @@ -1537,17 +1537,17 @@ public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0 } - foreach($currentPropertyNames as $prop) { + foreach ($currentPropertyNames as $prop) { if (isset($newProperties[200][$prop])) continue; - switch($prop) { + switch ($prop) { case '{DAV:}getlastmodified' : if ($node->getLastModified()) $newProperties[200][$prop] = new Property\GetLastModified($node->getLastModified()); break; case '{DAV:}getcontentlength' : if ($node instanceof IFile) { $size = $node->getSize(); if (!is_null($size)) { - $newProperties[200][$prop] = (int)$node->getSize(); + $newProperties[200][$prop] = (int) $node->getSize(); } } break; @@ -1567,14 +1567,14 @@ public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0 case '{DAV:}getcontenttype' : if ($node instanceof IFile && $ct = $node->getContentType()) $newProperties[200][$prop] = $ct; break; case '{DAV:}supported-report-set' : $reports = array(); - foreach($this->plugins as $plugin) { + foreach ($this->plugins as $plugin) { $reports = array_merge($reports, $plugin->getSupportedReportSet($myPath)); } $newProperties[200][$prop] = new Property\SupportedReportSet($reports); break; case '{DAV:}resourcetype' : $newProperties[200]['{DAV:}resourcetype'] = new Property\ResourceType(); - foreach($this->resourceTypeMapping as $className => $resourceType) { + foreach ($this->resourceTypeMapping as $className => $resourceType) { if ($node instanceof $className) $newProperties[200]['{DAV:}resourcetype']->add($resourceType); } break; @@ -1625,8 +1625,8 @@ public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0 * @param string $etag * @return bool */ - public function createFile($uri,$data, &$etag = null) { - + public function createFile($uri,$data, &$etag = null) + { list($dir,$name) = URLUtil::splitPath($uri); if (!$this->broadcastEvent('beforeBind',array($uri))) return false; @@ -1653,8 +1653,8 @@ public function createFile($uri,$data, &$etag = null) { * @param string $uri * @return void */ - public function createDirectory($uri) { - + public function createDirectory($uri) + { $this->createCollection($uri,array('{DAV:}collection'),array()); } @@ -1672,8 +1672,8 @@ public function createDirectory($uri) { * @param array $properties A list of properties * @return array|null */ - public function createCollection($uri, array $resourceType, array $properties) { - + public function createCollection($uri, array $resourceType, array $properties) + { list($parentUri,$newName) = URLUtil::splitPath($uri); // Making sure {DAV:}collection was specified as resourceType @@ -1785,8 +1785,8 @@ public function createCollection($uri, array $resourceType, array $properties) { * @param array $properties * @return array */ - public function updateProperties($uri, array $properties) { - + public function updateProperties($uri, array $properties) + { // we'll start by grabbing the node, this will throw the appropriate // exceptions if it doesn't. $node = $this->tree->getNodeForPath($uri); @@ -1800,8 +1800,8 @@ public function updateProperties($uri, array $properties) { $hasError = false; // Running through all properties to make sure none of them are protected - if (!$hasError) foreach($properties as $propertyName => $value) { - if(in_array($propertyName, $this->protectedProperties)) { + if (!$hasError) foreach ($properties as $propertyName => $value) { + if (in_array($propertyName, $this->protectedProperties)) { $result[403][$propertyName] = null; unset($remainingProperties[$propertyName]); $hasError = true; @@ -1821,7 +1821,7 @@ public function updateProperties($uri, array $properties) { // property is 403 Forbidden if (!$hasError && count($remainingProperties) && !($node instanceof IProperties)) { $hasError = true; - foreach($properties as $propertyName=> $value) { + foreach ($properties as $propertyName=> $value) { $result[403][$propertyName] = null; } $remainingProperties = array(); @@ -1836,14 +1836,14 @@ public function updateProperties($uri, array $properties) { if ($updateResult===true) { // success - foreach($remainingProperties as $propertyName=>$value) { + foreach ($remainingProperties as $propertyName=>$value) { $result[200][$propertyName] = null; } } elseif ($updateResult===false) { // The node failed to update the properties for an // unknown reason - foreach($remainingProperties as $propertyName=>$value) { + foreach ($remainingProperties as $propertyName=>$value) { $result[403][$propertyName] = null; } @@ -1851,7 +1851,7 @@ public function updateProperties($uri, array $properties) { // The node has detailed update information // We need to merge the results with the earlier results. - foreach($updateResult as $status => $props) { + foreach ($updateResult as $status => $props) { if (is_array($props)) { if (!isset($result[$status])) $result[$status] = array(); @@ -1868,14 +1868,14 @@ public function updateProperties($uri, array $properties) { } - foreach($remainingProperties as $propertyName=>$value) { + foreach ($remainingProperties as $propertyName=>$value) { // if there are remaining properties, it must mean // there's a dependency failure $result[424][$propertyName] = null; } // Removing empty array values - foreach($result as $status=>$props) { + foreach ($result as $status=>$props) { if (count($props)===0) unset($result[$status]); @@ -1910,8 +1910,8 @@ public function updateProperties($uri, array $properties) { * @param bool $handleAsGET * @return bool */ - public function checkPreconditions($handleAsGET = false) { - + public function checkPreconditions($handleAsGET = false) + { $uri = $this->getRequestUri(); $node = null; $lastMod = null; @@ -1935,7 +1935,7 @@ public function checkPreconditions($handleAsGET = false) { // There can be multiple etags $ifMatch = explode(',',$ifMatch); $haveMatch = false; - foreach($ifMatch as $ifMatchItem) { + foreach ($ifMatch as $ifMatchItem) { // Stripping any extra spaces $ifMatchItem = trim($ifMatchItem,' '); @@ -1981,7 +1981,7 @@ public function checkPreconditions($handleAsGET = false) { $ifNoneMatch = explode(',', $ifNoneMatch); $etag = $node->getETag(); - foreach($ifNoneMatch as $ifNoneMatchItem) { + foreach ($ifNoneMatch as $ifNoneMatchItem) { // Stripping any extra spaces $ifNoneMatchItem = trim($ifNoneMatchItem,' '); @@ -2068,21 +2068,21 @@ public function checkPreconditions($handleAsGET = false) { * @param bool strip404s * @return string */ - public function generateMultiStatus(array $fileProperties, $strip404s = false) { - + public function generateMultiStatus(array $fileProperties, $strip404s = false) + { $dom = new \DOMDocument('1.0','utf-8'); //$dom->formatOutput = true; $multiStatus = $dom->createElement('d:multistatus'); $dom->appendChild($multiStatus); // Adding in default namespaces - foreach($this->xmlNamespaces as $namespace=>$prefix) { + foreach ($this->xmlNamespaces as $namespace=>$prefix) { $multiStatus->setAttribute('xmlns:' . $prefix,$namespace); } - foreach($fileProperties as $entry) { + foreach ($fileProperties as $entry) { $href = $entry['href']; unset($entry['href']); @@ -2113,14 +2113,14 @@ public function generateMultiStatus(array $fileProperties, $strip404s = false) { * @param string $body xml body * @return array list of properties in need of updating or deletion */ - public function parsePropPatchRequest($body) { - + public function parsePropPatchRequest($body) + { //We'll need to change the DAV namespace declaration to something else in order to make it parsable $dom = XMLUtil::loadDOMDocument($body); $newProperties = array(); - foreach($dom->firstChild->childNodes as $child) { + foreach ($dom->firstChild->childNodes as $child) { if ($child->nodeType !== XML_ELEMENT_NODE) continue; @@ -2130,7 +2130,7 @@ public function parsePropPatchRequest($body) { $innerProperties = XMLUtil::parseProperties($child, $this->propertyMap); - foreach($innerProperties as $propertyName=>$propertyValue) { + foreach ($innerProperties as $propertyName=>$propertyValue) { if ($operation==='{DAV:}remove') { $propertyValue = null; @@ -2155,8 +2155,8 @@ public function parsePropPatchRequest($body) { * @param string $body * @return array */ - public function parsePropFindRequest($body) { - + public function parsePropFindRequest($body) + { // If the propfind body was empty, it means IE is requesting 'all' properties if (!$body) return array(); @@ -2169,4 +2169,3 @@ public function parsePropFindRequest($body) { // }}} } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/ServerPlugin.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/ServerPlugin.php index b6d46dbda9..de2ece3eb0 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/ServerPlugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/ServerPlugin.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class ServerPlugin { - +abstract class ServerPlugin +{ /** * This initializes the plugin. * @@ -34,8 +34,8 @@ abstract public function initialize(Server $server); * * @return array */ - public function getFeatures() { - + public function getFeatures() + { return array(); } @@ -50,8 +50,8 @@ public function getFeatures() { * @param string $uri * @return array */ - public function getHTTPMethods($uri) { - + public function getHTTPMethods($uri) + { return array(); } @@ -64,8 +64,8 @@ public function getHTTPMethods($uri) { * * @return string */ - public function getPluginName() { - + public function getPluginName() + { return get_class($this); } @@ -80,11 +80,10 @@ public function getPluginName() { * @param string $uri * @return array */ - public function getSupportedReportSet($uri) { - + public function getSupportedReportSet($uri) + { return array(); } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/SimpleCollection.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/SimpleCollection.php index 0b64055f0e..f1388cee2a 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/SimpleCollection.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/SimpleCollection.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SimpleCollection extends Collection { - +class SimpleCollection extends Collection +{ /** * List of childnodes * @@ -37,10 +37,10 @@ class SimpleCollection extends Collection { * @param string $name * @param array $children */ - public function __construct($name,array $children = array()) { - + public function __construct($name,array $children = array()) + { $this->name = $name; - foreach($children as $child) { + foreach ($children as $child) { if (!($child instanceof INode)) throw new Exception('Only instances of Sabre\DAV\INode are allowed to be passed in the children argument'); $this->addChild($child); @@ -55,8 +55,8 @@ public function __construct($name,array $children = array()) { * @param INode $child * @return void */ - public function addChild(INode $child) { - + public function addChild(INode $child) + { $this->children[$child->getName()] = $child; } @@ -66,8 +66,8 @@ public function addChild(INode $child) { * * @return string */ - public function getName() { - + public function getName() + { return $this->name; } @@ -85,8 +85,8 @@ public function getName() { * @throws Exception\NotFound * @return INode */ - public function getChild($name) { - + public function getChild($name) + { if (isset($this->children[$name])) return $this->children[$name]; throw new Exception\NotFound('File not found: ' . $name . ' in \'' . $this->getName() . '\''); @@ -97,12 +97,11 @@ public function getChild($name) { * * @return array */ - public function getChildren() { - + public function getChildren() + { return array_values($this->children); } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/SimpleFile.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/SimpleFile.php index 2789efc302..4aeb7d03bc 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/SimpleFile.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/SimpleFile.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SimpleFile extends File { - +class SimpleFile extends File +{ /** * File contents * @@ -46,8 +46,8 @@ class SimpleFile extends File { * @param string $contents * @param string|null $mimeType */ - public function __construct($name, $contents, $mimeType = null) { - + public function __construct($name, $contents, $mimeType = null) + { $this->name = $name; $this->contents = $contents; $this->mimeType = $mimeType; @@ -61,8 +61,8 @@ public function __construct($name, $contents, $mimeType = null) { * * @return string */ - public function getName() { - + public function getName() + { return $this->name; } @@ -74,8 +74,8 @@ public function getName() { * * @return mixed */ - public function get() { - + public function get() + { return $this->contents; } @@ -85,8 +85,8 @@ public function get() { * * @return int */ - public function getSize() { - + public function getSize() + { return strlen($this->contents); } @@ -100,8 +100,8 @@ public function getSize() { * Return null if the ETag can not effectively be determined * @return string */ - public function getETag() { - + public function getETag() + { return '"' . md5($this->contents) . '"'; } @@ -112,8 +112,8 @@ public function getETag() { * If null is returned, we'll assume application/octet-stream * @return string */ - public function getContentType() { - + public function getContentType() + { return $this->mimeType; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/StringUtil.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/StringUtil.php index 72ad00c3b7..c68f0b5b61 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/StringUtil.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/StringUtil.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class StringUtil { - +class StringUtil +{ /** * Checks if a needle occurs in a haystack ;) * @@ -24,9 +24,9 @@ class StringUtil { * @param string $matchType * @return bool */ - static public function textMatch($haystack, $needle, $collation, $matchType = 'contains') { - - switch($collation) { + public static function textMatch($haystack, $needle, $collation, $matchType = 'contains') + { + switch ($collation) { case 'i;ascii-casemap' : // default strtolower takes locale into consideration @@ -49,7 +49,7 @@ static public function textMatch($haystack, $needle, $collation, $matchType = 'c } - switch($matchType) { + switch ($matchType) { case 'contains' : return strpos($haystack, $needle)!==false; @@ -76,8 +76,8 @@ static public function textMatch($haystack, $needle, $collation, $matchType = 'c * @param string $input * @return string */ - static public function ensureUTF8($input) { - + public static function ensureUTF8($input) + { $encoding = mb_detect_encoding($input , array('UTF-8','ISO-8859-1'), true); if ($encoding === 'ISO-8859-1') { diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/TemporaryFileFilterPlugin.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/TemporaryFileFilterPlugin.php index abee6487f9..49acc8291e 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/TemporaryFileFilterPlugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/TemporaryFileFilterPlugin.php @@ -26,8 +26,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class TemporaryFileFilterPlugin extends ServerPlugin { - +class TemporaryFileFilterPlugin extends ServerPlugin +{ /** * This is the list of patterns we intercept. * If new patterns are added, they must be valid patterns for preg_match. @@ -68,8 +68,8 @@ class TemporaryFileFilterPlugin extends ServerPlugin { * * @param string|null $dataDir */ - public function __construct($dataDir = null) { - + public function __construct($dataDir = null) + { if (!$dataDir) $dataDir = ini_get('session.save_path').'/sabredav/'; if (!is_dir($dataDir)) mkdir($dataDir); $this->dataDir = $dataDir; @@ -85,8 +85,8 @@ public function __construct($dataDir = null) { * @param Server $server * @return void */ - public function initialize(Server $server) { - + public function initialize(Server $server) + { $this->server = $server; $server->subscribeEvent('beforeMethod',array($this,'beforeMethod')); $server->subscribeEvent('beforeCreateFile',array($this,'beforeCreateFile')); @@ -103,12 +103,12 @@ public function initialize(Server $server) { * @param string $uri * @return bool */ - public function beforeMethod($method, $uri) { - + public function beforeMethod($method, $uri) + { if (!$tempLocation = $this->isTempFile($uri)) return true; - switch($method) { + switch ($method) { case 'GET' : return $this->httpGet($tempLocation); case 'PUT' : @@ -132,8 +132,8 @@ public function beforeMethod($method, $uri) { * @param resource $data * @return bool */ - public function beforeCreateFile($uri,$data) { - + public function beforeCreateFile($uri,$data) + { if ($tempPath = $this->isTempFile($uri)) { $hR = $this->server->httpResponse; @@ -153,12 +153,12 @@ public function beforeCreateFile($uri,$data) { * @param string $path * @return boolean|string */ - protected function isTempFile($path) { - + protected function isTempFile($path) + { // We're only interested in the basename. list(, $tempPath) = URLUtil::splitPath($path); - foreach($this->temporaryFilePatterns as $tempFile) { + foreach ($this->temporaryFilePatterns as $tempFile) { if (preg_match($tempFile,$tempPath)) { return $this->getDataDir() . '/sabredav_' . md5($path) . '.tempfile'; @@ -179,8 +179,8 @@ protected function isTempFile($path) { * @param string $tempLocation * @return bool */ - public function httpGet($tempLocation) { - + public function httpGet($tempLocation) + { if (!file_exists($tempLocation)) return true; $hR = $this->server->httpResponse; @@ -199,8 +199,8 @@ public function httpGet($tempLocation) { * @param string $tempLocation * @return bool */ - public function httpPut($tempLocation) { - + public function httpPut($tempLocation) + { $hR = $this->server->httpResponse; $hR->setHeader('X-Sabre-Temp','true'); @@ -225,8 +225,8 @@ public function httpPut($tempLocation) { * @param string $tempLocation * @return bool */ - public function httpDelete($tempLocation) { - + public function httpDelete($tempLocation) + { if (!file_exists($tempLocation)) return true; unlink($tempLocation); @@ -248,8 +248,8 @@ public function httpDelete($tempLocation) { * @param string $uri * @return bool */ - public function httpPropfind($tempLocation, $uri) { - + public function httpPropfind($tempLocation, $uri) + { if (!file_exists($tempLocation)) return true; $hR = $this->server->httpResponse; diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Tree.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Tree.php index 21b56e5930..17846a2442 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Tree.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Tree.php @@ -9,8 +9,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class Tree { - +abstract class Tree +{ /** * This function must return an INode object for a path * If a Path doesn't exist, thrown a Exception_NotFound @@ -19,7 +19,7 @@ abstract class Tree { * @throws Exception\NotFound * @return INode */ - abstract function getNodeForPath($path); + abstract public function getNodeForPath($path); /** * This function allows you to check if a node exists. @@ -30,8 +30,8 @@ abstract function getNodeForPath($path); * @param string $path * @return bool */ - public function nodeExists($path) { - + public function nodeExists($path) + { try { $this->getNodeForPath($path); @@ -52,8 +52,8 @@ public function nodeExists($path) { * @param string $destinationPath The full destination path * @return void */ - public function copy($sourcePath, $destinationPath) { - + public function copy($sourcePath, $destinationPath) + { $sourceNode = $this->getNodeForPath($sourcePath); // grab the dirname and basename components @@ -73,8 +73,8 @@ public function copy($sourcePath, $destinationPath) { * @param string $destinationPath The full destination path, so not just the destination parent node * @return int */ - public function move($sourcePath, $destinationPath) { - + public function move($sourcePath, $destinationPath) + { list($sourceDir, $sourceName) = URLUtil::splitPath($sourcePath); list($destinationDir, $destinationName) = URLUtil::splitPath($destinationPath); @@ -96,8 +96,8 @@ public function move($sourcePath, $destinationPath) { * @param string $path * @return void */ - public function delete($path) { - + public function delete($path) + { $node = $this->getNodeForPath($path); $node->delete(); @@ -112,8 +112,8 @@ public function delete($path) { * @param string $path * @return array */ - public function getChildren($path) { - + public function getChildren($path) + { $node = $this->getNodeForPath($path); return $node->getChildren(); @@ -137,9 +137,8 @@ public function getChildren($path) { * @param string $path * @return void */ - public function markDirty($path) { - - + public function markDirty($path) + { } /** @@ -150,8 +149,8 @@ public function markDirty($path) { * @param string $destinationName * @return void */ - protected function copyNode(INode $source,ICollection $destinationParent,$destinationName = null) { - + protected function copyNode(INode $source,ICollection $destinationParent,$destinationName = null) + { if (!$destinationName) $destinationName = $source->getName(); if ($source instanceof IFile) { @@ -173,7 +172,7 @@ protected function copyNode(INode $source,ICollection $destinationParent,$destin $destinationParent->createDirectory($destinationName); $destination = $destinationParent->getChild($destinationName); - foreach($source->getChildren() as $child) { + foreach ($source->getChildren() as $child) { $this->copyNode($child,$destination); @@ -190,4 +189,3 @@ protected function copyNode(INode $source,ICollection $destinationParent,$destin } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Tree/Filesystem.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Tree/Filesystem.php index 2d5efc3039..03cccee3f9 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Tree/Filesystem.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Tree/Filesystem.php @@ -17,8 +17,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Filesystem extends DAV\Tree { - +class Filesystem extends DAV\Tree +{ /** * Base url on the filesystem. * @@ -33,8 +33,8 @@ class Filesystem extends DAV\Tree { * * @param string $basePath */ - public function __construct($basePath) { - + public function __construct($basePath) + { $this->basePath = $basePath; } @@ -45,10 +45,10 @@ public function __construct($basePath) { * @param string $path * @return DAV\FS\Node */ - public function getNodeForPath($path) { - + public function getNodeForPath($path) + { $realPath = $this->getRealPath($path); - if (!file_exists($realPath)) { + if (!file_exists($realPath)) { throw new DAV\Exception\NotFound('File at location ' . $realPath . ' not found'); } if (is_dir($realPath)) { @@ -65,8 +65,8 @@ public function getNodeForPath($path) { * @param string $publicPath * @return string */ - protected function getRealPath($publicPath) { - + protected function getRealPath($publicPath) + { return rtrim($this->basePath,'/') . '/' . trim($publicPath,'/'); } @@ -81,8 +81,8 @@ protected function getRealPath($publicPath) { * @param string $destination * @return void */ - public function copy($source,$destination) { - + public function copy($source,$destination) + { $source = $this->getRealPath($source); $destination = $this->getRealPath($destination); $this->realCopy($source,$destination); @@ -96,13 +96,13 @@ public function copy($source,$destination) { * @param string $destination * @return void */ - protected function realCopy($source,$destination) { - + protected function realCopy($source,$destination) + { if (is_file($source)) { copy($source,$destination); } else { mkdir($destination); - foreach(scandir($source) as $subnode) { + foreach (scandir($source) as $subnode) { if ($subnode=='.' || $subnode=='..') continue; $this->realCopy($source.'/'.$subnode,$destination.'/'.$subnode); @@ -121,8 +121,8 @@ protected function realCopy($source,$destination) { * @param string $destination * @return void */ - public function move($source,$destination) { - + public function move($source,$destination) + { $source = $this->getRealPath($source); $destination = $this->getRealPath($destination); rename($source,$destination); @@ -130,4 +130,3 @@ public function move($source,$destination) { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/URLUtil.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/URLUtil.php index 529845688a..8c8e846da6 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/URLUtil.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/URLUtil.php @@ -18,8 +18,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class URLUtil { - +class URLUtil +{ /** * Encodes the path of a url. * @@ -28,8 +28,8 @@ class URLUtil { * @param string $path * @return string */ - static function encodePath($path) { - + public static function encodePath($path) + { return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\)\/])/',function($match) { return '%'.sprintf('%02x',ord($match[0])); @@ -46,8 +46,8 @@ static function encodePath($path) { * @param string $pathSegment * @return string */ - static function encodePathSegment($pathSegment) { - + public static function encodePathSegment($pathSegment) + { return preg_replace_callback('/([^A-Za-z0-9_\-\.~\(\)])/',function($match) { return '%'.sprintf('%02x',ord($match[0])); @@ -61,8 +61,8 @@ static function encodePathSegment($pathSegment) { * @param string $path * @return string */ - static function decodePath($path) { - + public static function decodePath($path) + { return self::decodePathSegment($path); } @@ -73,12 +73,12 @@ static function decodePath($path) { * @param string $path * @return string */ - static function decodePathSegment($path) { - + public static function decodePathSegment($path) + { $path = rawurldecode($path); $encoding = mb_detect_encoding($path, array('UTF-8','ISO-8859-1')); - switch($encoding) { + switch ($encoding) { case 'ISO-8859-1' : $path = utf8_encode($path); @@ -107,10 +107,10 @@ static function decodePathSegment($path) { * @param string $path * @return array */ - static function splitPath($path) { - + public static function splitPath($path) + { $matches = array(); - if(preg_match('/^(?:(?:(.*)(?:\/+))?([^\/]+))(?:\/?)$/u',$path,$matches)) { + if (preg_match('/^(?:(?:(.*)(?:\/+))?([^\/]+))(?:\/?)$/u',$path,$matches)) { return array($matches[1],$matches[2]); } else { return array(null,null); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/UUIDUtil.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/UUIDUtil.php index adbce0f619..cb570beea0 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/UUIDUtil.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/UUIDUtil.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class UUIDUtil { - +class UUIDUtil +{ /** * Returns a pseudo-random v4 UUID * @@ -23,8 +23,8 @@ class UUIDUtil { * @see http://www.php.net/manual/en/function.uniqid.php#94959 * @return string */ - static function getUUID() { - + public static function getUUID() + { return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', // 32 bits for "time_low" mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), @@ -52,8 +52,8 @@ static function getUUID() { * @param string $uuid * @return bool */ - static function validateUUID($uuid) { - + public static function validateUUID($uuid) + { return preg_match( '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i', $uuid diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/Version.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/Version.php index 27cd8fb3af..a68d61d91d 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/Version.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/Version.php @@ -9,8 +9,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Version { - +class Version +{ /** * Full version number */ diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAV/XMLUtil.php b/core/src/core/classes/sabredav/lib/Sabre/DAV/XMLUtil.php index 1317d88716..b0236fefd1 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAV/XMLUtil.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAV/XMLUtil.php @@ -9,8 +9,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class XMLUtil { - +class XMLUtil +{ /** * Returns the 'clark notation' for an element. * @@ -29,8 +29,8 @@ class XMLUtil { * @param \DOMNode $dom * @return string */ - static function toClarkNotation(\DOMNode $dom) { - + public static function toClarkNotation(\DOMNode $dom) + { if ($dom->nodeType !== XML_ELEMENT_NODE) return null; // Mapping back to the real namespace, in case it was dav @@ -51,8 +51,8 @@ static function toClarkNotation(\DOMNode $dom) { * @throws InvalidArgumentException * @return array */ - static function parseClarkNotation($str) { - + public static function parseClarkNotation($str) + { if (!preg_match('/^{([^}]*)}(.*)$/',$str,$matches)) { throw new \InvalidArgumentException('\'' . $str . '\' is not a valid clark-notation formatted string'); } @@ -74,8 +74,8 @@ static function parseClarkNotation($str) { * @param string $xmlDocument * @return array|string|null */ - static function convertDAVNamespace($xmlDocument) { - + public static function convertDAVNamespace($xmlDocument) + { // This is used to map the DAV: namespace to urn:DAV. This is needed, because the DAV: // namespace is actually a violation of the XML namespaces specification, and will cause errors return preg_replace("/xmlns(:[A-Za-z0-9_]*)?=(\"|\')DAV:(\\2)/","xmlns\\1=\\2urn:DAV\\2",$xmlDocument); @@ -92,8 +92,8 @@ static function convertDAVNamespace($xmlDocument) { * @throws Sabre\DAV\Exception\BadRequest * @return DOMDocument */ - static function loadDOMDocument($xml) { - + public static function loadDOMDocument($xml) + { if (empty($xml)) throw new Exception\BadRequest('Empty XML document sent'); @@ -121,7 +121,7 @@ static function loadDOMDocument($xml) { // We don't generally care about any whitespace $dom->preserveWhiteSpace = false; - + $dom->loadXML(self::convertDAVNamespace($xml),LIBXML_NOWARNING | LIBXML_NOERROR); if ($error = libxml_get_last_error()) { @@ -158,14 +158,14 @@ static function loadDOMDocument($xml) { * @param array $propertyMap * @return array */ - static function parseProperties(\DOMElement $parentNode, array $propertyMap = array()) { - + public static function parseProperties(\DOMElement $parentNode, array $propertyMap = array()) + { $propList = array(); - foreach($parentNode->childNodes as $propNode) { + foreach ($parentNode->childNodes as $propNode) { if (self::toClarkNotation($propNode)!=='{DAV:}prop') continue; - foreach($propNode->childNodes as $propNodeData) { + foreach ($propNode->childNodes as $propNodeData) { /* If there are no elements in here, we actually get 1 text node, this special case is dedicated to netdrive */ if ($propNodeData->nodeType != XML_ELEMENT_NODE) continue; diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/AbstractPrincipalCollection.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/AbstractPrincipalCollection.php index 27d8048f90..ed3a51f673 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/AbstractPrincipalCollection.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/AbstractPrincipalCollection.php @@ -15,8 +15,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class AbstractPrincipalCollection extends DAV\Collection implements IPrincipalCollection { - +abstract class AbstractPrincipalCollection extends DAV\Collection implements IPrincipalCollection +{ /** * Node or 'directory' name. * @@ -51,8 +51,8 @@ abstract class AbstractPrincipalCollection extends DAV\Collection implements IPr * @param PrincipalBackend\BackendInterface $principalBackend * @param string $principalPrefix */ - public function __construct(PrincipalBackend\BackendInterface $principalBackend, $principalPrefix = 'principals') { - + public function __construct(PrincipalBackend\BackendInterface $principalBackend, $principalPrefix = 'principals') + { $this->principalPrefix = $principalPrefix; $this->principalBackend = $principalBackend; @@ -68,15 +68,15 @@ public function __construct(PrincipalBackend\BackendInterface $principalBackend, * @param array $principalInfo * @return IPrincipal */ - abstract function getChildForPrincipal(array $principalInfo); + abstract public function getChildForPrincipal(array $principalInfo); /** * Returns the name of this collection. * * @return string */ - public function getName() { - + public function getName() + { list(,$name) = DAV\URLUtil::splitPath($this->principalPrefix); return $name; @@ -87,13 +87,13 @@ public function getName() { * * @return array */ - public function getChildren() { - + public function getChildren() + { if ($this->disableListing) throw new DAV\Exception\MethodNotAllowed('Listing members of this collection is disabled'); $children = array(); - foreach($this->principalBackend->getPrincipalsByPrefix($this->principalPrefix) as $principalInfo) { + foreach ($this->principalBackend->getPrincipalsByPrefix($this->principalPrefix) as $principalInfo) { $children[] = $this->getChildForPrincipal($principalInfo); @@ -110,8 +110,8 @@ public function getChildren() { * @throws DAV\Exception\NotFound * @return IPrincipal */ - public function getChild($name) { - + public function getChild($name) + { $principalInfo = $this->principalBackend->getPrincipalByPath($this->principalPrefix . '/' . $name); if (!$principalInfo) throw new DAV\Exception\NotFound('Principal with name ' . $name . ' not found'); return $this->getChildForPrincipal($principalInfo); @@ -139,12 +139,12 @@ public function getChild($name) { * @param array $searchProperties * @return array */ - public function searchPrincipals(array $searchProperties) { - + public function searchPrincipals(array $searchProperties) + { $result = $this->principalBackend->searchPrincipals($this->principalPrefix, $searchProperties); $r = array(); - foreach($result as $row) { + foreach ($result as $row) { list(, $r[]) = DAV\URLUtil::splitPath($row); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/AceConflict.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/AceConflict.php index 2a2bd88bc4..721c3f2083 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/AceConflict.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/AceConflict.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class AceConflict extends DAV\Exception\Conflict { - +class AceConflict extends DAV\Exception\Conflict +{ /** * Adds in extra information in the xml response. * @@ -23,8 +23,8 @@ class AceConflict extends DAV\Exception\Conflict { * @param \DOMElement $errorNode * @return void */ - public function serialize(DAV\Server $server,\DOMElement $errorNode) { - + public function serialize(DAV\Server $server,\DOMElement $errorNode) + { $doc = $errorNode->ownerDocument; $np = $doc->createElementNS('DAV:','d:no-ace-conflict'); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NeedPrivileges.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NeedPrivileges.php index a4d70f2949..94bc423309 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NeedPrivileges.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NeedPrivileges.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class NeedPrivileges extends DAV\Exception\Forbidden { - +class NeedPrivileges extends DAV\Exception\Forbidden +{ /** * The relevant uri * @@ -36,8 +36,8 @@ class NeedPrivileges extends DAV\Exception\Forbidden { * @param string $uri * @param array $privileges */ - public function __construct($uri,array $privileges) { - + public function __construct($uri,array $privileges) + { $this->uri = $uri; $this->privileges = $privileges; @@ -54,14 +54,14 @@ public function __construct($uri,array $privileges) { * @param \DOMElement $errorNode * @return void */ - public function serialize(DAV\Server $server,\DOMElement $errorNode) { - + public function serialize(DAV\Server $server,\DOMElement $errorNode) + { $doc = $errorNode->ownerDocument; $np = $doc->createElementNS('DAV:','d:need-privileges'); $errorNode->appendChild($np); - foreach($this->privileges as $privilege) { + foreach ($this->privileges as $privilege) { $resource = $doc->createElementNS('DAV:','d:resource'); $np->appendChild($resource); @@ -80,4 +80,3 @@ public function serialize(DAV\Server $server,\DOMElement $errorNode) { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NoAbstract.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NoAbstract.php index a00b3389d5..83955f8586 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NoAbstract.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NoAbstract.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class NoAbstract extends DAV\Exception\PreconditionFailed { - +class NoAbstract extends DAV\Exception\PreconditionFailed +{ /** * Adds in extra information in the xml response. * @@ -23,8 +23,8 @@ class NoAbstract extends DAV\Exception\PreconditionFailed { * @param \DOMElement $errorNode * @return void */ - public function serialize(DAV\Server $server,\DOMElement $errorNode) { - + public function serialize(DAV\Server $server,\DOMElement $errorNode) + { $doc = $errorNode->ownerDocument; $np = $doc->createElementNS('DAV:','d:no-abstract'); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php index baad766dd9..f03052decd 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class NotRecognizedPrincipal extends DAV\Exception\PreconditionFailed { - +class NotRecognizedPrincipal extends DAV\Exception\PreconditionFailed +{ /** * Adds in extra information in the xml response. * @@ -23,8 +23,8 @@ class NotRecognizedPrincipal extends DAV\Exception\PreconditionFailed { * @param \DOMElement $errorNode * @return void */ - public function serialize(DAV\Server $server,\DOMElement $errorNode) { - + public function serialize(DAV\Server $server,\DOMElement $errorNode) + { $doc = $errorNode->ownerDocument; $np = $doc->createElementNS('DAV:','d:recognized-principal'); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NotSupportedPrivilege.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NotSupportedPrivilege.php index 6e07f799d7..b2ad741857 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NotSupportedPrivilege.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Exception/NotSupportedPrivilege.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class NotSupportedPrivilege extends DAV\Exception\PreconditionFailed { - +class NotSupportedPrivilege extends DAV\Exception\PreconditionFailed +{ /** * Adds in extra information in the xml response. * @@ -23,8 +23,8 @@ class NotSupportedPrivilege extends DAV\Exception\PreconditionFailed { * @param \DOMElement $errorNode * @return void */ - public function serialize(DAV\Server $server,\DOMElement $errorNode) { - + public function serialize(DAV\Server $server,\DOMElement $errorNode) + { $doc = $errorNode->ownerDocument; $np = $doc->createElementNS('DAV:','d:not-supported-privilege'); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IACL.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IACL.php index 5dceb21487..9a5bd037eb 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IACL.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IACL.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IACL extends DAV\INode { - +interface IACL extends DAV\INode +{ /** * Returns the owner principal * @@ -21,7 +21,7 @@ interface IACL extends DAV\INode { * * @return string|null */ - function getOwner(); + public function getOwner(); /** * Returns a group principal @@ -30,7 +30,7 @@ function getOwner(); * * @return string|null */ - function getGroup(); + public function getGroup(); /** * Returns a list of ACE's for this node. @@ -44,7 +44,7 @@ function getGroup(); * * @return array */ - function getACL(); + public function getACL(); /** * Updates the ACL @@ -54,7 +54,7 @@ function getACL(); * @param array $acl * @return void */ - function setACL(array $acl); + public function setACL(array $acl); /** * Returns the list of supported privileges for this node. @@ -68,7 +68,7 @@ function setACL(array $acl); * * @return array|null */ - function getSupportedPrivilegeSet(); + public function getSupportedPrivilegeSet(); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IPrincipal.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IPrincipal.php index b02769305d..6209b67b4d 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IPrincipal.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IPrincipal.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IPrincipal extends DAV\INode { - +interface IPrincipal extends DAV\INode +{ /** * Returns a list of alternative urls for a principal * @@ -22,14 +22,14 @@ interface IPrincipal extends DAV\INode { * * @return array */ - function getAlternateUriSet(); + public function getAlternateUriSet(); /** * Returns the full principal url * * @return string */ - function getPrincipalUrl(); + public function getPrincipalUrl(); /** * Returns the list of group members @@ -39,7 +39,7 @@ function getPrincipalUrl(); * * @return array */ - function getGroupMemberSet(); + public function getGroupMemberSet(); /** * Returns the list of groups this principal is member of @@ -49,7 +49,7 @@ function getGroupMemberSet(); * * @return array */ - function getGroupMembership(); + public function getGroupMembership(); /** * Sets a list of group members @@ -62,7 +62,7 @@ function getGroupMembership(); * @param array $principals * @return void */ - function setGroupMemberSet(array $principals); + public function setGroupMemberSet(array $principals); /** * Returns the displayname @@ -72,6 +72,6 @@ function setGroupMemberSet(array $principals); * * @return string */ - function getDisplayName(); + public function getDisplayName(); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IPrincipalCollection.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IPrincipalCollection.php index 1cb880f1c3..a16672d40e 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IPrincipalCollection.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/IPrincipalCollection.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface IPrincipalCollection extends DAV\INode { - +interface IPrincipalCollection extends DAV\INode +{ /** * This method is used to search for principals matching a set of * properties. @@ -37,6 +37,6 @@ interface IPrincipalCollection extends DAV\INode { * @param array $searchProperties * @return array */ - function searchPrincipals(array $searchProperties); + public function searchPrincipals(array $searchProperties); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Plugin.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Plugin.php index 0e71939ca4..afb37cff5d 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Plugin.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Plugin.php @@ -17,8 +17,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Plugin extends DAV\ServerPlugin { - +class Plugin extends DAV\ServerPlugin +{ /** * Recursion constants * @@ -118,8 +118,8 @@ class Plugin extends DAV\ServerPlugin { * * @return array */ - public function getFeatures() { - + public function getFeatures() + { return array('access-control', 'calendarserver-principal-property-search'); } @@ -130,8 +130,8 @@ public function getFeatures() { * @param string $uri * @return array */ - public function getMethods($uri) { - + public function getMethods($uri) + { return array('ACL'); } @@ -144,8 +144,8 @@ public function getMethods($uri) { * * @return string */ - public function getPluginName() { - + public function getPluginName() + { return 'acl'; } @@ -160,8 +160,8 @@ public function getPluginName() { * @param string $uri * @return array */ - public function getSupportedReportSet($uri) { - + public function getSupportedReportSet($uri) + { return array( '{DAV:}expand-property', '{DAV:}principal-property-search', @@ -185,8 +185,8 @@ public function getSupportedReportSet($uri) { * @throws Sabre\DAVACL\Exception\NeedPrivileges * @return bool */ - public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, $throwExceptions = true) { - + public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, $throwExceptions = true) + { if (!is_array($privileges)) $privileges = array($privileges); $acl = $this->getCurrentUserPrivilegeSet($uri); @@ -204,7 +204,7 @@ public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, } $failed = array(); - foreach($privileges as $priv) { + foreach ($privileges as $priv) { if (!in_array($priv, $acl)) { $failed[] = $priv; @@ -230,8 +230,8 @@ public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, * * @return string|null */ - public function getCurrentUserPrincipal() { - + public function getCurrentUserPrincipal() + { $authPlugin = $this->server->getPlugin('auth'); if (is_null($authPlugin)) return null; /** @var $authPlugin Sabre\DAV\Auth\Plugin */ @@ -250,8 +250,8 @@ public function getCurrentUserPrincipal() { * * @return array */ - public function getCurrentUserPrincipals() { - + public function getCurrentUserPrincipals() + { $currentUser = $this->getCurrentUserPrincipal(); if (is_null($currentUser)) return array(); @@ -278,8 +278,8 @@ public function getCurrentUserPrincipals() { * @param string $principal * @return array */ - public function getPrincipalMembership($mainPrincipal) { - + public function getPrincipalMembership($mainPrincipal) + { // First check our cache if (isset($this->principalMembershipCache[$mainPrincipal])) { return $this->principalMembershipCache[$mainPrincipal]; @@ -288,13 +288,13 @@ public function getPrincipalMembership($mainPrincipal) { $check = array($mainPrincipal); $principals = array(); - while(count($check)) { + while (count($check)) { $principal = array_shift($check); $node = $this->server->tree->getNodeForPath($principal); if ($node instanceof IPrincipal) { - foreach($node->getGroupMembership() as $groupMember) { + foreach ($node->getGroupMembership() as $groupMember) { if (!in_array($groupMember, $principals)) { @@ -328,8 +328,8 @@ public function getPrincipalMembership($mainPrincipal) { * @param string|DAV\INode $node * @return array */ - public function getSupportedPrivilegeSet($node) { - + public function getSupportedPrivilegeSet($node) + { if (is_string($node)) { $node = $this->server->tree->getNodeForPath($node); } @@ -351,8 +351,8 @@ public function getSupportedPrivilegeSet($node) { * * @return array */ - static function getDefaultSupportedPrivilegeSet() { - + public static function getDefaultSupportedPrivilegeSet() + { return array( 'privilege' => '{DAV:}all', 'abstract' => true, @@ -418,8 +418,8 @@ static function getDefaultSupportedPrivilegeSet() { * @param string|DAV\INode $node * @return array */ - final public function getFlatPrivilegeSet($node) { - + final public function getFlatPrivilegeSet($node) + { $privs = $this->getSupportedPrivilegeSet($node); $flat = array(); @@ -440,8 +440,8 @@ final public function getFlatPrivilegeSet($node) { * @param array $flat * @return void */ - final private function getFPSTraverse($priv, $concrete, &$flat) { - + final private function getFPSTraverse($priv, $concrete, &$flat) + { $myPriv = array( 'privilege' => $priv['privilege'], 'abstract' => isset($priv['abstract']) && $priv['abstract'], @@ -456,7 +456,7 @@ final private function getFPSTraverse($priv, $concrete, &$flat) { if (isset($priv['aggregates'])) { - foreach($priv['aggregates'] as $subPriv) { + foreach ($priv['aggregates'] as $subPriv) { $this->getFPSTraverse($subPriv, $myPriv['concrete'], $flat); @@ -476,8 +476,8 @@ final private function getFPSTraverse($priv, $concrete, &$flat) { * @param string|DAV\INode $node * @return array */ - public function getACL($node) { - + public function getACL($node) + { if (is_string($node)) { $node = $this->server->tree->getNodeForPath($node); } @@ -485,7 +485,7 @@ public function getACL($node) { return null; } $acl = $node->getACL(); - foreach($this->adminPrincipals as $adminPrincipal) { + foreach ($this->adminPrincipals as $adminPrincipal) { $acl[] = array( 'principal' => $adminPrincipal, 'privilege' => '{DAV:}all', @@ -507,8 +507,8 @@ public function getACL($node) { * @param string|DAV\INode $node * @return array */ - public function getCurrentUserPrivilegeSet($node) { - + public function getCurrentUserPrivilegeSet($node) + { if (is_string($node)) { $node = $this->server->tree->getNodeForPath($node); } @@ -521,11 +521,11 @@ public function getCurrentUserPrivilegeSet($node) { $collected = array(); - foreach($acl as $ace) { + foreach ($acl as $ace) { $principal = $ace['principal']; - switch($principal) { + switch ($principal) { case '{DAV:}owner' : $owner = $node->getOwner(); @@ -565,12 +565,12 @@ public function getCurrentUserPrivilegeSet($node) { $flat = $this->getFlatPrivilegeSet($node); $collected2 = array(); - while(count($collected)) { + while (count($collected)) { $current = array_pop($collected); $collected2[] = $current['privilege']; - foreach($flat[$current['privilege']]['aggregates'] as $subPriv) { + foreach ($flat[$current['privilege']]['aggregates'] as $subPriv) { $collected2[] = $subPriv; $collected[] = $flat[$subPriv]; } @@ -603,8 +603,8 @@ public function getCurrentUserPrivilegeSet($node) { * properties are index by a HTTP status code. * */ - public function principalSearch(array $searchProperties, array $requestedProperties, $collectionUri = null) { - + public function principalSearch(array $searchProperties, array $requestedProperties, $collectionUri = null) + { if (!is_null($collectionUri)) { $uris = array($collectionUri); } else { @@ -612,7 +612,7 @@ public function principalSearch(array $searchProperties, array $requestedPropert } $lookupResults = array(); - foreach($uris as $uri) { + foreach ($uris as $uri) { $principalCollection = $this->server->tree->getNodeForPath($uri); if (!$principalCollection instanceof IPrincipalCollection) { @@ -622,7 +622,7 @@ public function principalSearch(array $searchProperties, array $requestedPropert } $results = $principalCollection->searchPrincipals($searchProperties); - foreach($results as $result) { + foreach ($results as $result) { $lookupResults[] = rtrim($uri,'/') . '/' . $result; } @@ -630,7 +630,7 @@ public function principalSearch(array $searchProperties, array $requestedPropert $matches = array(); - foreach($lookupResults as $lookupResult) { + foreach ($lookupResults as $lookupResult) { list($matches[]) = $this->server->getPropertiesForPath($lookupResult, $requestedProperties, 0); @@ -648,8 +648,8 @@ public function principalSearch(array $searchProperties, array $requestedPropert * @param DAV\Server $server * @return void */ - public function initialize(DAV\Server $server) { - + public function initialize(DAV\Server $server) + { $this->server = $server; $server->subscribeEvent('beforeGetProperties',array($this,'beforeGetProperties')); @@ -696,14 +696,14 @@ public function initialize(DAV\Server $server) { * @param string $uri * @return void */ - public function beforeMethod($method, $uri) { - + public function beforeMethod($method, $uri) + { $exists = $this->server->tree->nodeExists($uri); // If the node doesn't exists, none of these checks apply if (!$exists) return; - switch($method) { + switch ($method) { case 'GET' : case 'HEAD' : @@ -761,8 +761,8 @@ public function beforeMethod($method, $uri) { * @param string $uri * @return void */ - public function beforeBind($uri) { - + public function beforeBind($uri) + { list($parentUri,$nodeName) = DAV\URLUtil::splitPath($uri); $this->checkPrivileges($parentUri,'{DAV:}bind'); @@ -777,8 +777,8 @@ public function beforeBind($uri) { * @param string $uri * @return void */ - public function beforeUnbind($uri) { - + public function beforeUnbind($uri) + { list($parentUri,$nodeName) = DAV\URLUtil::splitPath($uri); $this->checkPrivileges($parentUri,'{DAV:}unbind',self::R_RECURSIVEPARENTS); @@ -792,9 +792,8 @@ public function beforeUnbind($uri) { * @TODO: not yet implemented * @return void */ - public function beforeUnlock($uri, DAV\Locks\LockInfo $lock) { - - + public function beforeUnlock($uri, DAV\Locks\LockInfo $lock) + { } /** @@ -807,8 +806,8 @@ public function beforeUnlock($uri, DAV\Locks\LockInfo $lock) { * @TODO really should be broken into multiple methods, or even a class. * @return bool */ - public function beforeGetProperties($uri, DAV\INode $node, &$requestedProperties, &$returnedProperties) { - + public function beforeGetProperties($uri, DAV\INode $node, &$requestedProperties, &$returnedProperties) + { // Checking the read permission if (!$this->checkPrivileges($uri,'{DAV:}read',self::R_PARENT,false)) { @@ -818,7 +817,7 @@ public function beforeGetProperties($uri, DAV\INode $node, &$requestedProperties } // Marking all requested properties as '403'. - foreach($requestedProperties as $key=>$requestedProperty) { + foreach ($requestedProperties as $key=>$requestedProperty) { unset($requestedProperties[$key]); $returnedProperties[403][$requestedProperty] = null; } @@ -952,8 +951,8 @@ public function beforeGetProperties($uri, DAV\INode $node, &$requestedProperties * @param DAV\INode $node * @return bool */ - public function updateProperties(&$propertyDelta, &$result, DAV\INode $node) { - + public function updateProperties(&$propertyDelta, &$result, DAV\INode $node) + { if (!array_key_exists('{DAV:}group-member-set', $propertyDelta)) return; @@ -993,9 +992,9 @@ public function updateProperties(&$propertyDelta, &$result, DAV\INode $node) { * @param \DOMNode $dom * @return bool */ - public function report($reportName, $dom) { - - switch($reportName) { + public function report($reportName, $dom) + { + switch ($reportName) { case '{DAV:}principal-property-search' : $this->principalPropertySearchReport($dom); @@ -1019,8 +1018,8 @@ public function report($reportName, $dom) { * @param string $uri * @return bool */ - public function unknownMethod($method, $uri) { - + public function unknownMethod($method, $uri) + { if ($method!=='ACL') return; $this->httpACL($uri); @@ -1034,8 +1033,8 @@ public function unknownMethod($method, $uri) { * @param string $uri * @return void */ - public function httpACL($uri) { - + public function httpACL($uri) + { $body = $this->server->httpRequest->getBody(true); $dom = DAV\XMLUtil::loadDOMDocument($body); @@ -1044,7 +1043,7 @@ public function httpACL($uri) { ->getPrivileges(); // Normalizing urls - foreach($newAcl as $k=>$newAce) { + foreach ($newAcl as $k=>$newAce) { $newAcl[$k]['principal'] = $this->server->calculateUri($newAce['principal']); } @@ -1060,12 +1059,12 @@ public function httpACL($uri) { /* Checking if protected principals from the existing principal set are not overwritten. */ - foreach($oldAcl as $oldAce) { + foreach ($oldAcl as $oldAce) { if (!isset($oldAce['protected']) || !$oldAce['protected']) continue; $found = false; - foreach($newAcl as $newAce) { + foreach ($newAcl as $newAce) { if ( $newAce['privilege'] === $oldAce['privilege'] && $newAce['principal'] === $oldAce['principal'] && @@ -1079,7 +1078,7 @@ public function httpACL($uri) { } - foreach($newAcl as $newAce) { + foreach ($newAcl as $newAce) { // Do we recognize the privilege if (!isset($supportedPrivileges[$newAce['privilege']])) { @@ -1123,8 +1122,8 @@ public function httpACL($uri) { * @param \DOMElement $dom * @return void */ - protected function expandPropertyReport($dom) { - + protected function expandPropertyReport($dom) + { $requestedProperties = $this->parseExpandPropertyReportRequest($dom->firstChild->firstChild); $depth = $this->server->getHTTPDepth(0); $requestUri = $this->server->getRequestUri(); @@ -1137,13 +1136,13 @@ protected function expandPropertyReport($dom) { $dom->appendChild($multiStatus); // Adding in default namespaces - foreach($this->server->xmlNamespaces as $namespace=>$prefix) { + foreach ($this->server->xmlNamespaces as $namespace=>$prefix) { $multiStatus->setAttribute('xmlns:' . $prefix,$namespace); } - foreach($result as $response) { + foreach ($result as $response) { $response->serialize($this->server, $multiStatus); } @@ -1161,8 +1160,8 @@ protected function expandPropertyReport($dom) { * @param \DOMElement $node * @return array */ - protected function parseExpandPropertyReportRequest($node) { - + protected function parseExpandPropertyReportRequest($node) + { $requestedProperties = array(); do { @@ -1199,15 +1198,15 @@ protected function parseExpandPropertyReportRequest($node) { * @param int $depth * @return array */ - protected function expandProperties($path, array $requestedProperties, $depth) { - + protected function expandProperties($path, array $requestedProperties, $depth) + { $foundProperties = $this->server->getPropertiesForPath($path, array_keys($requestedProperties), $depth); $result = array(); - foreach($foundProperties as $node) { + foreach ($foundProperties as $node) { - foreach($requestedProperties as $propertyName=>$childRequestedProperties) { + foreach ($requestedProperties as $propertyName=>$childRequestedProperties) { // We're only traversing if sub-properties were requested if(count($childRequestedProperties)===0) continue; @@ -1223,7 +1222,7 @@ protected function expandProperties($path, array $requestedProperties, $depth) { } $childProps = array(); - foreach($hrefs as $href) { + foreach ($hrefs as $href) { $childProps = array_merge($childProps, $this->expandProperties($href, $childRequestedProperties, 0)); } $node[200][$propertyName] = new DAV\Property\ResponseList($childProps); @@ -1248,8 +1247,8 @@ protected function expandProperties($path, array $requestedProperties, $depth) { * @param \DOMDocument $dom * @return void */ - protected function principalSearchPropertySetReport(\DOMDocument $dom) { - + protected function principalSearchPropertySetReport(\DOMDocument $dom) + { $httpDepth = $this->server->getHTTPDepth(0); if ($httpDepth!==0) { throw new DAV\Exception\BadRequest('This report is only defined when Depth: 0'); @@ -1263,7 +1262,7 @@ protected function principalSearchPropertySetReport(\DOMDocument $dom) { $root = $dom->createElement('d:principal-search-property-set'); $dom->appendChild($root); // Adding in default namespaces - foreach($this->server->xmlNamespaces as $namespace=>$prefix) { + foreach ($this->server->xmlNamespaces as $namespace=>$prefix) { $root->setAttribute('xmlns:' . $prefix,$namespace); @@ -1271,7 +1270,7 @@ protected function principalSearchPropertySetReport(\DOMDocument $dom) { $nsList = $this->server->xmlNamespaces; - foreach($this->principalSearchPropertySet as $propertyName=>$description) { + foreach ($this->principalSearchPropertySet as $propertyName=>$description) { $psp = $dom->createElement('d:principal-search-property'); $root->appendChild($psp); @@ -1310,8 +1309,8 @@ protected function principalSearchPropertySetReport(\DOMDocument $dom) { * @param \DOMDocument $dom * @return void */ - protected function principalPropertySearchReport(\DOMDocument $dom) { - + protected function principalPropertySearchReport(\DOMDocument $dom) + { list($searchProperties, $requestedProperties, $applyToPrincipalCollectionSet) = $this->parsePrincipalPropertySearchReportRequest($dom); $uri = null; @@ -1342,8 +1341,8 @@ protected function principalPropertySearchReport(\DOMDocument $dom) { * @param \DOMDocument $dom * @return array */ - protected function parsePrincipalPropertySearchReportRequest($dom) { - + protected function parsePrincipalPropertySearchReportRequest($dom) + { $httpDepth = $this->server->getHTTPDepth(0); if ($httpDepth!==0) { throw new DAV\Exception\BadRequest('This report is only defined when Depth: 0'); @@ -1354,7 +1353,7 @@ protected function parsePrincipalPropertySearchReportRequest($dom) { $applyToPrincipalCollectionSet = false; // Parsing the search request - foreach($dom->firstChild->childNodes as $searchNode) { + foreach ($dom->firstChild->childNodes as $searchNode) { if (DAV\XMLUtil::toClarkNotation($searchNode) == '{DAV:}apply-to-principal-collection-set') { $applyToPrincipalCollectionSet = true; @@ -1366,9 +1365,9 @@ protected function parsePrincipalPropertySearchReportRequest($dom) { $propertyName = null; $propertyValue = null; - foreach($searchNode->childNodes as $childNode) { + foreach ($searchNode->childNodes as $childNode) { - switch(DAV\XMLUtil::toClarkNotation($childNode)) { + switch (DAV\XMLUtil::toClarkNotation($childNode)) { case '{DAV:}prop' : $property = DAV\XMLUtil::parseProperties($searchNode); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Principal.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Principal.php index 965e741b00..cd7b5e151f 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Principal.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Principal.php @@ -19,8 +19,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Principal extends DAV\Node implements IPrincipal, DAV\IProperties, IACL { - +class Principal extends DAV\Node implements IPrincipal, DAV\IProperties, IACL +{ /** * Struct with principal information. * @@ -41,8 +41,8 @@ class Principal extends DAV\Node implements IPrincipal, DAV\IProperties, IACL { * @param IPrincipalBackend $principalBackend * @param array $principalProperties */ - public function __construct(PrincipalBackend\BackendInterface $principalBackend, array $principalProperties = array()) { - + public function __construct(PrincipalBackend\BackendInterface $principalBackend, array $principalProperties = array()) + { if (!isset($principalProperties['uri'])) { throw new DAV\Exception('The principal properties must at least contain the \'uri\' key'); } @@ -56,8 +56,8 @@ public function __construct(PrincipalBackend\BackendInterface $principalBackend, * * @return string */ - public function getPrincipalUrl() { - + public function getPrincipalUrl() + { return $this->principalProperties['uri']; } @@ -69,8 +69,8 @@ public function getPrincipalUrl() { * * @return array */ - public function getAlternateUriSet() { - + public function getAlternateUriSet() + { $uris = array(); if (isset($this->principalProperties['{DAV:}alternate-URI-set'])) { @@ -94,8 +94,8 @@ public function getAlternateUriSet() { * * @return array */ - public function getGroupMemberSet() { - + public function getGroupMemberSet() + { return $this->principalBackend->getGroupMemberSet($this->principalProperties['uri']); } @@ -108,8 +108,8 @@ public function getGroupMemberSet() { * * @return array */ - public function getGroupMembership() { - + public function getGroupMembership() + { return $this->principalBackend->getGroupMemberShip($this->principalProperties['uri']); } @@ -126,8 +126,8 @@ public function getGroupMembership() { * @param array $groupMembers * @return void */ - public function setGroupMemberSet(array $groupMembers) { - + public function setGroupMemberSet(array $groupMembers) + { $this->principalBackend->setGroupMemberSet($this->principalProperties['uri'], $groupMembers); } @@ -138,8 +138,8 @@ public function setGroupMemberSet(array $groupMembers) { * * @return string */ - public function getName() { - + public function getName() + { $uri = $this->principalProperties['uri']; list(, $name) = DAV\URLUtil::splitPath($uri); return $name; @@ -151,8 +151,8 @@ public function getName() { * * @return string */ - public function getDisplayName() { - + public function getDisplayName() + { if (isset($this->principalProperties['{DAV:}displayname'])) { return $this->principalProperties['{DAV:}displayname']; } else { @@ -167,10 +167,10 @@ public function getDisplayName() { * @param array $requestedProperties * @return array */ - public function getProperties($requestedProperties) { - + public function getProperties($requestedProperties) + { $newProperties = array(); - foreach($requestedProperties as $propName) { + foreach ($requestedProperties as $propName) { if (isset($this->principalProperties[$propName])) { $newProperties[$propName] = $this->principalProperties[$propName]; @@ -184,13 +184,13 @@ public function getProperties($requestedProperties) { /** * Updates this principals properties. - * + * * @param array $mutations * @see Sabre\DAV\IProperties::updateProperties * @return bool|array */ - public function updateProperties($mutations) { - + public function updateProperties($mutations) + { return $this->principalBackend->updatePrincipal($this->principalProperties['uri'], $mutations); } @@ -202,8 +202,8 @@ public function updateProperties($mutations) { * * @return string|null */ - public function getOwner() { - + public function getOwner() + { return $this->principalProperties['uri']; @@ -216,8 +216,8 @@ public function getOwner() { * * @return string|null */ - public function getGroup() { - + public function getGroup() + { return null; } @@ -234,8 +234,8 @@ public function getGroup() { * * @return array */ - public function getACL() { - + public function getACL() + { return array( array( 'privilege' => '{DAV:}read', @@ -254,8 +254,8 @@ public function getACL() { * @param array $acl * @return void */ - public function setACL(array $acl) { - + public function setACL(array $acl) + { throw new DAV\Exception\MethodNotAllowed('Updating ACLs is not allowed here'); } @@ -272,8 +272,8 @@ public function setACL(array $acl) { * * @return array|null */ - public function getSupportedPrivilegeSet() { - + public function getSupportedPrivilegeSet() + { return null; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/AbstractBackend.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/AbstractBackend.php index be0962cac4..a524f2eea4 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/AbstractBackend.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/AbstractBackend.php @@ -13,6 +13,6 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class AbstractBackend implements BackendInterface { - +abstract class AbstractBackend implements BackendInterface +{ } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/BackendInterface.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/BackendInterface.php index b45fa7de93..dcba71cfd2 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/BackendInterface.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/BackendInterface.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -interface BackendInterface { - +interface BackendInterface +{ /** * Returns a list of principals based on a prefix. * @@ -31,7 +31,7 @@ interface BackendInterface { * @param string $prefixPath * @return array */ - function getPrincipalsByPrefix($prefixPath); + public function getPrincipalsByPrefix($prefixPath); /** * Returns a specific principal, specified by it's path. @@ -41,7 +41,7 @@ function getPrincipalsByPrefix($prefixPath); * @param string $path * @return array */ - function getPrincipalByPath($path); + public function getPrincipalByPath($path); /** * Updates one ore more webdav properties on a principal. @@ -91,7 +91,7 @@ function getPrincipalByPath($path); * @param array $mutations * @return array|bool */ - function updatePrincipal($path, $mutations); + public function updatePrincipal($path, $mutations); /** * This method is used to search for principals matching a set of @@ -121,7 +121,7 @@ function updatePrincipal($path, $mutations); * @param array $searchProperties * @return array */ - function searchPrincipals($prefixPath, array $searchProperties); + public function searchPrincipals($prefixPath, array $searchProperties); /** * Returns the list of members for a group-principal @@ -129,7 +129,7 @@ function searchPrincipals($prefixPath, array $searchProperties); * @param string $principal * @return array */ - function getGroupMemberSet($principal); + public function getGroupMemberSet($principal); /** * Returns the list of groups a principal is a member of @@ -137,7 +137,7 @@ function getGroupMemberSet($principal); * @param string $principal * @return array */ - function getGroupMembership($principal); + public function getGroupMembership($principal); /** * Updates the list of group members for a group principal. @@ -148,6 +148,6 @@ function getGroupMembership($principal); * @param array $members * @return void */ - function setGroupMemberSet($principal, array $members); + public function setGroupMemberSet($principal, array $members); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/PDO.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/PDO.php index 2a2824e417..8590165bb4 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/PDO.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalBackend/PDO.php @@ -16,8 +16,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class PDO extends AbstractBackend { - +class PDO extends AbstractBackend +{ /** * pdo * @@ -79,8 +79,8 @@ class PDO extends AbstractBackend { * @param string $tableName * @param string $groupMembersTableName */ - public function __construct(\PDO $pdo, $tableName = 'principals', $groupMembersTableName = 'groupmembers') { - + public function __construct(\PDO $pdo, $tableName = 'principals', $groupMembersTableName = 'groupmembers') + { $this->pdo = $pdo; $this->tableName = $tableName; $this->groupMembersTableName = $groupMembersTableName; @@ -104,20 +104,20 @@ public function __construct(\PDO $pdo, $tableName = 'principals', $groupMembersT * @param string $prefixPath * @return array */ - public function getPrincipalsByPrefix($prefixPath) { - + public function getPrincipalsByPrefix($prefixPath) + { $fields = array( 'uri', ); - foreach($this->fieldMap as $key=>$value) { + foreach ($this->fieldMap as $key=>$value) { $fields[] = $value['dbField']; } $result = $this->pdo->query('SELECT '.implode(',', $fields).' FROM '. $this->tableName); $principals = array(); - while($row = $result->fetch(\PDO::FETCH_ASSOC)) { + while ($row = $result->fetch(\PDO::FETCH_ASSOC)) { // Checking if the principal is in the prefix list($rowPrefix) = DAV\URLUtil::splitPath($row['uri']); @@ -126,7 +126,7 @@ public function getPrincipalsByPrefix($prefixPath) { $principal = array( 'uri' => $row['uri'], ); - foreach($this->fieldMap as $key=>$value) { + foreach ($this->fieldMap as $key=>$value) { if ($row[$value['dbField']]) { $principal[$key] = $row[$value['dbField']]; } @@ -147,14 +147,14 @@ public function getPrincipalsByPrefix($prefixPath) { * @param string $path * @return array */ - public function getPrincipalByPath($path) { - + public function getPrincipalByPath($path) + { $fields = array( 'id', 'uri', ); - foreach($this->fieldMap as $key=>$value) { + foreach ($this->fieldMap as $key=>$value) { $fields[] = $value['dbField']; } $stmt = $this->pdo->prepare('SELECT '.implode(',', $fields).' FROM '. $this->tableName . ' WHERE uri = ?'); @@ -167,7 +167,7 @@ public function getPrincipalByPath($path) { 'id' => $row['id'], 'uri' => $row['uri'], ); - foreach($this->fieldMap as $key=>$value) { + foreach ($this->fieldMap as $key=>$value) { if ($row[$value['dbField']]) { $principal[$key] = $row[$value['dbField']]; } @@ -224,10 +224,10 @@ public function getPrincipalByPath($path) { * @param array $mutations * @return array|bool */ - public function updatePrincipal($path, $mutations) { - + public function updatePrincipal($path, $mutations) + { $updateAble = array(); - foreach($mutations as $key=>$value) { + foreach ($mutations as $key=>$value) { // We are not aware of this field, we must fail. if (!isset($this->fieldMap[$key])) { @@ -240,7 +240,7 @@ public function updatePrincipal($path, $mutations) { ); // Adding the rest to the response as a 424 - foreach($mutations as $subKey=>$subValue) { + foreach ($mutations as $subKey=>$subValue) { if ($subKey !== $key) { $response[424][$subKey] = null; } @@ -256,7 +256,7 @@ public function updatePrincipal($path, $mutations) { $query = "UPDATE " . $this->tableName . " SET "; $first = true; - foreach($updateAble as $key => $value) { + foreach ($updateAble as $key => $value) { if (!$first) { $query.= ', '; } @@ -300,13 +300,13 @@ public function updatePrincipal($path, $mutations) { * @param array $searchProperties * @return array */ - public function searchPrincipals($prefixPath, array $searchProperties) { - + public function searchPrincipals($prefixPath, array $searchProperties) + { $query = 'SELECT uri FROM ' . $this->tableName . ' WHERE 1=1 '; $values = array(); - foreach($searchProperties as $property => $value) { + foreach ($searchProperties as $property => $value) { - switch($property) { + switch ($property) { case '{DAV:}displayname' : $query.=' AND displayname LIKE ?'; @@ -327,7 +327,7 @@ public function searchPrincipals($prefixPath, array $searchProperties) { $stmt->execute($values); $principals = array(); - while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { // Checking if the principal is in the prefix list($rowPrefix) = DAV\URLUtil::splitPath($row['uri']); @@ -347,8 +347,8 @@ public function searchPrincipals($prefixPath, array $searchProperties) { * @param string $principal * @return array */ - public function getGroupMemberSet($principal) { - + public function getGroupMemberSet($principal) + { $principal = $this->getPrincipalByPath($principal); if (!$principal) throw new DAV\Exception('Principal not found'); @@ -369,8 +369,8 @@ public function getGroupMemberSet($principal) { * @param string $principal * @return array */ - public function getGroupMembership($principal) { - + public function getGroupMembership($principal) + { $principal = $this->getPrincipalByPath($principal); if (!$principal) throw new DAV\Exception('Principal not found'); @@ -394,8 +394,8 @@ public function getGroupMembership($principal) { * @param array $members * @return void */ - public function setGroupMemberSet($principal, array $members) { - + public function setGroupMemberSet($principal, array $members) + { // Grabbing the list of principal id's. $stmt = $this->pdo->prepare('SELECT id, uri FROM '.$this->tableName.' WHERE uri IN (? ' . str_repeat(', ? ', count($members)) . ');'); $stmt->execute(array_merge(array($principal), $members)); @@ -403,7 +403,7 @@ public function setGroupMemberSet($principal, array $members) { $memberIds = array(); $principalId = null; - while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { + while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { if ($row['uri'] == $principal) { $principalId = $row['id']; } else { @@ -416,7 +416,7 @@ public function setGroupMemberSet($principal, array $members) { $stmt = $this->pdo->prepare('DELETE FROM '.$this->groupMembersTableName.' WHERE principal_id = ?;'); $stmt->execute(array($principalId)); - foreach($memberIds as $memberId) { + foreach ($memberIds as $memberId) { $stmt = $this->pdo->prepare('INSERT INTO '.$this->groupMembersTableName.' (principal_id, member_id) VALUES (?, ?);'); $stmt->execute(array($principalId, $memberId)); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalCollection.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalCollection.php index aae1088096..29bc904959 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalCollection.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/PrincipalCollection.php @@ -12,8 +12,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class PrincipalCollection extends AbstractPrincipalCollection { - +class PrincipalCollection extends AbstractPrincipalCollection +{ /** * This method returns a node for a principal. * @@ -24,8 +24,8 @@ class PrincipalCollection extends AbstractPrincipalCollection { * @param array $principal * @return \Sabre\DAV\INode */ - public function getChildForPrincipal(array $principal) { - + public function getChildForPrincipal(array $principal) + { return new Principal($this->principalBackend, $principal); } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/Acl.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/Acl.php index 4c3fcfcd09..58d4368602 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/Acl.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/Acl.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Acl extends DAV\Property { - +class Acl extends DAV\Property +{ /** * List of privileges * @@ -45,8 +45,8 @@ class Acl extends DAV\Property { * @param bool $prefixBaseUrl * @param array $privileges */ - public function __construct(array $privileges, $prefixBaseUrl = true) { - + public function __construct(array $privileges, $prefixBaseUrl = true) + { $this->privileges = $privileges; $this->prefixBaseUrl = $prefixBaseUrl; @@ -57,8 +57,8 @@ public function __construct(array $privileges, $prefixBaseUrl = true) { * * @return array */ - public function getPrivileges() { - + public function getPrivileges() + { return $this->privileges; } @@ -70,10 +70,10 @@ public function getPrivileges() { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server,\DOMElement $node) { - + public function serialize(DAV\Server $server,\DOMElement $node) + { $doc = $node->ownerDocument; - foreach($this->privileges as $ace) { + foreach ($this->privileges as $ace) { $this->serializeAce($doc, $node, $ace, $server); @@ -87,11 +87,11 @@ public function serialize(DAV\Server $server,\DOMElement $node) { * @param \DOMElement $dom * @return Acl */ - static public function unserialize(\DOMElement $dom) { - + public static function unserialize(\DOMElement $dom) + { $privileges = array(); $xaces = $dom->getElementsByTagNameNS('urn:DAV','ace'); - for($ii=0; $ii < $xaces->length; $ii++) { + for ($ii=0; $ii < $xaces->length; $ii++) { $xace = $xaces->item($ii); $principal = $xace->getElementsByTagNameNS('urn:DAV','principal'); @@ -100,7 +100,7 @@ static public function unserialize(\DOMElement $dom) { } $principal = Principal::unserialize($principal->item(0)); - switch($principal->getType()) { + switch ($principal->getType()) { case Principal::HREF : $principal = $principal->getHref(); break; @@ -129,7 +129,7 @@ static public function unserialize(\DOMElement $dom) { $grant = $grants->item(0); $xprivs = $grant->getElementsByTagNameNS('urn:DAV','privilege'); - for($jj=0; $jj<$xprivs->length; $jj++) { + for ($jj=0; $jj<$xprivs->length; $jj++) { $xpriv = $xprivs->item($jj); @@ -170,14 +170,14 @@ static public function unserialize(\DOMElement $dom) { * @param DAV\Server $server * @return void */ - private function serializeAce($doc,$node,$ace, DAV\Server $server) { - + private function serializeAce($doc,$node,$ace, DAV\Server $server) + { $xace = $doc->createElementNS('DAV:','d:ace'); $node->appendChild($xace); $principal = $doc->createElementNS('DAV:','d:principal'); $xace->appendChild($principal); - switch($ace['principal']) { + switch ($ace['principal']) { case '{DAV:}authenticated' : $principal->appendChild($doc->createElementNS('DAV:','d:authenticated')); break; diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/AclRestrictions.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/AclRestrictions.php index e3c3d3d1d0..c9ae9d290f 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/AclRestrictions.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/AclRestrictions.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class AclRestrictions extends DAV\Property { - +class AclRestrictions extends DAV\Property +{ /** * Serializes the property into a DOMElement * @@ -22,8 +22,8 @@ class AclRestrictions extends DAV\Property { * @param \DOMElement $elem * @return void */ - public function serialize(DAV\Server $server,\DOMElement $elem) { - + public function serialize(DAV\Server $server,\DOMElement $elem) + { $doc = $elem->ownerDocument; $elem->appendChild($doc->createElementNS('DAV:','d:grant-only')); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php index b1b428f713..13d3ce24ad 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php @@ -14,8 +14,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class CurrentUserPrivilegeSet extends DAV\Property { - +class CurrentUserPrivilegeSet extends DAV\Property +{ /** * List of privileges * @@ -30,8 +30,8 @@ class CurrentUserPrivilegeSet extends DAV\Property { * * @param array $privileges */ - public function __construct(array $privileges) { - + public function __construct(array $privileges) + { $this->privileges = $privileges; } @@ -43,10 +43,10 @@ public function __construct(array $privileges) { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server,\DOMElement $node) { - + public function serialize(DAV\Server $server,\DOMElement $node) + { $doc = $node->ownerDocument; - foreach($this->privileges as $privName) { + foreach ($this->privileges as $privName) { $this->serializePriv($doc,$node,$privName); @@ -62,8 +62,8 @@ public function serialize(DAV\Server $server,\DOMElement $node) { * @param string $privName * @return void */ - protected function serializePriv($doc,$node,$privName) { - + protected function serializePriv($doc,$node,$privName) + { $xp = $doc->createElementNS('DAV:','d:privilege'); $node->appendChild($xp); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/Principal.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/Principal.php index 9f59907dd7..7cc183ab85 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/Principal.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/Principal.php @@ -13,8 +13,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Principal extends DAV\Property implements DAV\Property\IHref { - +class Principal extends DAV\Property implements DAV\Property\IHref +{ /** * To specify a not-logged-in user, use the UNAUTHENTICATED principal */ @@ -63,8 +63,8 @@ class Principal extends DAV\Property implements DAV\Property\IHref { * @param int $type * @param string|null $href */ - public function __construct($type, $href = null) { - + public function __construct($type, $href = null) + { $this->type = $type; if ($type===self::HREF && is_null($href)) { @@ -79,8 +79,8 @@ public function __construct($type, $href = null) { * * @return int */ - public function getType() { - + public function getType() + { return $this->type; } @@ -90,8 +90,8 @@ public function getType() { * * @return string */ - public function getHref() { - + public function getHref() + { return $this->href; } @@ -103,10 +103,10 @@ public function getHref() { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server, \DOMElement $node) { - + public function serialize(DAV\Server $server, \DOMElement $node) + { $prefix = $server->xmlNamespaces['DAV:']; - switch($this->type) { + switch ($this->type) { case self::UNAUTHENTICATED : $node->appendChild( @@ -134,14 +134,14 @@ public function serialize(DAV\Server $server, \DOMElement $node) { * @param \DOMElement $dom * @return Principal */ - static public function unserialize(\DOMElement $dom) { - + public static function unserialize(\DOMElement $dom) + { $parent = $dom->firstChild; - while(!DAV\XMLUtil::toClarkNotation($parent)) { + while (!DAV\XMLUtil::toClarkNotation($parent)) { $parent = $parent->nextSibling; } - switch(DAV\XMLUtil::toClarkNotation($parent)) { + switch (DAV\XMLUtil::toClarkNotation($parent)) { case '{DAV:}unauthenticated' : return new self(self::UNAUTHENTICATED); diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/SupportedPrivilegeSet.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/SupportedPrivilegeSet.php index 920c52c14d..fc6a19a278 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/SupportedPrivilegeSet.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Property/SupportedPrivilegeSet.php @@ -18,8 +18,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class SupportedPrivilegeSet extends DAV\Property { - +class SupportedPrivilegeSet extends DAV\Property +{ /** * privileges * @@ -32,8 +32,8 @@ class SupportedPrivilegeSet extends DAV\Property { * * @param array $privileges */ - public function __construct(array $privileges) { - + public function __construct(array $privileges) + { $this->privileges = $privileges; } @@ -45,8 +45,8 @@ public function __construct(array $privileges) { * @param \DOMElement $node * @return void */ - public function serialize(DAV\Server $server,\DOMElement $node) { - + public function serialize(DAV\Server $server,\DOMElement $node) + { $doc = $node->ownerDocument; $this->serializePriv($doc, $node, $this->privileges); @@ -62,8 +62,8 @@ public function serialize(DAV\Server $server,\DOMElement $node) { * @param array $privilege * @return void */ - private function serializePriv($doc,$node,$privilege) { - + private function serializePriv($doc,$node,$privilege) + { $xsp = $doc->createElementNS('DAV:','d:supported-privilege'); $node->appendChild($xsp); @@ -84,7 +84,7 @@ private function serializePriv($doc,$node,$privilege) { } if (isset($privilege['aggregates'])) { - foreach($privilege['aggregates'] as $subPrivilege) { + foreach ($privilege['aggregates'] as $subPrivilege) { $this->serializePriv($doc,$xsp,$subPrivilege); } } diff --git a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Version.php b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Version.php index 2349c86de8..3486b8e4e4 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Version.php +++ b/core/src/core/classes/sabredav/lib/Sabre/DAVACL/Version.php @@ -9,8 +9,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Version { - +class Version +{ /** * Full version number */ diff --git a/core/src/core/classes/sabredav/lib/Sabre/HTTP/AWSAuth.php b/core/src/core/classes/sabredav/lib/Sabre/HTTP/AWSAuth.php index bec61188f9..d50c466421 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/HTTP/AWSAuth.php +++ b/core/src/core/classes/sabredav/lib/Sabre/HTTP/AWSAuth.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class AWSAuth extends AbstractAuth { - +class AWSAuth extends AbstractAuth +{ /** * The signature supplied by the HTTP client * @@ -49,8 +49,8 @@ class AWSAuth extends AbstractAuth { * * @return bool */ - public function init() { - + public function init() + { $authHeader = $this->httpRequest->getHeader('Authorization'); $authHeader = explode(' ',$authHeader); @@ -70,8 +70,8 @@ public function init() { * * @return string */ - public function getAccessKey() { - + public function getAccessKey() + { return $this->accessKey; } @@ -82,8 +82,8 @@ public function getAccessKey() { * @param string $secretKey * @return bool */ - public function validate($secretKey) { - + public function validate($secretKey) + { $contentMD5 = $this->httpRequest->getHeader('Content-MD5'); if ($contentMD5) { @@ -137,8 +137,8 @@ public function validate($secretKey) { * * @return void */ - public function requireLogin() { - + public function requireLogin() + { $this->httpResponse->setHeader('WWW-Authenticate','AWS'); $this->httpResponse->sendStatus(401); @@ -156,8 +156,8 @@ public function requireLogin() { * @param string $dateHeader * @return bool */ - protected function validateRFC2616Date($dateHeader) { - + protected function validateRFC2616Date($dateHeader) + { $date = Util::parseHTTPDate($dateHeader); // Unknown format @@ -184,11 +184,11 @@ protected function validateRFC2616Date($dateHeader) { * * @return string */ - protected function getAmzHeaders() { - + protected function getAmzHeaders() + { $amzHeaders = array(); $headers = $this->httpRequest->getHeaders(); - foreach($headers as $headerName => $headerValue) { + foreach ($headers as $headerName => $headerValue) { if (strpos(strtolower($headerName),'x-amz-')===0) { $amzHeaders[strtolower($headerName)] = str_replace(array("\r\n"),array(' '),$headerValue) . "\n"; } @@ -196,7 +196,7 @@ protected function getAmzHeaders() { ksort($amzHeaders); $headerStr = ''; - foreach($amzHeaders as $h=>$v) { + foreach ($amzHeaders as $h=>$v) { $headerStr.=$h.':'.$v; } @@ -211,8 +211,8 @@ protected function getAmzHeaders() { * @param string $message * @return string */ - private function hmacsha1($key, $message) { - + private function hmacsha1($key, $message) + { $blocksize=64; if (strlen($key)>$blocksize) $key=pack('H*', sha1($key)); diff --git a/core/src/core/classes/sabredav/lib/Sabre/HTTP/AbstractAuth.php b/core/src/core/classes/sabredav/lib/Sabre/HTTP/AbstractAuth.php index 4d52a91f4b..f3509d3ff9 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/HTTP/AbstractAuth.php +++ b/core/src/core/classes/sabredav/lib/Sabre/HTTP/AbstractAuth.php @@ -8,11 +8,11 @@ * This class has the common functionality for BasicAuth and DigestAuth * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class AbstractAuth { - +abstract class AbstractAuth +{ /** * The realm will be displayed in the dialog boxes * @@ -41,8 +41,8 @@ abstract class AbstractAuth { * __construct * */ - public function __construct() { - + public function __construct() + { $this->httpResponse = new Response(); $this->httpRequest = new Request(); @@ -54,8 +54,8 @@ public function __construct() { * @param Response $response * @return void */ - public function setHTTPResponse(Response $response) { - + public function setHTTPResponse(Response $response) + { $this->httpResponse = $response; } @@ -66,8 +66,8 @@ public function setHTTPResponse(Response $response) { * @param Request $request * @return void */ - public function setHTTPRequest(Request $request) { - + public function setHTTPRequest(Request $request) + { $this->httpRequest = $request; } @@ -82,8 +82,8 @@ public function setHTTPRequest(Request $request) { * @param string $realm * @return void */ - public function setRealm($realm) { - + public function setRealm($realm) + { $this->realm = $realm; } @@ -93,8 +93,8 @@ public function setRealm($realm) { * * @return string */ - public function getRealm() { - + public function getRealm() + { return $this->realm; } diff --git a/core/src/core/classes/sabredav/lib/Sabre/HTTP/BasicAuth.php b/core/src/core/classes/sabredav/lib/Sabre/HTTP/BasicAuth.php index 6f954752c4..326bbc3039 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/HTTP/BasicAuth.php +++ b/core/src/core/classes/sabredav/lib/Sabre/HTTP/BasicAuth.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class BasicAuth extends AbstractAuth { - +class BasicAuth extends AbstractAuth +{ /** * Returns the supplied username and password. * @@ -24,8 +24,8 @@ class BasicAuth extends AbstractAuth { * * @return mixed */ - public function getUserPass() { - + public function getUserPass() + { // Apache and mod_php if (($user = $this->httpRequest->getRawServerValue('PHP_AUTH_USER')) && ($pass = $this->httpRequest->getRawServerValue('PHP_AUTH_PW'))) { @@ -57,8 +57,8 @@ public function getUserPass() { * * @return void */ - public function requireLogin() { - + public function requireLogin() + { $this->httpResponse->setHeader('WWW-Authenticate','Basic realm="' . $this->realm . '"'); $this->httpResponse->sendStatus(401); diff --git a/core/src/core/classes/sabredav/lib/Sabre/HTTP/DigestAuth.php b/core/src/core/classes/sabredav/lib/Sabre/HTTP/DigestAuth.php index 094a239fe0..e6d323ab54 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/HTTP/DigestAuth.php +++ b/core/src/core/classes/sabredav/lib/Sabre/HTTP/DigestAuth.php @@ -22,11 +22,11 @@ * * * @copyright Copyright (C) 2007-2013 Rooftop Solutions. All rights reserved. - * @author Evert Pot (http://www.rooftopsolutions.nl/) + * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class DigestAuth extends AbstractAuth { - +class DigestAuth extends AbstractAuth +{ /** * These constants are used in setQOP(); */ @@ -42,8 +42,8 @@ class DigestAuth extends AbstractAuth { /** * Initializes the object */ - public function __construct() { - + public function __construct() + { $this->nonce = uniqid(); $this->opaque = md5($this->realm); parent::__construct(); @@ -57,8 +57,8 @@ public function __construct() { * * @return void */ - public function init() { - + public function init() + { $digest = $this->getDigest(); $this->digestParts = $this->parseDigest($digest); @@ -80,8 +80,8 @@ public function init() { * @param int $qop * @return void */ - public function setQOP($qop) { - + public function setQOP($qop) + { $this->qop = $qop; } @@ -94,8 +94,8 @@ public function setQOP($qop) { * @param string $A1 * @return bool */ - public function validateA1($A1) { - + public function validateA1($A1) + { $this->A1 = $A1; return $this->validate(); @@ -108,8 +108,8 @@ public function validateA1($A1) { * @param string $password * @return bool */ - public function validatePassword($password) { - + public function validatePassword($password) + { $this->A1 = md5($this->digestParts['username'] . ':' . $this->realm . ':' . $password); return $this->validate(); @@ -120,8 +120,8 @@ public function validatePassword($password) { * * @return string */ - public function getUsername() { - + public function getUsername() + { return $this->digestParts['username']; } @@ -131,8 +131,8 @@ public function getUsername() { * * @return bool */ - protected function validate() { - + protected function validate() + { $A2 = $this->httpRequest->getMethod() . ':' . $this->digestParts['uri']; if ($this->digestParts['qop']=='auth-int') { @@ -164,10 +164,10 @@ protected function validate() { * * @return void */ - public function requireLogin() { - + public function requireLogin() + { $qop = ''; - switch($this->qop) { + switch ($this->qop) { case self::QOP_AUTH : $qop = 'auth'; break; case self::QOP_AUTHINT : $qop = 'auth-int'; break; case self::QOP_AUTH | self::QOP_AUTHINT : $qop = 'auth,auth-int'; break; @@ -188,8 +188,8 @@ public function requireLogin() { * * @return mixed */ - public function getDigest() { - + public function getDigest() + { // mod_php $digest = $this->httpRequest->getRawServerValue('PHP_AUTH_DIGEST'); if ($digest) return $digest; @@ -220,8 +220,8 @@ public function getDigest() { * @param string $digest * @return mixed */ - protected function parseDigest($digest) { - + protected function parseDigest($digest) + { // protect against missing data $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1); $data = array(); diff --git a/core/src/core/classes/sabredav/lib/Sabre/HTTP/Request.php b/core/src/core/classes/sabredav/lib/Sabre/HTTP/Request.php index a42398f1bf..76ac3102ef 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/HTTP/Request.php +++ b/core/src/core/classes/sabredav/lib/Sabre/HTTP/Request.php @@ -16,8 +16,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Request { - +class Request +{ /** * PHP's $_SERVER data * @@ -48,7 +48,7 @@ class Request { * * @var resource */ - static $defaultInputStream=null; + public static $defaultInputStream=null; /** * Sets up the object @@ -59,8 +59,8 @@ class Request { * @param array $serverData * @param array $postData */ - public function __construct(array $serverData = null, array $postData = null) { - + public function __construct(array $serverData = null, array $postData = null) + { if ($serverData) $this->_SERVER = $serverData; else $this->_SERVER =& $_SERVER; @@ -77,8 +77,8 @@ public function __construct(array $serverData = null, array $postData = null) { * @param string $name * @return string */ - public function getHeader($name) { - + public function getHeader($name) + { $name = strtoupper(str_replace(array('-'),array('_'),$name)); if (isset($this->_SERVER['HTTP_' . $name])) { return $this->_SERVER['HTTP_' . $name]; @@ -86,7 +86,7 @@ public function getHeader($name) { // There's a few headers that seem to end up in the top-level // server array. - switch($name) { + switch ($name) { case 'CONTENT_TYPE' : case 'CONTENT_LENGTH' : if (isset($this->_SERVER[$name])) { @@ -107,12 +107,12 @@ public function getHeader($name) { * * @return array */ - public function getHeaders() { - + public function getHeaders() + { $hdrs = array(); - foreach($this->_SERVER as $key=>$value) { + foreach ($this->_SERVER as $key=>$value) { - switch($key) { + switch ($key) { case 'CONTENT_LENGTH' : case 'CONTENT_TYPE' : $hdrs[strtolower(str_replace('_','-',$key))] = $value; @@ -137,8 +137,8 @@ public function getHeaders() { * * @return string */ - public function getMethod() { - + public function getMethod() + { return $this->_SERVER['REQUEST_METHOD']; } @@ -148,8 +148,8 @@ public function getMethod() { * * @return string */ - public function getUri() { - + public function getUri() + { return $this->_SERVER['REQUEST_URI']; } @@ -159,8 +159,8 @@ public function getUri() { * * @return string */ - public function getAbsoluteUri() { - + public function getAbsoluteUri() + { // Checking if the request was made through HTTPS. The last in line is for IIS $protocol = isset($this->_SERVER['HTTPS']) && ($this->_SERVER['HTTPS']) && ($this->_SERVER['HTTPS']!='off'); return ($protocol?'https':'http') . '://' . $this->getHeader('Host') . $this->getUri(); @@ -172,8 +172,8 @@ public function getAbsoluteUri() { * * @return string */ - public function getQueryString() { - + public function getQueryString() + { return isset($this->_SERVER['QUERY_STRING'])?$this->_SERVER['QUERY_STRING']:''; } @@ -187,8 +187,8 @@ public function getQueryString() { * @param bool $asString * @return resource */ - public function getBody($asString = false) { - + public function getBody($asString = false) + { if (is_null($this->body)) { if (!is_null(self::$defaultInputStream)) { $this->body = self::$defaultInputStream; @@ -218,9 +218,9 @@ public function getBody($asString = false) { * @param bool $setAsDefaultInputStream * @return void */ - public function setBody($body,$setAsDefaultInputStream = false) { - - if(is_resource($body)) { + public function setBody($body,$setAsDefaultInputStream = false) + { + if (is_resource($body)) { $this->body = $body; } else { @@ -244,8 +244,8 @@ public function setBody($body,$setAsDefaultInputStream = false) { * * @return array */ - public function getPostVars() { - + public function getPostVars() + { return $this->_POST; } @@ -258,8 +258,8 @@ public function getPostVars() { * @param string $field * @return string */ - public function getRawServerValue($field) { - + public function getRawServerValue($field) + { return isset($this->_SERVER[$field])?$this->_SERVER[$field]:null; } @@ -269,8 +269,8 @@ public function getRawServerValue($field) { * * @return string */ - public function getHTTPVersion() { - + public function getHTTPVersion() + { $protocol = $this->getRawServerValue('SERVER_PROTOCOL'); if ($protocol==='HTTP/1.0') { return '1.0'; @@ -281,4 +281,3 @@ public function getHTTPVersion() { } } - diff --git a/core/src/core/classes/sabredav/lib/Sabre/HTTP/Response.php b/core/src/core/classes/sabredav/lib/Sabre/HTTP/Response.php index af0e73e01f..3d2615c7b0 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/HTTP/Response.php +++ b/core/src/core/classes/sabredav/lib/Sabre/HTTP/Response.php @@ -11,8 +11,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Response { - +class Response +{ /** * The HTTP version to return in the header() line. * @@ -30,8 +30,8 @@ class Response { * @param int $code * @return string */ - public function getStatusMessage($code, $httpVersion = '1.1') { - + public function getStatusMessage($code, $httpVersion = '1.1') + { $msg = array( 100 => 'Continue', 101 => 'Switching Protocols', @@ -107,8 +107,8 @@ public function getStatusMessage($code, $httpVersion = '1.1') { * @param int $code HTTP status code * @return bool */ - public function sendStatus($code) { - + public function sendStatus($code) + { if (!headers_sent()) return header($this->getStatusMessage($code, $this->defaultHttpVersion)); else return false; @@ -123,8 +123,8 @@ public function sendStatus($code) { * @param bool $replace * @return bool */ - public function setHeader($name, $value, $replace = true) { - + public function setHeader($name, $value, $replace = true) + { $value = str_replace(array("\r","\n"),array('\r','\n'),$value); if (!headers_sent()) return header($name . ': ' . $value, $replace); @@ -142,8 +142,8 @@ public function setHeader($name, $value, $replace = true) { * @param array $headers * @return void */ - public function setHeaders(array $headers) { - + public function setHeaders(array $headers) + { foreach($headers as $key=>$value) $this->setHeader($key, $value); @@ -157,8 +157,8 @@ public function setHeaders(array $headers) { * @param mixed $body * @return void */ - public function sendBody($body) { - + public function sendBody($body) + { if (is_resource($body)) { fpassthru($body); diff --git a/core/src/core/classes/sabredav/lib/Sabre/HTTP/Util.php b/core/src/core/classes/sabredav/lib/Sabre/HTTP/Util.php index 0c428174ed..a1df16a89a 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/HTTP/Util.php +++ b/core/src/core/classes/sabredav/lib/Sabre/HTTP/Util.php @@ -10,8 +10,8 @@ * @author Paul Voegler * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Util { - +class Util +{ /** * Parses a RFC2616-compatible date string * @@ -20,8 +20,8 @@ class Util { * @param string $dateHeader * @return bool|DateTime */ - static function parseHTTPDate($dateHeader) { - + public static function parseHTTPDate($dateHeader) + { //RFC 2616 section 3.3.1 Full Date //Only the format is checked, valid ranges are checked by strtotime below $month = '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)'; @@ -69,8 +69,8 @@ static function parseHTTPDate($dateHeader) { * @param \DateTime $dateTime * @return string */ - static function toHTTPDate(\DateTime $dateTime) { - + public static function toHTTPDate(\DateTime $dateTime) + { // We need to clone it, as we don't want to affect the existing // DateTime. $dateTime = clone $dateTime; diff --git a/core/src/core/classes/sabredav/lib/Sabre/HTTP/Version.php b/core/src/core/classes/sabredav/lib/Sabre/HTTP/Version.php index baa40c03bf..20e006b0dd 100644 --- a/core/src/core/classes/sabredav/lib/Sabre/HTTP/Version.php +++ b/core/src/core/classes/sabredav/lib/Sabre/HTTP/Version.php @@ -9,8 +9,8 @@ * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Version { - +class Version +{ /** * Full version number */ diff --git a/core/src/core/classes/securimage/securimage.php b/core/src/core/classes/securimage/securimage.php index ebabab0fe8..4857fb50bc 100644 --- a/core/src/core/classes/securimage/securimage.php +++ b/core/src/core/classes/securimage/securimage.php @@ -54,7 +54,7 @@ - Flash button to stream mp3 audio (Douglas Walsh www.douglaswalsh.net) - Audio output is mp3 format by default - Change font to AlteHaasGrotesk by yann le coroller - - Some code cleanup + - Some code cleanup 1.0.4 (unreleased) - Ability to output audible codes in mp3 format to stream from flash @@ -104,1412 +104,1411 @@ * @subpackage classes * */ -class Securimage { - - /** - * The desired width of the CAPTCHA image. - * - * @var int - */ - var $image_width; - - /** - * The desired width of the CAPTCHA image. - * - * @var int - */ - var $image_height; - - /** - * The image format for output.
    - * Valid options: SI_IMAGE_PNG, SI_IMAGE_JPG, SI_IMAGE_GIF - * - * @var int - */ - var $image_type; - - /** - * The length of the code to generate. - * - * @var int - */ - var $code_length; - - /** - * The character set for individual characters in the image.
    - * Letters are converted to uppercase.
    - * The font must support the letters or there may be problematic substitutions. - * - * @var string - */ - var $charset; - - /** - * Create codes using this word list - * - * @var string The path to the word list to use for creating CAPTCHA codes - */ - var $wordlist_file; - - /** - * Use wordlist of not - * - * @var bool true to use wordlist file, false to use random code - */ - var $use_wordlist = false; - - /** - * Note: Use of GD fonts is not recommended as many distortion features are not available
    - * The GD font to use.
    - * Internal gd fonts can be loaded by their number.
    - * Alternatively, a file path can be given and the font will be loaded from file. - * - * @var mixed - */ - var $gd_font_file; - - /** - * The approximate size of the font in pixels.
    - * This does not control the size of the font because that is determined by the GD font itself.
    - * This is used to aid the calculations of positioning used by this class.
    - * - * @var int - */ - var $gd_font_size; - - /** - * Use a gd font instead of TTF - * - * @var bool true for gd font, false for TTF - */ - var $use_gd_font; - - // Note: These font options below do not apply if you set $use_gd_font to true with the exception of $text_color - - /** - * The path to the TTF font file to load. - * - * @var string - */ - var $ttf_file; - - /** - * How much to distort image, higher = more distortion.
    - * Distortion is only available when using TTF fonts.
    - * - * @var float - */ - var $perturbation; - - /** - * The minimum angle in degrees, with 0 degrees being left-to-right reading text.
    - * Higher values represent a counter-clockwise rotation.
    - * For example, a value of 90 would result in bottom-to-top reading text.
    - * This value along with maximum angle distance do not need to be very high with perturbation - * - * @var int - */ - var $text_angle_minimum; - - /** - * The minimum angle in degrees, with 0 degrees being left-to-right reading text.
    - * Higher values represent a counter-clockwise rotation.
    - * For example, a value of 90 would result in bottom-to-top reading text. - * - * @var int - */ - var $text_angle_maximum; - - /** - * The X-Position on the image where letter drawing will begin.
    - * This value is in pixels from the left side of the image. - * - * @var int - * @deprecated 2.0 - */ - var $text_x_start; - - /** - * The background color for the image as a Securimage_Color.
    - * - * @var Securimage_Color - */ - var $image_bg_color; - - /** - * Scan this directory for gif, jpg, and png files to use as background images.
    - * A random image file will be picked each time.
    - * Change from null to the full path to your directory.
    - * i.e. var $background_directory = $_SERVER['DOCUMENT_ROOT'] . '/securimage/backgrounds'; - * Make sure not to pass a background image to the show function, otherwise this directive is ignored. - * - * @var string - */ - var $background_directory = null; //'./backgrounds'; - - /** - * The text color to use for drawing characters as a Securimage_Color.
    - * This value is ignored if $use_multi_text is set to true.
    - * Make sure this contrasts well with the background color or image.
    - * - * @see Securimage::$use_multi_text - * @var Securimage_Color - */ - var $text_color; - - /** - * Set to true to use multiple colors for each character. - * - * @see Securimage::$multi_text_color - * @var boolean - */ - var $use_multi_text; - - /** - * Array of Securimage_Colors which will be randomly selected for each letter.
    - * - * @var array - */ - var $multi_text_color; - - /** - * Set to true to make the characters appear transparent. - * - * @see Securimage::$text_transparency_percentage - * @var boolean - */ - var $use_transparent_text; - - /** - * The percentage of transparency, 0 to 100.
    - * A value of 0 is completely opaque, 100 is completely transparent (invisble) - * - * @see Securimage::$use_transparent_text - * @var int - */ - var $text_transparency_percentage; - - - // Line options - /** - * Draw vertical and horizontal lines on the image. - * - * @see Securimage::$line_color - * @see Securimage::$draw_lines_over_text - * @var boolean - */ - var $num_lines; - - /** - * Color of lines drawn over text - * - * @var string - */ - var $line_color; - - /** - * Draw the lines over the text.
    - * If fales lines will be drawn before putting the text on the image. - * - * @var boolean - */ - var $draw_lines_over_text; - - /** - * Text to write at the bottom corner of captcha image - * - * @since 2.0 - * @var string Signature text - */ - var $image_signature; - - /** - * Color to use for writing signature text - * - * @since 2.0 - * @var Securimage_Color - */ - var $signature_color; - - /** - * Full path to the WAV files to use to make the audio files, include trailing /.
    - * Name Files [A-Z0-9].wav - * - * @since 1.0.1 - * @var string - */ - var $audio_path; - - /** - * Type of audio file to generate (mp3 or wav) - * - * @var string - */ - var $audio_format; - - /** - * The session name to use if not the default. Blank for none - * - * @see http://php.net/session_name - * @since 2.0 - * @var string - */ - var $session_name = ''; - - /** - * The amount of time in seconds that a code remains valid.
    - * Any code older than this number will be considered invalid even if entered correctly.
    - * Any non-numeric or value less than 1 disables this functionality. - * - * @var int - */ - var $expiry_time; - - /** - * Path to the file to use for storing codes for users.
    - * THIS FILE MUST ABSOLUTELY NOT BE ACCESSIBLE FROM A WEB BROWSER!!
    - * Put this file in a directory below the web root or one that is restricted (i.e. an apache .htaccess file with deny from all)
    - * If you cannot meet those requirements your forms may not be completely protected.
    - * You could obscure the database file name but this is also not recommended. - * - * @var string - */ - var $sqlite_database; - - /** - * Use an SQLite database for storing codes as a backup to sessions.
    - * Note: Sessions will still be used - */ - var $use_sqlite_db; - - - //END USER CONFIGURATION - //There should be no need to edit below unless you really know what you are doing. - - /** - * The gd image resource. - * - * @access private - * @var resource - */ - var $im; - - /** - * Temporary image for rendering - * - * @access private - * @var resource - */ - var $tmpimg; - - /** - * Internal scale factor for anti-alias @hkcaptcha - * - * @access private - * @since 2.0 - * @var int - */ - var $iscale; // internal scale factor for anti-alias @hkcaptcha - - /** - * The background image resource - * - * @access private - * @var resource - */ - var $bgimg; - - /** - * The code generated by the script - * - * @access private - * @var string - */ - var $code; - - /** - * The code that was entered by the user - * - * @access private - * @var string - */ - var $code_entered; - - /** - * Whether or not the correct code was entered - * - * @access private - * @var boolean - */ - var $correct_code; - - /** - * Handle to SQLite database - * - * @access private - * @var resource - */ - var $sqlite_handle; - - /** - * Color resource for image line color - * - * @access private - * @var int - */ - var $gdlinecolor; - - /** - * Array of colors for multi colored codes - * - * @access private - * @var array - */ - var $gdmulticolor; - - /** - * Color resource for image font color - * - * @access private - * @var int - */ - var $gdtextcolor; - - /** - * Color resource for image signature color - * - * @access private - * @var int - */ - var $gdsignaturecolor; - - /** - * Color resource for image background color - * - * @access private - * @var int - */ - var $gdbgcolor; - - - /** - * Class constructor.
    - * Because the class uses sessions, this will attempt to start a session if there is no previous one.
    - * If you do not start a session before calling the class, the constructor must be called before any - * output is sent to the browser. - * - * - * $securimage = new Securimage(); - * - * - */ - function Securimage() - { - // Initialize session or attach to existing - if ( session_id() == '' ) { // no session has been started yet, which is needed for validation - if (trim($this->session_name) != '') { - session_name($this->session_name); // set session name if provided - } - session_start(); - } - - // Set Default Values - $this->image_width = 230; - $this->image_height = 80; - $this->image_type = SI_IMAGE_PNG; - - $this->code_length = 6; - $this->charset = 'ABCDEFGHKLMNPRSTUVWYZabcdefghklmnprstuvwyz23456789'; - $this->wordlist_file = './words/words.txt'; - $this->use_wordlist = false; - - $this->gd_font_file = 'gdfonts/automatic.gdf'; - $this->use_gd_font = false; - $this->gd_font_size = 24; - $this->text_x_start = 15; - - $this->ttf_file = './AHGBold.ttf'; - - $this->perturbation = 0.75; - $this->iscale = 5; - $this->text_angle_minimum = 0; - $this->text_angle_maximum = 0; - - $this->image_bg_color = new Securimage_Color(0xff, 0xff, 0xff); +class Securimage +{ + /** + * The desired width of the CAPTCHA image. + * + * @var int + */ + public $image_width; + + /** + * The desired width of the CAPTCHA image. + * + * @var int + */ + public $image_height; + + /** + * The image format for output.
    + * Valid options: SI_IMAGE_PNG, SI_IMAGE_JPG, SI_IMAGE_GIF + * + * @var int + */ + public $image_type; + + /** + * The length of the code to generate. + * + * @var int + */ + public $code_length; + + /** + * The character set for individual characters in the image.
    + * Letters are converted to uppercase.
    + * The font must support the letters or there may be problematic substitutions. + * + * @var string + */ + public $charset; + + /** + * Create codes using this word list + * + * @var string The path to the word list to use for creating CAPTCHA codes + */ + public $wordlist_file; + + /** + * Use wordlist of not + * + * @var bool true to use wordlist file, false to use random code + */ + public $use_wordlist = false; + + /** + * Note: Use of GD fonts is not recommended as many distortion features are not available
    + * The GD font to use.
    + * Internal gd fonts can be loaded by their number.
    + * Alternatively, a file path can be given and the font will be loaded from file. + * + * @var mixed + */ + public $gd_font_file; + + /** + * The approximate size of the font in pixels.
    + * This does not control the size of the font because that is determined by the GD font itself.
    + * This is used to aid the calculations of positioning used by this class.
    + * + * @var int + */ + public $gd_font_size; + + /** + * Use a gd font instead of TTF + * + * @var bool true for gd font, false for TTF + */ + public $use_gd_font; + + // Note: These font options below do not apply if you set $use_gd_font to true with the exception of $text_color + + /** + * The path to the TTF font file to load. + * + * @var string + */ + public $ttf_file; + + /** + * How much to distort image, higher = more distortion.
    + * Distortion is only available when using TTF fonts.
    + * + * @var float + */ + public $perturbation; + + /** + * The minimum angle in degrees, with 0 degrees being left-to-right reading text.
    + * Higher values represent a counter-clockwise rotation.
    + * For example, a value of 90 would result in bottom-to-top reading text.
    + * This value along with maximum angle distance do not need to be very high with perturbation + * + * @var int + */ + public $text_angle_minimum; + + /** + * The minimum angle in degrees, with 0 degrees being left-to-right reading text.
    + * Higher values represent a counter-clockwise rotation.
    + * For example, a value of 90 would result in bottom-to-top reading text. + * + * @var int + */ + public $text_angle_maximum; + + /** + * The X-Position on the image where letter drawing will begin.
    + * This value is in pixels from the left side of the image. + * + * @var int + * @deprecated 2.0 + */ + public $text_x_start; + + /** + * The background color for the image as a Securimage_Color.
    + * + * @var Securimage_Color + */ + public $image_bg_color; + + /** + * Scan this directory for gif, jpg, and png files to use as background images.
    + * A random image file will be picked each time.
    + * Change from null to the full path to your directory.
    + * i.e. var $background_directory = $_SERVER['DOCUMENT_ROOT'] . '/securimage/backgrounds'; + * Make sure not to pass a background image to the show function, otherwise this directive is ignored. + * + * @var string + */ + public $background_directory = null; //'./backgrounds'; + + /** + * The text color to use for drawing characters as a Securimage_Color.
    + * This value is ignored if $use_multi_text is set to true.
    + * Make sure this contrasts well with the background color or image.
    + * + * @see Securimage::$use_multi_text + * @var Securimage_Color + */ + public $text_color; + + /** + * Set to true to use multiple colors for each character. + * + * @see Securimage::$multi_text_color + * @var boolean + */ + public $use_multi_text; + + /** + * Array of Securimage_Colors which will be randomly selected for each letter.
    + * + * @var array + */ + public $multi_text_color; + + /** + * Set to true to make the characters appear transparent. + * + * @see Securimage::$text_transparency_percentage + * @var boolean + */ + public $use_transparent_text; + + /** + * The percentage of transparency, 0 to 100.
    + * A value of 0 is completely opaque, 100 is completely transparent (invisble) + * + * @see Securimage::$use_transparent_text + * @var int + */ + public $text_transparency_percentage; + + + // Line options + /** + * Draw vertical and horizontal lines on the image. + * + * @see Securimage::$line_color + * @see Securimage::$draw_lines_over_text + * @var boolean + */ + public $num_lines; + + /** + * Color of lines drawn over text + * + * @var string + */ + public $line_color; + + /** + * Draw the lines over the text.
    + * If fales lines will be drawn before putting the text on the image. + * + * @var boolean + */ + public $draw_lines_over_text; + + /** + * Text to write at the bottom corner of captcha image + * + * @since 2.0 + * @var string Signature text + */ + public $image_signature; + + /** + * Color to use for writing signature text + * + * @since 2.0 + * @var Securimage_Color + */ + public $signature_color; + + /** + * Full path to the WAV files to use to make the audio files, include trailing /.
    + * Name Files [A-Z0-9].wav + * + * @since 1.0.1 + * @var string + */ + public $audio_path; + + /** + * Type of audio file to generate (mp3 or wav) + * + * @var string + */ + public $audio_format; + + /** + * The session name to use if not the default. Blank for none + * + * @see http://php.net/session_name + * @since 2.0 + * @var string + */ + public $session_name = ''; + + /** + * The amount of time in seconds that a code remains valid.
    + * Any code older than this number will be considered invalid even if entered correctly.
    + * Any non-numeric or value less than 1 disables this functionality. + * + * @var int + */ + public $expiry_time; + + /** + * Path to the file to use for storing codes for users.
    + * THIS FILE MUST ABSOLUTELY NOT BE ACCESSIBLE FROM A WEB BROWSER!!
    + * Put this file in a directory below the web root or one that is restricted (i.e. an apache .htaccess file with deny from all)
    + * If you cannot meet those requirements your forms may not be completely protected.
    + * You could obscure the database file name but this is also not recommended. + * + * @var string + */ + public $sqlite_database; + + /** + * Use an SQLite database for storing codes as a backup to sessions.
    + * Note: Sessions will still be used + */ + public $use_sqlite_db; + + + //END USER CONFIGURATION + //There should be no need to edit below unless you really know what you are doing. + + /** + * The gd image resource. + * + * @access private + * @var resource + */ + public $im; + + /** + * Temporary image for rendering + * + * @access private + * @var resource + */ + public $tmpimg; + + /** + * Internal scale factor for anti-alias @hkcaptcha + * + * @access private + * @since 2.0 + * @var int + */ + public $iscale; // internal scale factor for anti-alias @hkcaptcha + + /** + * The background image resource + * + * @access private + * @var resource + */ + public $bgimg; + + /** + * The code generated by the script + * + * @access private + * @var string + */ + public $code; + + /** + * The code that was entered by the user + * + * @access private + * @var string + */ + public $code_entered; + + /** + * Whether or not the correct code was entered + * + * @access private + * @var boolean + */ + public $correct_code; + + /** + * Handle to SQLite database + * + * @access private + * @var resource + */ + public $sqlite_handle; + + /** + * Color resource for image line color + * + * @access private + * @var int + */ + public $gdlinecolor; + + /** + * Array of colors for multi colored codes + * + * @access private + * @var array + */ + public $gdmulticolor; + + /** + * Color resource for image font color + * + * @access private + * @var int + */ + public $gdtextcolor; + + /** + * Color resource for image signature color + * + * @access private + * @var int + */ + public $gdsignaturecolor; + + /** + * Color resource for image background color + * + * @access private + * @var int + */ + public $gdbgcolor; + + + /** + * Class constructor.
    + * Because the class uses sessions, this will attempt to start a session if there is no previous one.
    + * If you do not start a session before calling the class, the constructor must be called before any + * output is sent to the browser. + * + * + * $securimage = new Securimage(); + * + * + */ + public function Securimage() + { + // Initialize session or attach to existing + if ( session_id() == '' ) { // no session has been started yet, which is needed for validation + if (trim($this->session_name) != '') { + session_name($this->session_name); // set session name if provided + } + session_start(); + } + + // Set Default Values + $this->image_width = 230; + $this->image_height = 80; + $this->image_type = SI_IMAGE_PNG; + + $this->code_length = 6; + $this->charset = 'ABCDEFGHKLMNPRSTUVWYZabcdefghklmnprstuvwyz23456789'; + $this->wordlist_file = './words/words.txt'; + $this->use_wordlist = false; + + $this->gd_font_file = 'gdfonts/automatic.gdf'; + $this->use_gd_font = false; + $this->gd_font_size = 24; + $this->text_x_start = 15; + + $this->ttf_file = './AHGBold.ttf'; + + $this->perturbation = 0.75; + $this->iscale = 5; + $this->text_angle_minimum = 0; + $this->text_angle_maximum = 0; + + $this->image_bg_color = new Securimage_Color(0xff, 0xff, 0xff); $this->text_color = new Securimage_Color(0x3d, 0x3d, 0x3d); - $this->multi_text_color = array(new Securimage_Color(0x0, 0x20, 0xCC), - new Securimage_Color(0x0, 0x30, 0xEE), - new Securimage_color(0x0, 0x40, 0xCC), - new Securimage_Color(0x0, 0x50, 0xEE), - new Securimage_Color(0x0, 0x60, 0xCC)); - $this->use_multi_text = false; - - $this->use_transparent_text = false; - $this->text_transparency_percentage = 30; - - $this->num_lines = 10; - $this->line_color = new Securimage_Color(0x3d, 0x3d, 0x3d); - $this->draw_lines_over_text = true; - - $this->image_signature = ''; - $this->signature_color = new Securimage_Color(0x20, 0x50, 0xCC); - $this->signature_font = './AHGBold.ttf'; - - $this->audio_path = './audio/'; - $this->audio_format = 'mp3'; - $this->session_name = ''; - $this->expiry_time = 900; - - $this->sqlite_database = 'database/securimage.sqlite'; - $this->use_sqlite_db = false; - - $this->sqlite_handle = false; - } - - /** - * Generate a code and output the image to the browser. - * - * - * show('bg.jpg'); - * ?> - * - * - * @param string $background_image The path to an image to use as the background for the CAPTCHA - */ - function show($background_image = "") - { - if($background_image != "" && is_readable($background_image)) { - $this->bgimg = $background_image; - } - - $this->doImage(); - } - - /** - * Validate the code entered by the user. - * - * - * $code = $_POST['code']; - * if ($securimage->check($code) == false) { - * die("Sorry, the code entered did not match."); - * } else { - * $valid = true; - * } - * - * @param string $code The code the user entered - * @return boolean true if the code was correct, false if not - */ - function check($code) - { - $this->code_entered = $code; - $this->validate(); - return $this->correct_code; - } - - /** - * Output audio file with HTTP headers to browser - * - * - * $sound = new Securimage(); - * $sound->audio_format = 'mp3'; - * $sound->outputAudioFile(); - * - * - * @since 2.0 - */ - function outputAudioFile() - { - if (strtolower($this->audio_format) == 'wav') { - header('Content-type: audio/x-wav'); - $ext = 'wav'; - } else { - header('Content-type: audio/mpeg'); // default to mp3 - $ext = 'mp3'; - } - - header("Content-Disposition: attachment; filename=\"securimage_audio.{$ext}\""); - header('Cache-Control: no-store, no-cache, must-revalidate'); - header('Expires: Sun, 1 Jan 2000 12:00:00 GMT'); - header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT'); - - $audio = $this->getAudibleCode($ext); - - header('Content-Length: ' . strlen($audio)); - - echo $audio; - exit; - } - - /** - * Generate and output the image - * - * @access private - * - */ - function doImage() - { - if ($this->use_gd_font == true) { - $this->iscale = 1; - } - if($this->use_transparent_text == true || $this->bgimg != "") { - $this->im = imagecreatetruecolor($this->image_width, $this->image_height); - $this->tmpimg = imagecreatetruecolor($this->image_width * $this->iscale, $this->image_height * $this->iscale); - - } else { //no transparency - $this->im = imagecreate($this->image_width, $this->image_height); - $this->tmpimg = imagecreate($this->image_width * $this->iscale, $this->image_height * $this->iscale); - } - - $this->allocateColors(); - imagepalettecopy($this->tmpimg, $this->im); - - $this->setBackground(); - - $this->createCode(); - - if (!$this->draw_lines_over_text && $this->num_lines > 0) $this->drawLines(); - - $this->drawWord(); - if ($this->use_gd_font == false && is_readable($this->ttf_file)) $this->distortedCopy(); - - if ($this->draw_lines_over_text && $this->num_lines > 0) $this->drawLines(); - - if (trim($this->image_signature) != '') $this->addSignature(); - - $this->output(); - - } - - /** - * Allocate all colors that will be used in the CAPTCHA image - * - * @since 2.0.1 - * @access private - */ - function allocateColors() - { - // allocate bg color first for imagecreate - $this->gdbgcolor = imagecolorallocate($this->im, $this->image_bg_color->r, $this->image_bg_color->g, $this->image_bg_color->b); - - $alpha = intval($this->text_transparency_percentage / 100 * 127); - - if ($this->use_transparent_text == true) { + $this->multi_text_color = array(new Securimage_Color(0x0, 0x20, 0xCC), + new Securimage_Color(0x0, 0x30, 0xEE), + new Securimage_color(0x0, 0x40, 0xCC), + new Securimage_Color(0x0, 0x50, 0xEE), + new Securimage_Color(0x0, 0x60, 0xCC)); + $this->use_multi_text = false; + + $this->use_transparent_text = false; + $this->text_transparency_percentage = 30; + + $this->num_lines = 10; + $this->line_color = new Securimage_Color(0x3d, 0x3d, 0x3d); + $this->draw_lines_over_text = true; + + $this->image_signature = ''; + $this->signature_color = new Securimage_Color(0x20, 0x50, 0xCC); + $this->signature_font = './AHGBold.ttf'; + + $this->audio_path = './audio/'; + $this->audio_format = 'mp3'; + $this->session_name = ''; + $this->expiry_time = 900; + + $this->sqlite_database = 'database/securimage.sqlite'; + $this->use_sqlite_db = false; + + $this->sqlite_handle = false; + } + + /** + * Generate a code and output the image to the browser. + * + * + * show('bg.jpg'); + * ?> + * + * + * @param string $background_image The path to an image to use as the background for the CAPTCHA + */ + public function show($background_image = "") + { + if ($background_image != "" && is_readable($background_image)) { + $this->bgimg = $background_image; + } + + $this->doImage(); + } + + /** + * Validate the code entered by the user. + * + * + * $code = $_POST['code']; + * if ($securimage->check($code) == false) { + * die("Sorry, the code entered did not match."); + * } else { + * $valid = true; + * } + * + * @param string $code The code the user entered + * @return boolean true if the code was correct, false if not + */ + public function check($code) + { + $this->code_entered = $code; + $this->validate(); + return $this->correct_code; + } + + /** + * Output audio file with HTTP headers to browser + * + * + * $sound = new Securimage(); + * $sound->audio_format = 'mp3'; + * $sound->outputAudioFile(); + * + * + * @since 2.0 + */ + public function outputAudioFile() + { + if (strtolower($this->audio_format) == 'wav') { + header('Content-type: audio/x-wav'); + $ext = 'wav'; + } else { + header('Content-type: audio/mpeg'); // default to mp3 + $ext = 'mp3'; + } + + header("Content-Disposition: attachment; filename=\"securimage_audio.{$ext}\""); + header('Cache-Control: no-store, no-cache, must-revalidate'); + header('Expires: Sun, 1 Jan 2000 12:00:00 GMT'); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT'); + + $audio = $this->getAudibleCode($ext); + + header('Content-Length: ' . strlen($audio)); + + echo $audio; + exit; + } + + /** + * Generate and output the image + * + * @access private + * + */ + public function doImage() + { + if ($this->use_gd_font == true) { + $this->iscale = 1; + } + if ($this->use_transparent_text == true || $this->bgimg != "") { + $this->im = imagecreatetruecolor($this->image_width, $this->image_height); + $this->tmpimg = imagecreatetruecolor($this->image_width * $this->iscale, $this->image_height * $this->iscale); + + } else { //no transparency + $this->im = imagecreate($this->image_width, $this->image_height); + $this->tmpimg = imagecreate($this->image_width * $this->iscale, $this->image_height * $this->iscale); + } + + $this->allocateColors(); + imagepalettecopy($this->tmpimg, $this->im); + + $this->setBackground(); + + $this->createCode(); + + if (!$this->draw_lines_over_text && $this->num_lines > 0) $this->drawLines(); + + $this->drawWord(); + if ($this->use_gd_font == false && is_readable($this->ttf_file)) $this->distortedCopy(); + + if ($this->draw_lines_over_text && $this->num_lines > 0) $this->drawLines(); + + if (trim($this->image_signature) != '') $this->addSignature(); + + $this->output(); + + } + + /** + * Allocate all colors that will be used in the CAPTCHA image + * + * @since 2.0.1 + * @access private + */ + public function allocateColors() + { + // allocate bg color first for imagecreate + $this->gdbgcolor = imagecolorallocate($this->im, $this->image_bg_color->r, $this->image_bg_color->g, $this->image_bg_color->b); + + $alpha = intval($this->text_transparency_percentage / 100 * 127); + + if ($this->use_transparent_text == true) { $this->gdtextcolor = imagecolorallocatealpha($this->im, $this->text_color->r, $this->text_color->g, $this->text_color->b, $alpha); $this->gdlinecolor = imagecolorallocatealpha($this->im, $this->line_color->r, $this->line_color->g, $this->line_color->b, $alpha); - } else { - $this->gdtextcolor = imagecolorallocate($this->im, $this->text_color->r, $this->text_color->g, $this->text_color->b); + } else { + $this->gdtextcolor = imagecolorallocate($this->im, $this->text_color->r, $this->text_color->g, $this->text_color->b); $this->gdlinecolor = imagecolorallocate($this->im, $this->line_color->r, $this->line_color->g, $this->line_color->b); - } - + } + $this->gdsignaturecolor = imagecolorallocate($this->im, $this->signature_color->r, $this->signature_color->g, $this->signature_color->b); - + if ($this->use_multi_text == true) { - $this->gdmulticolor = array(); - - foreach($this->multi_text_color as $color) { - if ($this->use_transparent_text == true) { - $this->gdmulticolor[] = imagecolorallocatealpha($this->im, $color->r, $color->g, $color->b, $alpha); - } else { - $this->gdmulticolor[] = imagecolorallocate($this->im, $color->r, $color->g, $color->b); - } - } + $this->gdmulticolor = array(); + + foreach ($this->multi_text_color as $color) { + if ($this->use_transparent_text == true) { + $this->gdmulticolor[] = imagecolorallocatealpha($this->im, $color->r, $color->g, $color->b, $alpha); + } else { + $this->gdmulticolor[] = imagecolorallocate($this->im, $color->r, $color->g, $color->b); + } + } } - } - - /** - * Set the background of the CAPTCHA image - * - * @access private - * - */ - function setBackground() - { - imagefilledrectangle($this->im, 0, 0, $this->image_width * $this->iscale, $this->image_height * $this->iscale, $this->gdbgcolor); + } + + /** + * Set the background of the CAPTCHA image + * + * @access private + * + */ + public function setBackground() + { + imagefilledrectangle($this->im, 0, 0, $this->image_width * $this->iscale, $this->image_height * $this->iscale, $this->gdbgcolor); imagefilledrectangle($this->tmpimg, 0, 0, $this->image_width * $this->iscale, $this->image_height * $this->iscale, $this->gdbgcolor); - - if ($this->bgimg == '') { - if ($this->background_directory != null && is_dir($this->background_directory) && is_readable($this->background_directory)) { - $img = $this->getBackgroundFromDirectory(); - if ($img != false) { - $this->bgimg = $img; - } - } - } - - $dat = @getimagesize($this->bgimg); - if($dat == false) { - return; - } - - switch($dat[2]) { - case 1: $newim = @imagecreatefromgif($this->bgimg); break; - case 2: $newim = @imagecreatefromjpeg($this->bgimg); break; - case 3: $newim = @imagecreatefrompng($this->bgimg); break; - case 15: $newim = @imagecreatefromwbmp($this->bgimg); break; - case 16: $newim = @imagecreatefromxbm($this->bgimg); break; - default: return; - } - - if(!$newim) return; - - imagecopyresized($this->im, $newim, 0, 0, 0, 0, $this->image_width, $this->image_height, imagesx($newim), imagesy($newim)); - } - - /** - * Return the full path to a random gif, jpg, or png from the background directory. - * - * @access private - * @see Securimage::$background_directory - * @return mixed false if none found, string $path if found - */ - function getBackgroundFromDirectory() - { - $images = array(); - - if ($dh = opendir($this->background_directory)) { - while (($file = readdir($dh)) !== false) { - if (preg_match('/(jpg|gif|png)$/i', $file)) $images[] = $file; - } - - closedir($dh); - - if (sizeof($images) > 0) { - return rtrim($this->background_directory, '/') . '/' . $images[rand(0, sizeof($images)-1)]; - } - } - - return false; - } - - /** - * Draw random curvy lines over the image
    - * Modified code from HKCaptcha - * - * @since 2.0 - * @access private - * - */ - function drawLines() - { - for ($line = 0; $line < $this->num_lines; ++$line) { - $x = $this->image_width * (1 + $line) / ($this->num_lines + 1); - $x += (0.5 - $this->frand()) * $this->image_width / $this->num_lines; - $y = rand($this->image_height * 0.1, $this->image_height * 0.9); - - $theta = ($this->frand()-0.5) * M_PI * 0.7; - $w = $this->image_width; - $len = rand($w * 0.4, $w * 0.7); - $lwid = rand(0, 2); - - $k = $this->frand() * 0.6 + 0.2; - $k = $k * $k * 0.5; - $phi = $this->frand() * 6.28; - $step = 0.5; - $dx = $step * cos($theta); - $dy = $step * sin($theta); - $n = $len / $step; - $amp = 1.5 * $this->frand() / ($k + 5.0 / $len); - $x0 = $x - 0.5 * $len * cos($theta); - $y0 = $y - 0.5 * $len * sin($theta); - - $ldx = round(-$dy * $lwid); - $ldy = round($dx * $lwid); - - for ($i = 0; $i < $n; ++$i) { - $x = $x0 + $i * $dx + $amp * $dy * sin($k * $i * $step + $phi); - $y = $y0 + $i * $dy - $amp * $dx * sin($k * $i * $step + $phi); - imagefilledrectangle($this->im, $x, $y, $x + $lwid, $y + $lwid, $this->gdlinecolor); - } - } - } - - /** - * Draw the CAPTCHA code over the image - * - * @access private - * - */ - function drawWord() - { - $width2 = $this->image_width * $this->iscale; - $height2 = $this->image_height * $this->iscale; - - if ($this->use_gd_font == true || !is_readable($this->ttf_file)) { - if (!is_int($this->gd_font_file)) { //is a file name - $font = @imageloadfont($this->gd_font_file); - if ($font == false) { - trigger_error("Failed to load GD Font file {$this->gd_font_file} ", E_USER_WARNING); - return; - } - } else { //gd font identifier - $font = $this->gd_font_file; - } - - imagestring($this->im, $font, $this->text_x_start, ($this->image_height / 2) - ($this->gd_font_size / 2), $this->code, $this->gdtextcolor); - } else { //ttf font - $font_size = $height2 * .35; - $bb = imagettfbbox($font_size, 0, $this->ttf_file, $this->code); - $tx = $bb[4] - $bb[0]; - $ty = $bb[5] - $bb[1]; - $x = floor($width2 / 2 - $tx / 2 - $bb[0]); - $y = round($height2 / 2 - $ty / 2 - $bb[1]); - - $strlen = strlen($this->code); - if (!is_array($this->multi_text_color)) $this->use_multi_text = false; - - - if ($this->use_multi_text == false && $this->text_angle_minimum == 0 && $this->text_angle_maximum == 0) { // no angled or multi-color characters - imagettftext($this->tmpimg, $font_size, 0, $x, $y, $this->gdtextcolor, $this->ttf_file, $this->code); - } else { - for($i = 0; $i < $strlen; ++$i) { - $angle = rand($this->text_angle_minimum, $this->text_angle_maximum); - $y = rand($y - 5, $y + 5); - if ($this->use_multi_text == true) { - $font_color = $this->gdmulticolor[rand(0, sizeof($this->gdmulticolor) - 1)]; - } else { - $font_color = $this->gdtextcolor; - } - - $ch = $this->code{$i}; - - imagettftext($this->tmpimg, $font_size, $angle, $x, $y, $font_color, $this->ttf_file, $ch); - - // estimate character widths to increment $x without creating spaces that are too large or too small - // these are best estimates to align text but may vary between fonts - // for optimal character widths, do not use multiple text colors or character angles and the complete string will be written by imagettftext - if (strpos('abcdeghknopqsuvxyz', $ch) !== false) { - $min_x = $font_size - ($this->iscale * 6); - $max_x = $font_size - ($this->iscale * 6); - } else if (strpos('ilI1', $ch) !== false) { - $min_x = $font_size / 5; - $max_x = $font_size / 3; - } else if (strpos('fjrt', $ch) !== false) { - $min_x = $font_size - ($this->iscale * 12); - $max_x = $font_size - ($this->iscale * 12); - } else if ($ch == 'wm') { - $min_x = $font_size; - $max_x = $font_size + ($this->iscale * 3); - } else { // numbers, capitals or unicode - $min_x = $font_size + ($this->iscale * 2); - $max_x = $font_size + ($this->iscale * 5); - } - - $x += rand($min_x, $max_x); - } //for loop - } // angled or multi-color - } //else ttf font - //$this->im = $this->tmpimg; - //$this->output(); - } //function - - /** - * Warp text from temporary image onto final image.
    - * Modified for securimage - * - * @access private - * @since 2.0 - * @author Han-Kwang Nienhuys modified - * @copyright Han-Kwang Neinhuys - * - */ - function distortedCopy() - { - $numpoles = 3; // distortion factor - - // make array of poles AKA attractor points - for ($i = 0; $i < $numpoles; ++$i) { - $px[$i] = rand($this->image_width * 0.3, $this->image_width * 0.7); - $py[$i] = rand($this->image_height * 0.3, $this->image_height * 0.7); - $rad[$i] = rand($this->image_width * 0.4, $this->image_width * 0.7); - $tmp = -$this->frand() * 0.15 - 0.15; - $amp[$i] = $this->perturbation * $tmp; - } - - $bgCol = imagecolorat($this->tmpimg, 0, 0); - $width2 = $this->iscale * $this->image_width; - $height2 = $this->iscale * $this->image_height; - - imagepalettecopy($this->im, $this->tmpimg); // copy palette to final image so text colors come across - - // loop over $img pixels, take pixels from $tmpimg with distortion field - for ($ix = 0; $ix < $this->image_width; ++$ix) { - for ($iy = 0; $iy < $this->image_height; ++$iy) { - $x = $ix; - $y = $iy; - - for ($i = 0; $i < $numpoles; ++$i) { - $dx = $ix - $px[$i]; - $dy = $iy - $py[$i]; - if ($dx == 0 && $dy == 0) continue; - - $r = sqrt($dx * $dx + $dy * $dy); - if ($r > $rad[$i]) continue; - - $rscale = $amp[$i] * sin(3.14 * $r / $rad[$i]); - $x += $dx * $rscale; - $y += $dy * $rscale; - } - - $c = $bgCol; - $x *= $this->iscale; - $y *= $this->iscale; - - if ($x >= 0 && $x < $width2 && $y >= 0 && $y < $height2) { - $c = imagecolorat($this->tmpimg, $x, $y); - } - - if ($c != $bgCol) { // only copy pixels of letters to preserve any background image - imagesetpixel($this->im, $ix, $iy, $c); - } - } - } - } - - /** - * Create a code and save to the session - * - * @access private - * @since 1.0.1 - * - */ - function createCode() - { - $this->code = false; - - if ($this->use_wordlist && is_readable($this->wordlist_file)) { - $this->code = $this->readCodeFromFile(); - } - - if ($this->code == false) { - $this->code = $this->generateCode($this->code_length); - } - - $this->saveData(); - } - - /** - * Generate a code - * - * @access private - * @param int $len The code length - * @return string - */ - function generateCode($len) - { - $code = ''; - - for($i = 1, $cslen = strlen($this->charset); $i <= $len; ++$i) { - $code .= $this->charset{rand(0, $cslen - 1)}; - } - return $code; - } - - /** - * Reads a word list file to get a code - * - * @access private - * @since 1.0.2 - * @return mixed false on failure, a word on success - */ - function readCodeFromFile() - { - $fp = @fopen($this->wordlist_file, 'rb'); - if (!$fp) return false; - - $fsize = filesize($this->wordlist_file); - if ($fsize < 32) return false; // too small of a list to be effective - - if ($fsize < 128) { - $max = $fsize; // still pretty small but changes the range of seeking - } else { - $max = 128; - } - - fseek($fp, rand(0, $fsize - $max), SEEK_SET); - $data = fread($fp, 128); // read a random 128 bytes from file - fclose($fp); - $data = preg_replace("/\r?\n/", "\n", $data); - - $start = strpos($data, "\n", rand(0, 100)) + 1; // random start position - $end = strpos($data, "\n", $start); // find end of word - - return strtolower(substr($data, $start, $end - $start)); // return substring in 128 bytes - } - - /** - * Output image to the browser - * - * @access private - * - */ - function output() - { - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - - switch($this->image_type) - { - case SI_IMAGE_JPEG: - header("Content-Type: image/jpeg"); - imagejpeg($this->im, null, 90); - break; - - case SI_IMAGE_GIF: - header("Content-Type: image/gif"); - imagegif($this->im); - break; - - default: - header("Content-Type: image/png"); - imagepng($this->im); - break; - } - - imagedestroy($this->im); - exit; - } - - /** - * Get WAV or MP3 file data of the spoken code.
    - * This is appropriate for output to the browser as audio/x-wav or audio/mpeg - * - * @since 1.0.1 - * @return string WAV or MP3 data - * - */ - function getAudibleCode($format = 'wav') - { - $letters = array(); - $code = $this->getCode(); - - if ($code == '') { - $this->createCode(); - $code = $this->getCode(); - } - - for($i = 0; $i < strlen($code); ++$i) { - $letters[] = $code{$i}; - } - - if ($format == 'mp3') { - return $this->generateMP3($letters); - } else { - return $this->generateWAV($letters); - } - } - - /** - * Set the path to the audio directory.
    - * - * @since 1.0.4 - * @return bool true if the directory exists and is readble, false if not - */ - function setAudioPath($audio_directory) - { - if (is_dir($audio_directory) && is_readable($audio_directory)) { - $this->audio_path = $audio_directory; - return true; - } else { - return false; - } - } - - /** - * Save the code in the session - * - * @access private - * - */ - function saveData() - { - $_SESSION['securimage_code_value'] = strtolower($this->code); - $_SESSION['securimage_code_ctime'] = time(); - - $this->saveCodeToDatabase(); - } - - /** - * Validate the code to the user code - * - * @access private - * - */ - function validate() - { - // retrieve code from session, if no code exists check sqlite database if supported. - - if (isset($_SESSION['securimage_code_value']) && trim($_SESSION['securimage_code_value']) != '') { - if ($this->isCodeExpired($_SESSION['securimage_code_ctime']) == false) { - $code = $_SESSION['securimage_code_value']; - } - } else if ($this->use_sqlite_db == true && function_exists('sqlite_open')) { // no code in session - may mean user has cookies turned off - $this->openDatabase(); - $code = $this->getCodeFromDatabase(); - } else { - // session code invalid or non-existant and code not found in sqlite db or sqlite is not available - $code = ''; - } - - $code = trim(strtolower($code)); - $code_entered = trim(strtolower($this->code_entered)); - $this->correct_code = false; - - if ($code != '') { - if ($code == $code_entered) { - $this->correct_code = true; - $_SESSION['securimage_code_value'] = ''; - $_SESSION['securimage_code_ctime'] = ''; - $this->clearCodeFromDatabase(); - } - } - } - - /** - * Get the captcha code - * - * @since 1.0.1 - * @return string - */ - function getCode() - { - if (isset($_SESSION['securimage_code_value']) && !empty($_SESSION['securimage_code_value'])) { - return strtolower($_SESSION['securimage_code_value']); - } else { - if ($this->sqlite_handle == false) $this->openDatabase(); - - return $this->getCodeFromDatabase(); // attempt to get from database, returns empty string if sqlite is not available or disabled - } - } - - /** - * Check if the user entered code was correct - * - * @access private - * @return boolean - */ - function checkCode() - { - return $this->correct_code; - } - - /** - * Generate a wav file by concatenating individual files - * - * @since 1.0.1 - * @access private - * @param array $letters Array of letters to build a file from - * @return string WAV file data - */ - function generateWAV($letters) - { - $data_len = 0; - $files = array(); - $out_data = ''; - - foreach ($letters as $letter) { - $filename = $this->audio_path . strtoupper($letter) . '.wav'; - - $fp = fopen($filename, 'rb'); - - $file = array(); - - $data = fread($fp, filesize($filename)); // read file in - - $header = substr($data, 0, 36); - $body = substr($data, 44); - - - $data = unpack('NChunkID/VChunkSize/NFormat/NSubChunk1ID/VSubChunk1Size/vAudioFormat/vNumChannels/VSampleRate/VByteRate/vBlockAlign/vBitsPerSample', $header); - - $file['sub_chunk1_id'] = $data['SubChunk1ID']; - $file['bits_per_sample'] = $data['BitsPerSample']; - $file['channels'] = $data['NumChannels']; - $file['format'] = $data['AudioFormat']; - $file['sample_rate'] = $data['SampleRate']; - $file['size'] = $data['ChunkSize'] + 8; - $file['data'] = $body; - - if ( ($p = strpos($file['data'], 'LIST')) !== false) { - // If the LIST data is not at the end of the file, this will probably break your sound file - $info = substr($file['data'], $p + 4, 8); - $data = unpack('Vlength/Vjunk', $info); - $file['data'] = substr($file['data'], 0, $p); - $file['size'] = $file['size'] - (strlen($file['data']) - $p); - } - - $files[] = $file; - $data = null; - $header = null; - $body = null; - - $data_len += strlen($file['data']); - - fclose($fp); - } - - $out_data = ''; - for($i = 0; $i < sizeof($files); ++$i) { - if ($i == 0) { // output header - $out_data .= pack('C4VC8', ord('R'), ord('I'), ord('F'), ord('F'), $data_len + 36, ord('W'), ord('A'), ord('V'), ord('E'), ord('f'), ord('m'), ord('t'), ord(' ')); - - $out_data .= pack('VvvVVvv', - 16, - $files[$i]['format'], - $files[$i]['channels'], - $files[$i]['sample_rate'], - $files[$i]['sample_rate'] * (($files[$i]['bits_per_sample'] * $files[$i]['channels']) / 8), - ($files[$i]['bits_per_sample'] * $files[$i]['channels']) / 8, - $files[$i]['bits_per_sample'] ); - - $out_data .= pack('C4', ord('d'), ord('a'), ord('t'), ord('a')); - - $out_data .= pack('V', $data_len); - } - - $out_data .= $files[$i]['data']; - } - - $this->scrambleAudioData($out_data, 'wav'); - return $out_data; - } - - /** - * Randomly modify the audio data to scramble sound and prevent binary recognition.
    - * Take care not to "break" the audio file by leaving the header data intact. - * - * @since 2.0 - * @access private - * @param $data Sound data in mp3 of wav format - */ - function scrambleAudioData(&$data, $format) - { - if ($format == 'wav') { - $start = strpos($data, 'data') + 4; // look for "data" indicator - if ($start === false) $start = 44; // if not found assume 44 byte header - } else { // mp3 - $start = 4; // 4 byte (32 bit) frame header - } - - $start += rand(1, 64); // randomize starting offset - $datalen = strlen($data) - $start - 256; // leave last 256 bytes unchanged - - for ($i = $start; $i < $datalen; $i += 64) { - $ch = ord($data{$i}); - if ($ch < 9 || $ch > 119) continue; - - $data{$i} = chr($ch + rand(-8, 8)); - } - } - - /** - * Generate an mp3 file by concatenating individual files - * @since 1.0.4 - * @access private - * @param array $letters Array of letters to build a file from - * @return string MP3 file data - */ - function generateMP3($letters) - { - $data_len = 0; - $files = array(); - $out_data = ''; - - foreach ($letters as $letter) { - $filename = $this->audio_path . strtoupper($letter) . '.mp3'; - - $fp = fopen($filename, 'rb'); - $data = fread($fp, filesize($filename)); // read file in - - $this->scrambleAudioData($data, 'mp3'); - $out_data .= $data; - - fclose($fp); - } - - - return $out_data; - } - - /** - * Generate random number less than 1 - * @since 2.0 - * @access private - * @return float - */ - function frand() - { - return 0.0001*rand(0,9999); - } - - /** - * Print signature text on image - * - * @since 2.0 - * @access private - * - */ - function addSignature() - { - if ($this->use_gd_font) { - imagestring($this->im, 5, $this->image_width - (strlen($this->image_signature) * 10), $this->image_height - 20, $this->image_signature, $this->gdsignaturecolor); - } else { - - $bbox = imagettfbbox(10, 0, $this->signature_font, $this->image_signature); - $textlen = $bbox[2] - $bbox[0]; - $x = $this->image_width - $textlen - 5; - $y = $this->image_height - 3; - - imagettftext($this->im, 10, 0, $x, $y, $this->gdsignaturecolor, $this->signature_font, $this->image_signature); - } - } - - /** - * Get hashed IP address of remote user - * - * @access private - * @since 2.0.1 - * @return string - */ - function getIPHash() - { - return strtolower(md5($_SERVER['REMOTE_ADDR'])); - } - - /** - * Open SQLite database - * - * @access private - * @since 2.0.1 - * @return bool true if database was opened successfully - */ - function openDatabase() - { - $this->sqlite_handle = false; - - if ($this->use_sqlite_db && function_exists('sqlite_open')) { - $this->sqlite_handle = sqlite_open($this->sqlite_database, 0666, $error); - - if ($this->sqlite_handle !== false) { - $res = sqlite_query($this->sqlite_handle, "PRAGMA table_info(codes)"); - if (sqlite_num_rows($res) == 0) { - sqlite_query($this->sqlite_handle, "CREATE TABLE codes (iphash VARCHAR(32) PRIMARY KEY, code VARCHAR(32) NOT NULL, created INTEGER)"); - } - } - - return $this->sqlite_handle != false; - } - - return $this->sqlite_handle; - } - - /** - * Save captcha code to sqlite database - * - * @access private - * @since 2.0.1 - * @return bool true if code was saved, false if not - */ - function saveCodeToDatabase() - { - $success = false; - - $this->openDatabase(); - - if ($this->use_sqlite_db && $this->sqlite_handle !== false) { - $ip = $this->getIPHash(); - $time = time(); - $code = $_SESSION['securimage_code_value']; // hash code for security - if cookies are disabled the session still exists at this point - $success = sqlite_query($this->sqlite_handle, "INSERT OR REPLACE INTO codes(iphash, code, created) VALUES('$ip', '$code', $time)"); - } - - return $success !== false; - } - - /** - * Get stored captcha code from sqlite database based on ip address hash - * - * @access private - * @since 2.0.1 - * @return string captcha code - */ - function getCodeFromDatabase() - { + + if ($this->bgimg == '') { + if ($this->background_directory != null && is_dir($this->background_directory) && is_readable($this->background_directory)) { + $img = $this->getBackgroundFromDirectory(); + if ($img != false) { + $this->bgimg = $img; + } + } + } + + $dat = @getimagesize($this->bgimg); + if ($dat == false) { + return; + } + + switch ($dat[2]) { + case 1: $newim = @imagecreatefromgif($this->bgimg); break; + case 2: $newim = @imagecreatefromjpeg($this->bgimg); break; + case 3: $newim = @imagecreatefrompng($this->bgimg); break; + case 15: $newim = @imagecreatefromwbmp($this->bgimg); break; + case 16: $newim = @imagecreatefromxbm($this->bgimg); break; + default: return; + } + + if(!$newim) return; + + imagecopyresized($this->im, $newim, 0, 0, 0, 0, $this->image_width, $this->image_height, imagesx($newim), imagesy($newim)); + } + + /** + * Return the full path to a random gif, jpg, or png from the background directory. + * + * @access private + * @see Securimage::$background_directory + * @return mixed false if none found, string $path if found + */ + public function getBackgroundFromDirectory() + { + $images = array(); + + if ($dh = opendir($this->background_directory)) { + while (($file = readdir($dh)) !== false) { + if (preg_match('/(jpg|gif|png)$/i', $file)) $images[] = $file; + } + + closedir($dh); + + if (sizeof($images) > 0) { + return rtrim($this->background_directory, '/') . '/' . $images[rand(0, sizeof($images)-1)]; + } + } + + return false; + } + + /** + * Draw random curvy lines over the image
    + * Modified code from HKCaptcha + * + * @since 2.0 + * @access private + * + */ + public function drawLines() + { + for ($line = 0; $line < $this->num_lines; ++$line) { + $x = $this->image_width * (1 + $line) / ($this->num_lines + 1); + $x += (0.5 - $this->frand()) * $this->image_width / $this->num_lines; + $y = rand($this->image_height * 0.1, $this->image_height * 0.9); + + $theta = ($this->frand()-0.5) * M_PI * 0.7; + $w = $this->image_width; + $len = rand($w * 0.4, $w * 0.7); + $lwid = rand(0, 2); + + $k = $this->frand() * 0.6 + 0.2; + $k = $k * $k * 0.5; + $phi = $this->frand() * 6.28; + $step = 0.5; + $dx = $step * cos($theta); + $dy = $step * sin($theta); + $n = $len / $step; + $amp = 1.5 * $this->frand() / ($k + 5.0 / $len); + $x0 = $x - 0.5 * $len * cos($theta); + $y0 = $y - 0.5 * $len * sin($theta); + + $ldx = round(-$dy * $lwid); + $ldy = round($dx * $lwid); + + for ($i = 0; $i < $n; ++$i) { + $x = $x0 + $i * $dx + $amp * $dy * sin($k * $i * $step + $phi); + $y = $y0 + $i * $dy - $amp * $dx * sin($k * $i * $step + $phi); + imagefilledrectangle($this->im, $x, $y, $x + $lwid, $y + $lwid, $this->gdlinecolor); + } + } + } + + /** + * Draw the CAPTCHA code over the image + * + * @access private + * + */ + public function drawWord() + { + $width2 = $this->image_width * $this->iscale; + $height2 = $this->image_height * $this->iscale; + + if ($this->use_gd_font == true || !is_readable($this->ttf_file)) { + if (!is_int($this->gd_font_file)) { //is a file name + $font = @imageloadfont($this->gd_font_file); + if ($font == false) { + trigger_error("Failed to load GD Font file {$this->gd_font_file} ", E_USER_WARNING); + return; + } + } else { //gd font identifier + $font = $this->gd_font_file; + } + + imagestring($this->im, $font, $this->text_x_start, ($this->image_height / 2) - ($this->gd_font_size / 2), $this->code, $this->gdtextcolor); + } else { //ttf font + $font_size = $height2 * .35; + $bb = imagettfbbox($font_size, 0, $this->ttf_file, $this->code); + $tx = $bb[4] - $bb[0]; + $ty = $bb[5] - $bb[1]; + $x = floor($width2 / 2 - $tx / 2 - $bb[0]); + $y = round($height2 / 2 - $ty / 2 - $bb[1]); + + $strlen = strlen($this->code); + if (!is_array($this->multi_text_color)) $this->use_multi_text = false; + + + if ($this->use_multi_text == false && $this->text_angle_minimum == 0 && $this->text_angle_maximum == 0) { // no angled or multi-color characters + imagettftext($this->tmpimg, $font_size, 0, $x, $y, $this->gdtextcolor, $this->ttf_file, $this->code); + } else { + for ($i = 0; $i < $strlen; ++$i) { + $angle = rand($this->text_angle_minimum, $this->text_angle_maximum); + $y = rand($y - 5, $y + 5); + if ($this->use_multi_text == true) { + $font_color = $this->gdmulticolor[rand(0, sizeof($this->gdmulticolor) - 1)]; + } else { + $font_color = $this->gdtextcolor; + } + + $ch = $this->code{$i}; + + imagettftext($this->tmpimg, $font_size, $angle, $x, $y, $font_color, $this->ttf_file, $ch); + + // estimate character widths to increment $x without creating spaces that are too large or too small + // these are best estimates to align text but may vary between fonts + // for optimal character widths, do not use multiple text colors or character angles and the complete string will be written by imagettftext + if (strpos('abcdeghknopqsuvxyz', $ch) !== false) { + $min_x = $font_size - ($this->iscale * 6); + $max_x = $font_size - ($this->iscale * 6); + } else if (strpos('ilI1', $ch) !== false) { + $min_x = $font_size / 5; + $max_x = $font_size / 3; + } else if (strpos('fjrt', $ch) !== false) { + $min_x = $font_size - ($this->iscale * 12); + $max_x = $font_size - ($this->iscale * 12); + } else if ($ch == 'wm') { + $min_x = $font_size; + $max_x = $font_size + ($this->iscale * 3); + } else { // numbers, capitals or unicode + $min_x = $font_size + ($this->iscale * 2); + $max_x = $font_size + ($this->iscale * 5); + } + + $x += rand($min_x, $max_x); + } //for loop + } // angled or multi-color + } //else ttf font + //$this->im = $this->tmpimg; + //$this->output(); + } //function + + /** + * Warp text from temporary image onto final image.
    + * Modified for securimage + * + * @access private + * @since 2.0 + * @author Han-Kwang Nienhuys modified + * @copyright Han-Kwang Neinhuys + * + */ + public function distortedCopy() + { + $numpoles = 3; // distortion factor + + // make array of poles AKA attractor points + for ($i = 0; $i < $numpoles; ++$i) { + $px[$i] = rand($this->image_width * 0.3, $this->image_width * 0.7); + $py[$i] = rand($this->image_height * 0.3, $this->image_height * 0.7); + $rad[$i] = rand($this->image_width * 0.4, $this->image_width * 0.7); + $tmp = -$this->frand() * 0.15 - 0.15; + $amp[$i] = $this->perturbation * $tmp; + } + + $bgCol = imagecolorat($this->tmpimg, 0, 0); + $width2 = $this->iscale * $this->image_width; + $height2 = $this->iscale * $this->image_height; + + imagepalettecopy($this->im, $this->tmpimg); // copy palette to final image so text colors come across + + // loop over $img pixels, take pixels from $tmpimg with distortion field + for ($ix = 0; $ix < $this->image_width; ++$ix) { + for ($iy = 0; $iy < $this->image_height; ++$iy) { + $x = $ix; + $y = $iy; + + for ($i = 0; $i < $numpoles; ++$i) { + $dx = $ix - $px[$i]; + $dy = $iy - $py[$i]; + if ($dx == 0 && $dy == 0) continue; + + $r = sqrt($dx * $dx + $dy * $dy); + if ($r > $rad[$i]) continue; + + $rscale = $amp[$i] * sin(3.14 * $r / $rad[$i]); + $x += $dx * $rscale; + $y += $dy * $rscale; + } + + $c = $bgCol; + $x *= $this->iscale; + $y *= $this->iscale; + + if ($x >= 0 && $x < $width2 && $y >= 0 && $y < $height2) { + $c = imagecolorat($this->tmpimg, $x, $y); + } + + if ($c != $bgCol) { // only copy pixels of letters to preserve any background image + imagesetpixel($this->im, $ix, $iy, $c); + } + } + } + } + + /** + * Create a code and save to the session + * + * @access private + * @since 1.0.1 + * + */ + public function createCode() + { + $this->code = false; + + if ($this->use_wordlist && is_readable($this->wordlist_file)) { + $this->code = $this->readCodeFromFile(); + } + + if ($this->code == false) { + $this->code = $this->generateCode($this->code_length); + } + + $this->saveData(); + } + + /** + * Generate a code + * + * @access private + * @param int $len The code length + * @return string + */ + public function generateCode($len) + { + $code = ''; + + for ($i = 1, $cslen = strlen($this->charset); $i <= $len; ++$i) { + $code .= $this->charset{rand(0, $cslen - 1)}; + } + return $code; + } + + /** + * Reads a word list file to get a code + * + * @access private + * @since 1.0.2 + * @return mixed false on failure, a word on success + */ + public function readCodeFromFile() + { + $fp = @fopen($this->wordlist_file, 'rb'); + if (!$fp) return false; + + $fsize = filesize($this->wordlist_file); + if ($fsize < 32) return false; // too small of a list to be effective + + if ($fsize < 128) { + $max = $fsize; // still pretty small but changes the range of seeking + } else { + $max = 128; + } + + fseek($fp, rand(0, $fsize - $max), SEEK_SET); + $data = fread($fp, 128); // read a random 128 bytes from file + fclose($fp); + $data = preg_replace("/\r?\n/", "\n", $data); + + $start = strpos($data, "\n", rand(0, 100)) + 1; // random start position + $end = strpos($data, "\n", $start); // find end of word + + return strtolower(substr($data, $start, $end - $start)); // return substring in 128 bytes + } + + /** + * Output image to the browser + * + * @access private + * + */ + public function output() + { + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . "GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + + switch ($this->image_type) { + case SI_IMAGE_JPEG: + header("Content-Type: image/jpeg"); + imagejpeg($this->im, null, 90); + break; + + case SI_IMAGE_GIF: + header("Content-Type: image/gif"); + imagegif($this->im); + break; + + default: + header("Content-Type: image/png"); + imagepng($this->im); + break; + } + + imagedestroy($this->im); + exit; + } + + /** + * Get WAV or MP3 file data of the spoken code.
    + * This is appropriate for output to the browser as audio/x-wav or audio/mpeg + * + * @since 1.0.1 + * @return string WAV or MP3 data + * + */ + public function getAudibleCode($format = 'wav') + { + $letters = array(); + $code = $this->getCode(); + + if ($code == '') { + $this->createCode(); + $code = $this->getCode(); + } + + for ($i = 0; $i < strlen($code); ++$i) { + $letters[] = $code{$i}; + } + + if ($format == 'mp3') { + return $this->generateMP3($letters); + } else { + return $this->generateWAV($letters); + } + } + + /** + * Set the path to the audio directory.
    + * + * @since 1.0.4 + * @return bool true if the directory exists and is readble, false if not + */ + public function setAudioPath($audio_directory) + { + if (is_dir($audio_directory) && is_readable($audio_directory)) { + $this->audio_path = $audio_directory; + return true; + } else { + return false; + } + } + + /** + * Save the code in the session + * + * @access private + * + */ + public function saveData() + { + $_SESSION['securimage_code_value'] = strtolower($this->code); + $_SESSION['securimage_code_ctime'] = time(); + + $this->saveCodeToDatabase(); + } + + /** + * Validate the code to the user code + * + * @access private + * + */ + public function validate() + { + // retrieve code from session, if no code exists check sqlite database if supported. + + if (isset($_SESSION['securimage_code_value']) && trim($_SESSION['securimage_code_value']) != '') { + if ($this->isCodeExpired($_SESSION['securimage_code_ctime']) == false) { + $code = $_SESSION['securimage_code_value']; + } + } else if ($this->use_sqlite_db == true && function_exists('sqlite_open')) { // no code in session - may mean user has cookies turned off + $this->openDatabase(); + $code = $this->getCodeFromDatabase(); + } else { + // session code invalid or non-existant and code not found in sqlite db or sqlite is not available + $code = ''; + } + + $code = trim(strtolower($code)); + $code_entered = trim(strtolower($this->code_entered)); + $this->correct_code = false; + + if ($code != '') { + if ($code == $code_entered) { + $this->correct_code = true; + $_SESSION['securimage_code_value'] = ''; + $_SESSION['securimage_code_ctime'] = ''; + $this->clearCodeFromDatabase(); + } + } + } + + /** + * Get the captcha code + * + * @since 1.0.1 + * @return string + */ + public function getCode() + { + if (isset($_SESSION['securimage_code_value']) && !empty($_SESSION['securimage_code_value'])) { + return strtolower($_SESSION['securimage_code_value']); + } else { + if ($this->sqlite_handle == false) $this->openDatabase(); + + return $this->getCodeFromDatabase(); // attempt to get from database, returns empty string if sqlite is not available or disabled + } + } + + /** + * Check if the user entered code was correct + * + * @access private + * @return boolean + */ + public function checkCode() + { + return $this->correct_code; + } + + /** + * Generate a wav file by concatenating individual files + * + * @since 1.0.1 + * @access private + * @param array $letters Array of letters to build a file from + * @return string WAV file data + */ + public function generateWAV($letters) + { + $data_len = 0; + $files = array(); + $out_data = ''; + + foreach ($letters as $letter) { + $filename = $this->audio_path . strtoupper($letter) . '.wav'; + + $fp = fopen($filename, 'rb'); + + $file = array(); + + $data = fread($fp, filesize($filename)); // read file in + + $header = substr($data, 0, 36); + $body = substr($data, 44); + + + $data = unpack('NChunkID/VChunkSize/NFormat/NSubChunk1ID/VSubChunk1Size/vAudioFormat/vNumChannels/VSampleRate/VByteRate/vBlockAlign/vBitsPerSample', $header); + + $file['sub_chunk1_id'] = $data['SubChunk1ID']; + $file['bits_per_sample'] = $data['BitsPerSample']; + $file['channels'] = $data['NumChannels']; + $file['format'] = $data['AudioFormat']; + $file['sample_rate'] = $data['SampleRate']; + $file['size'] = $data['ChunkSize'] + 8; + $file['data'] = $body; + + if ( ($p = strpos($file['data'], 'LIST')) !== false) { + // If the LIST data is not at the end of the file, this will probably break your sound file + $info = substr($file['data'], $p + 4, 8); + $data = unpack('Vlength/Vjunk', $info); + $file['data'] = substr($file['data'], 0, $p); + $file['size'] = $file['size'] - (strlen($file['data']) - $p); + } + + $files[] = $file; + $data = null; + $header = null; + $body = null; + + $data_len += strlen($file['data']); + + fclose($fp); + } + + $out_data = ''; + for ($i = 0; $i < sizeof($files); ++$i) { + if ($i == 0) { // output header + $out_data .= pack('C4VC8', ord('R'), ord('I'), ord('F'), ord('F'), $data_len + 36, ord('W'), ord('A'), ord('V'), ord('E'), ord('f'), ord('m'), ord('t'), ord(' ')); + + $out_data .= pack('VvvVVvv', + 16, + $files[$i]['format'], + $files[$i]['channels'], + $files[$i]['sample_rate'], + $files[$i]['sample_rate'] * (($files[$i]['bits_per_sample'] * $files[$i]['channels']) / 8), + ($files[$i]['bits_per_sample'] * $files[$i]['channels']) / 8, + $files[$i]['bits_per_sample'] ); + + $out_data .= pack('C4', ord('d'), ord('a'), ord('t'), ord('a')); + + $out_data .= pack('V', $data_len); + } + + $out_data .= $files[$i]['data']; + } + + $this->scrambleAudioData($out_data, 'wav'); + return $out_data; + } + + /** + * Randomly modify the audio data to scramble sound and prevent binary recognition.
    + * Take care not to "break" the audio file by leaving the header data intact. + * + * @since 2.0 + * @access private + * @param $data Sound data in mp3 of wav format + */ + public function scrambleAudioData(&$data, $format) + { + if ($format == 'wav') { + $start = strpos($data, 'data') + 4; // look for "data" indicator + if ($start === false) $start = 44; // if not found assume 44 byte header + } else { // mp3 + $start = 4; // 4 byte (32 bit) frame header + } + + $start += rand(1, 64); // randomize starting offset + $datalen = strlen($data) - $start - 256; // leave last 256 bytes unchanged + + for ($i = $start; $i < $datalen; $i += 64) { + $ch = ord($data{$i}); + if ($ch < 9 || $ch > 119) continue; + + $data{$i} = chr($ch + rand(-8, 8)); + } + } + + /** + * Generate an mp3 file by concatenating individual files + * @since 1.0.4 + * @access private + * @param array $letters Array of letters to build a file from + * @return string MP3 file data + */ + public function generateMP3($letters) + { + $data_len = 0; + $files = array(); + $out_data = ''; + + foreach ($letters as $letter) { + $filename = $this->audio_path . strtoupper($letter) . '.mp3'; + + $fp = fopen($filename, 'rb'); + $data = fread($fp, filesize($filename)); // read file in + + $this->scrambleAudioData($data, 'mp3'); + $out_data .= $data; + + fclose($fp); + } + + + return $out_data; + } + + /** + * Generate random number less than 1 + * @since 2.0 + * @access private + * @return float + */ + public function frand() + { + return 0.0001*rand(0,9999); + } + + /** + * Print signature text on image + * + * @since 2.0 + * @access private + * + */ + public function addSignature() + { + if ($this->use_gd_font) { + imagestring($this->im, 5, $this->image_width - (strlen($this->image_signature) * 10), $this->image_height - 20, $this->image_signature, $this->gdsignaturecolor); + } else { + + $bbox = imagettfbbox(10, 0, $this->signature_font, $this->image_signature); + $textlen = $bbox[2] - $bbox[0]; + $x = $this->image_width - $textlen - 5; + $y = $this->image_height - 3; + + imagettftext($this->im, 10, 0, $x, $y, $this->gdsignaturecolor, $this->signature_font, $this->image_signature); + } + } + + /** + * Get hashed IP address of remote user + * + * @access private + * @since 2.0.1 + * @return string + */ + public function getIPHash() + { + return strtolower(md5($_SERVER['REMOTE_ADDR'])); + } + + /** + * Open SQLite database + * + * @access private + * @since 2.0.1 + * @return bool true if database was opened successfully + */ + public function openDatabase() + { + $this->sqlite_handle = false; + + if ($this->use_sqlite_db && function_exists('sqlite_open')) { + $this->sqlite_handle = sqlite_open($this->sqlite_database, 0666, $error); + + if ($this->sqlite_handle !== false) { + $res = sqlite_query($this->sqlite_handle, "PRAGMA table_info(codes)"); + if (sqlite_num_rows($res) == 0) { + sqlite_query($this->sqlite_handle, "CREATE TABLE codes (iphash VARCHAR(32) PRIMARY KEY, code VARCHAR(32) NOT NULL, created INTEGER)"); + } + } + + return $this->sqlite_handle != false; + } + + return $this->sqlite_handle; + } + + /** + * Save captcha code to sqlite database + * + * @access private + * @since 2.0.1 + * @return bool true if code was saved, false if not + */ + public function saveCodeToDatabase() + { + $success = false; + + $this->openDatabase(); + + if ($this->use_sqlite_db && $this->sqlite_handle !== false) { + $ip = $this->getIPHash(); + $time = time(); + $code = $_SESSION['securimage_code_value']; // hash code for security - if cookies are disabled the session still exists at this point + $success = sqlite_query($this->sqlite_handle, "INSERT OR REPLACE INTO codes(iphash, code, created) VALUES('$ip', '$code', $time)"); + } + + return $success !== false; + } + + /** + * Get stored captcha code from sqlite database based on ip address hash + * + * @access private + * @since 2.0.1 + * @return string captcha code + */ + public function getCodeFromDatabase() + { $code = ''; if ($this->use_sqlite_db && $this->sqlite_handle !== false) { - $ip = $this->getIPHash(); - - $res = sqlite_query($this->sqlite_handle, "SELECT * FROM codes WHERE iphash = '$ip'"); - if ($res && sqlite_num_rows($res) > 0) { - $res = sqlite_fetch_array($res); - - if ($this->isCodeExpired($res['created']) == false) { - $code = $res['code']; - } - } + $ip = $this->getIPHash(); + + $res = sqlite_query($this->sqlite_handle, "SELECT * FROM codes WHERE iphash = '$ip'"); + if ($res && sqlite_num_rows($res) > 0) { + $res = sqlite_fetch_array($res); + + if ($this->isCodeExpired($res['created']) == false) { + $code = $res['code']; + } + } } - + return $code; - } - - /** - * Delete a code from the database by ip address hash - * - * @access private - * @since 2.0.1 - */ - function clearCodeFromDatabase() - { - if ($this->sqlite_handle !== false) { - $ip = $this->getIPHash(); - - sqlite_query($this->sqlite_handle, "DELETE FROM codes WHERE iphash = '$ip'"); - } - } - - /** - * Purge codes over a day old from database - * - * @access private - * @since 2.0.1 - */ - function purgeOldCodesFromDatabase() - { - if ($this->use_sqlite_db && $this->sqlite_handle !== false) { - $now = time(); - $limit = (!is_numeric($this->expiry_time) || $this->expiry_time < 1) ? 86400 : $this->expiry_time; - - sqlite_query($this->sqlite_handle, "DELETE FROM codes WHERE $now - created > $limit"); - } - } - - /** - * Check a code to see if it is expired based on creation time - * - * @access private - * @since 2.0.1 - * @param $creation_time unix timestamp of code creation time - * @return bool true if code has expired, false if not - */ - function isCodeExpired($creation_time) - { - $expired = true; - - if (!is_numeric($this->expiry_time) || $this->expiry_time < 1) { - $expired = false; - } else if (time() - $creation_time < $this->expiry_time) { - $expired = false; - } - - return $expired; - } - + } + + /** + * Delete a code from the database by ip address hash + * + * @access private + * @since 2.0.1 + */ + public function clearCodeFromDatabase() + { + if ($this->sqlite_handle !== false) { + $ip = $this->getIPHash(); + + sqlite_query($this->sqlite_handle, "DELETE FROM codes WHERE iphash = '$ip'"); + } + } + + /** + * Purge codes over a day old from database + * + * @access private + * @since 2.0.1 + */ + public function purgeOldCodesFromDatabase() + { + if ($this->use_sqlite_db && $this->sqlite_handle !== false) { + $now = time(); + $limit = (!is_numeric($this->expiry_time) || $this->expiry_time < 1) ? 86400 : $this->expiry_time; + + sqlite_query($this->sqlite_handle, "DELETE FROM codes WHERE $now - created > $limit"); + } + } + + /** + * Check a code to see if it is expired based on creation time + * + * @access private + * @since 2.0.1 + * @param $creation_time unix timestamp of code creation time + * @return bool true if code has expired, false if not + */ + public function isCodeExpired($creation_time) + { + $expired = true; + + if (!is_numeric($this->expiry_time) || $this->expiry_time < 1) { + $expired = false; + } else if (time() - $creation_time < $this->expiry_time) { + $expired = false; + } + + return $expired; + } + } /* class Securimage */ @@ -1521,64 +1520,65 @@ function isCodeExpired($creation_time) * @subpackage classes * */ -class Securimage_Color { - /** - * Red component: 0-255 - * - * @var int - */ - var $r; - /** - * Green component: 0-255 - * - * @var int - */ - var $g; - /** - * Blue component: 0-255 - * - * @var int - */ - var $b; - - /** - * Create a new Securimage_Color object.
    - * Specify the red, green, and blue components using their HTML hex code equivalent.
    - * Example: The code for the HTML color #4A203C is:
    - * $color = new Securimage_Color(0x4A, 0x20, 0x3C); - * - * @param $red Red component 0-255 - * @param $green Green component 0-255 - * @param $blue Blue component 0-255 - */ - function Securimage_Color($red, $green = null, $blue = null) - { - if ($green == null && $blue == null && preg_match('/^#[a-f0-9]{3,6}$/i', $red)) { - $col = substr($red, 1); - if (strlen($col) == 3) { - $red = str_repeat(substr($col, 0, 1), 2); - $green = str_repeat(substr($col, 1, 1), 2); - $blue = str_repeat(substr($col, 2, 1), 2); - } else { - $red = substr($col, 0, 2); - $green = substr($col, 2, 2); - $blue = substr($col, 4, 2); - } - - $red = hexdec($red); - $green = hexdec($green); - $blue = hexdec($blue); - } else { - if ($red < 0) $red = 0; - if ($red > 255) $red = 255; - if ($green < 0) $green = 0; - if ($green > 255) $green = 255; - if ($blue < 0) $blue = 0; - if ($blue > 255) $blue = 255; - } - - $this->r = $red; - $this->g = $green; - $this->b = $blue; - } +class Securimage_Color +{ + /** + * Red component: 0-255 + * + * @var int + */ + public $r; + /** + * Green component: 0-255 + * + * @var int + */ + public $g; + /** + * Blue component: 0-255 + * + * @var int + */ + public $b; + + /** + * Create a new Securimage_Color object.
    + * Specify the red, green, and blue components using their HTML hex code equivalent.
    + * Example: The code for the HTML color #4A203C is:
    + * $color = new Securimage_Color(0x4A, 0x20, 0x3C); + * + * @param $red Red component 0-255 + * @param $green Green component 0-255 + * @param $blue Blue component 0-255 + */ + public function Securimage_Color($red, $green = null, $blue = null) + { + if ($green == null && $blue == null && preg_match('/^#[a-f0-9]{3,6}$/i', $red)) { + $col = substr($red, 1); + if (strlen($col) == 3) { + $red = str_repeat(substr($col, 0, 1), 2); + $green = str_repeat(substr($col, 1, 1), 2); + $blue = str_repeat(substr($col, 2, 1), 2); + } else { + $red = substr($col, 0, 2); + $green = substr($col, 2, 2); + $blue = substr($col, 4, 2); + } + + $red = hexdec($red); + $green = hexdec($green); + $blue = hexdec($blue); + } else { + if ($red < 0) $red = 0; + if ($red > 255) $red = 255; + if ($green < 0) $green = 0; + if ($green > 255) $green = 255; + if ($blue < 0) $blue = 0; + if ($blue > 255) $blue = 255; + } + + $this->r = $red; + $this->g = $green; + $this->b = $blue; + } } diff --git a/core/src/core/tests/test.AJXPVersion.php b/core/src/core/tests/test.AJXPVersion.php index e0a8f324d9..d0aeeae608 100644 --- a/core/src/core/tests/test.AJXPVersion.php +++ b/core/src/core/tests/test.AJXPVersion.php @@ -29,12 +29,10 @@ */ class AJXPVersion extends AbstractTest { - function AJXPVersion() { parent::AbstractTest("AjaXplorer version", "AJXP version : ".AJXP_VERSION); } - function doTest() - { + public function AJXPVersion() { parent::AbstractTest("AjaXplorer version", "AJXP version : ".AJXP_VERSION); } + public function doTest() + { $this->failedLevel = "info"; return FALSE; } }; - -?> diff --git a/core/src/core/tests/test.Client.php b/core/src/core/tests/test.Client.php index 2a1e5917e0..f68570086f 100644 --- a/core/src/core/tests/test.Client.php +++ b/core/src/core/tests/test.Client.php @@ -29,13 +29,11 @@ */ class Client extends AbstractTest { - function Client() { parent::AbstractTest("Client Browser", "Current client ".$_SERVER['HTTP_USER_AGENT']); } - function doTest() - { - $this->testedParams["Client"] = $_SERVER['HTTP_USER_AGENT']; + public function Client() { parent::AbstractTest("Client Browser", "Current client ".$_SERVER['HTTP_USER_AGENT']); } + public function doTest() + { + $this->testedParams["Client"] = $_SERVER['HTTP_USER_AGENT']; $this->failedLevel = "info"; return FALSE; } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.PHPCLI.php b/core/src/core/tests/test.PHPCLI.php index 9d0e68df3e..372dc90bf8 100644 --- a/core/src/core/tests/test.PHPCLI.php +++ b/core/src/core/tests/test.PHPCLI.php @@ -1,137 +1,135 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); -require_once('../classes/class.AbstractTest.php'); - -/** - * Check current PHP Version - * @package AjaXplorer - * @subpackage Tests - */ -class PHPCLI extends AbstractTest -{ - function PHPCLI() { parent::AbstractTest("PHP Command Line", "Testing PHP command line (default is php)"); } - function doTest() - { - if(!is_writable(AJXP_CACHE_DIR)){ - $this->testedParams["Command Line Available"] = "No"; - $this->failedLevel = "warning"; - $this->failedInfo = "Php command line not detected (cache directory not writeable), this is NOT BLOCKING, but enabling it could allow to send some long tasks in background. If you do not have the ability to tweak your server, you can safely ignore this warning."; - return FALSE; - } - $windows = (PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows"); - - $sModeExecDir = ini_get("safe_mode_exec_dir") ; - $safeEnabled = ini_get("safe_mode") || !empty($sModeExecDir); - - $disabled_functions=explode(',',ini_get('disable_functions')); - $fName = ($windows ? "popen" : "exec"); - $notFoundFunction = in_array($fName, $disabled_functions) || !function_exists($fName) || !is_callable($fName); - - $comEnabled = class_exists("COM"); - $useCOM = false; - - if( ( $safeEnabled || $notFoundFunction )){ - if($comEnabled){ - $useCOM = true; - }else{ - $this->testedParams["Command Line Available"] = "No"; - $this->failedLevel = "warning"; - $this->failedInfo = "Php command line not detected (there seem to be some safe_mode or a-like restriction), this is NOT BLOCKING, but enabling it could allow to send some long tasks in background. If you do not have the ability to tweak your server, you can safely ignore this warning."; - return FALSE; - } - } - - $defaultCli = ConfService::getCoreConf("CLI_PHP"); - if($defaultCli == null) $defaultCli = "php"; - - $token = md5(time()); - $robustCacheDir = str_replace("/", DIRECTORY_SEPARATOR, AJXP_CACHE_DIR); - $logDir = $robustCacheDir.DIRECTORY_SEPARATOR."cmd_outputs"; - if(!is_dir($logDir)) mkdir($logDir, 0755); - $logFile = $logDir."/".$token.".out"; - - $testScript = AJXP_CACHE_DIR."/cli_test.php"; - file_put_contents($testScript, ""); - - $cmd = $defaultCli." ". $robustCacheDir .DIRECTORY_SEPARATOR."cli_test.php"; - - if ($windows){ - /* Next 2 lines modified by rmeske: Need to wrap the folder and file paths in double quotes. */ - $cmd = $defaultCli." ". chr(34).$robustCacheDir .DIRECTORY_SEPARATOR."cli_test.php".chr(34); - $cmd .= " > ".chr(34).$logFile.chr(34); - - $comCommand = $cmd; - if($useCOM){ - $WshShell = new COM("WScript.Shell"); - $res = $WshShell->Run("cmd /C $comCommand", 0, false); - }else{ - $tmpBat = implode(DIRECTORY_SEPARATOR, array(str_replace("/", DIRECTORY_SEPARATOR, AJXP_INSTALL_PATH), "data","tmp", md5(time()).".bat")); - $cmd .= "\n DEL ".chr(34).$tmpBat.chr(34); - file_put_contents($tmpBat, $cmd); - /* Following 1 line modified by rmeske: The windows Start command identifies the first parameter in quotes as a title for the window. Therefore, when enclosing a command with double quotes you must include a window title first - START ["title"] [/Dpath] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED] [/LOW | /NORMAL | /HIGH | /REALTIME] [/WAIT] [/B] [command / program] [parameters] - */ - @pclose(@popen('start /b "CLI" "'.$tmpBat.'"', 'r')); - sleep(1); - // Failed, but we can try with COM - if( ! is_file(AJXP_CACHE_DIR."/cli_result.php") && $comEnabled ){ - $useCOM = true; - $WshShell = new COM("WScript.Shell"); - $res = $WshShell->Run("cmd /C $comCommand", 0, false); - } - } - }else{ - new UnixProcess($cmd, $logFile); - } - - sleep(1); - $availability = true; - if(is_file(AJXP_CACHE_DIR."/cli_result.php")){ - $this->testedParams["Command Line Available"] = "Yes"; - unlink(AJXP_CACHE_DIR."/cli_result.php"); - if($useCOM){ - $this->failedLevel = "warning"; - $availability = true; - $this->failedInfo = "Php command line detected, but using the windows COM extension. Just make sure to enable COM in the AjaXplorer Core Options"; - }else{ - $this->failedInfo = "Php command line detected, this will allow to send some tasks in background. Enable it in the AjaXplorer Core Options"; - } - }else{ - if(is_file($logFile)){ - $log = file_get_contents($logFile); - unlink($logFile); - } - $this->testedParams["Command Line Available"] = "No : $log"; - $this->failedLevel = "warning"; - $this->failedInfo = "Php command line not detected, this is NOT BLOCKING, but enabling it could allow to send some long tasks in background. If you do not have the ability to tweak your server, you can safely ignore this warning."; - if($windows){ - $this->failedInfo .= "
    On Windows, try to activate the php COM extension, and set correct rights to the cmd exectuble to make it runnable by the web server, this should solve the problem."; - } - $availability = false; - } - unlink(AJXP_CACHE_DIR."/cli_test.php"); - - return $availability; - } -}; - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); +require_once('../classes/class.AbstractTest.php'); + +/** + * Check current PHP Version + * @package AjaXplorer + * @subpackage Tests + */ +class PHPCLI extends AbstractTest +{ + public function PHPCLI() { parent::AbstractTest("PHP Command Line", "Testing PHP command line (default is php)"); } + public function doTest() + { + if (!is_writable(AJXP_CACHE_DIR)) { + $this->testedParams["Command Line Available"] = "No"; + $this->failedLevel = "warning"; + $this->failedInfo = "Php command line not detected (cache directory not writeable), this is NOT BLOCKING, but enabling it could allow to send some long tasks in background. If you do not have the ability to tweak your server, you can safely ignore this warning."; + return FALSE; + } + $windows = (PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows"); + + $sModeExecDir = ini_get("safe_mode_exec_dir") ; + $safeEnabled = ini_get("safe_mode") || !empty($sModeExecDir); + + $disabled_functions=explode(',',ini_get('disable_functions')); + $fName = ($windows ? "popen" : "exec"); + $notFoundFunction = in_array($fName, $disabled_functions) || !function_exists($fName) || !is_callable($fName); + + $comEnabled = class_exists("COM"); + $useCOM = false; + + if ( ( $safeEnabled || $notFoundFunction )) { + if ($comEnabled) { + $useCOM = true; + } else { + $this->testedParams["Command Line Available"] = "No"; + $this->failedLevel = "warning"; + $this->failedInfo = "Php command line not detected (there seem to be some safe_mode or a-like restriction), this is NOT BLOCKING, but enabling it could allow to send some long tasks in background. If you do not have the ability to tweak your server, you can safely ignore this warning."; + return FALSE; + } + } + + $defaultCli = ConfService::getCoreConf("CLI_PHP"); + if($defaultCli == null) $defaultCli = "php"; + + $token = md5(time()); + $robustCacheDir = str_replace("/", DIRECTORY_SEPARATOR, AJXP_CACHE_DIR); + $logDir = $robustCacheDir.DIRECTORY_SEPARATOR."cmd_outputs"; + if(!is_dir($logDir)) mkdir($logDir, 0755); + $logFile = $logDir."/".$token.".out"; + + $testScript = AJXP_CACHE_DIR."/cli_test.php"; + file_put_contents($testScript, ""); + + $cmd = $defaultCli." ". $robustCacheDir .DIRECTORY_SEPARATOR."cli_test.php"; + + if ($windows) { + /* Next 2 lines modified by rmeske: Need to wrap the folder and file paths in double quotes. */ + $cmd = $defaultCli." ". chr(34).$robustCacheDir .DIRECTORY_SEPARATOR."cli_test.php".chr(34); + $cmd .= " > ".chr(34).$logFile.chr(34); + + $comCommand = $cmd; + if ($useCOM) { + $WshShell = new COM("WScript.Shell"); + $res = $WshShell->Run("cmd /C $comCommand", 0, false); + } else { + $tmpBat = implode(DIRECTORY_SEPARATOR, array(str_replace("/", DIRECTORY_SEPARATOR, AJXP_INSTALL_PATH), "data","tmp", md5(time()).".bat")); + $cmd .= "\n DEL ".chr(34).$tmpBat.chr(34); + file_put_contents($tmpBat, $cmd); + /* Following 1 line modified by rmeske: The windows Start command identifies the first parameter in quotes as a title for the window. Therefore, when enclosing a command with double quotes you must include a window title first + START ["title"] [/Dpath] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED] [/LOW | /NORMAL | /HIGH | /REALTIME] [/WAIT] [/B] [command / program] [parameters] + */ + @pclose(@popen('start /b "CLI" "'.$tmpBat.'"', 'r')); + sleep(1); + // Failed, but we can try with COM + if ( ! is_file(AJXP_CACHE_DIR."/cli_result.php") && $comEnabled ) { + $useCOM = true; + $WshShell = new COM("WScript.Shell"); + $res = $WshShell->Run("cmd /C $comCommand", 0, false); + } + } + } else { + new UnixProcess($cmd, $logFile); + } + + sleep(1); + $availability = true; + if (is_file(AJXP_CACHE_DIR."/cli_result.php")) { + $this->testedParams["Command Line Available"] = "Yes"; + unlink(AJXP_CACHE_DIR."/cli_result.php"); + if ($useCOM) { + $this->failedLevel = "warning"; + $availability = true; + $this->failedInfo = "Php command line detected, but using the windows COM extension. Just make sure to enable COM in the AjaXplorer Core Options"; + } else { + $this->failedInfo = "Php command line detected, this will allow to send some tasks in background. Enable it in the AjaXplorer Core Options"; + } + } else { + if (is_file($logFile)) { + $log = file_get_contents($logFile); + unlink($logFile); + } + $this->testedParams["Command Line Available"] = "No : $log"; + $this->failedLevel = "warning"; + $this->failedInfo = "Php command line not detected, this is NOT BLOCKING, but enabling it could allow to send some long tasks in background. If you do not have the ability to tweak your server, you can safely ignore this warning."; + if ($windows) { + $this->failedInfo .= "
    On Windows, try to activate the php COM extension, and set correct rights to the cmd exectuble to make it runnable by the web server, this should solve the problem."; + } + $availability = false; + } + unlink(AJXP_CACHE_DIR."/cli_test.php"); + + return $availability; + } +}; diff --git a/core/src/core/tests/test.PHPDomXML.php b/core/src/core/tests/test.PHPDomXML.php index 90df2f10ec..2ab63fc6f7 100644 --- a/core/src/core/tests/test.PHPDomXML.php +++ b/core/src/core/tests/test.PHPDomXML.php @@ -28,17 +28,15 @@ */ class PHPDomXML extends AbstractTest { - function PHPDomXML() { parent::AbstractTest("DOM Xml enabled", "Dom XML is required, you may have to install the php-xml extension."); } - function doTest() - { + public function PHPDomXML() { parent::AbstractTest("DOM Xml enabled", "Dom XML is required, you may have to install the php-xml extension."); } + public function doTest() + { $this->failedLevel = "error"; - if (!class_exists("DOMDocument")){ - $this->testedParams["DOM Enabled"] = "No"; - return FALSE; + if (!class_exists("DOMDocument")) { + $this->testedParams["DOM Enabled"] = "No"; + return FALSE; } $this->testedParams["DOM Enabled"] = "Yes"; return TRUE; } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.PHPErrorLevel.php b/core/src/core/tests/test.PHPErrorLevel.php index cb781263c7..2162f6e5ec 100644 --- a/core/src/core/tests/test.PHPErrorLevel.php +++ b/core/src/core/tests/test.PHPErrorLevel.php @@ -28,39 +28,35 @@ */ class PHPErrorLevel extends AbstractTest { - function PHPErrorLevel() { parent::AbstractTest("PHP error level", PHPErrorLevel::error2string(error_reporting())); } - function doTest() - { - if (error_reporting() & E_NOTICE) - { + public function PHPErrorLevel() { parent::AbstractTest("PHP error level", PHPErrorLevel::error2string(error_reporting())); } + public function doTest() + { + if (error_reporting() & E_NOTICE) { $this->failedLevel = "error"; $this->failedInfo = "You must lower your PHP error level in php.ini NOT TO INCLUDE E_NOTICE (you have:".$this->failedInfo.")"; return false; } $this->failedLevel = "info"; - return FALSE; + return FALSE; } - - function error2string($value) - { - $level_names = array( - E_ERROR => 'E_ERROR', E_WARNING => 'E_WARNING', - E_PARSE => 'E_PARSE', E_NOTICE => 'E_NOTICE', - E_CORE_ERROR => 'E_CORE_ERROR', E_CORE_WARNING => 'E_CORE_WARNING', - E_COMPILE_ERROR => 'E_COMPILE_ERROR', E_COMPILE_WARNING => 'E_COMPILE_WARNING', - E_USER_ERROR => 'E_USER_ERROR', E_USER_WARNING => 'E_USER_WARNING', - E_USER_NOTICE => 'E_USER_NOTICE' ); - if(defined('E_STRICT')) $level_names[E_STRICT]='E_STRICT'; - $levels=array(); - if(($value&E_ALL)==E_ALL) - { - $levels[]='E_ALL'; - $value&=~E_ALL; - } - foreach($level_names as $level=>$name) - if(($value&$level)==$level) $levels[]=$name; - return implode(' | ',$levels); - } -}; -?> \ No newline at end of file + public function error2string($value) + { + $level_names = array( + E_ERROR => 'E_ERROR', E_WARNING => 'E_WARNING', + E_PARSE => 'E_PARSE', E_NOTICE => 'E_NOTICE', + E_CORE_ERROR => 'E_CORE_ERROR', E_CORE_WARNING => 'E_CORE_WARNING', + E_COMPILE_ERROR => 'E_COMPILE_ERROR', E_COMPILE_WARNING => 'E_COMPILE_WARNING', + E_USER_ERROR => 'E_USER_ERROR', E_USER_WARNING => 'E_USER_WARNING', + E_USER_NOTICE => 'E_USER_NOTICE' ); + if(defined('E_STRICT')) $level_names[E_STRICT]='E_STRICT'; + $levels=array(); + if (($value&E_ALL)==E_ALL) { + $levels[]='E_ALL'; + $value&=~E_ALL; + } + foreach($level_names as $level=>$name) + if(($value&$level)==$level) $levels[]=$name; + return implode(' | ',$levels); + } +}; diff --git a/core/src/core/tests/test.PHPGDVersion.php b/core/src/core/tests/test.PHPGDVersion.php index 1ca795f8db..d58727e4d4 100644 --- a/core/src/core/tests/test.PHPGDVersion.php +++ b/core/src/core/tests/test.PHPGDVersion.php @@ -28,17 +28,15 @@ */ class PHPGDVersion extends AbstractTest { - function PHPGDVersion() { parent::AbstractTest("PHP GD version", "GD is required for generating thumbnails"); } - function doTest() - { + public function PHPGDVersion() { parent::AbstractTest("PHP GD version", "GD is required for generating thumbnails"); } + public function doTest() + { $this->failedLevel = "warning"; - if (!function_exists("gd_info") || !function_exists("imagecopyresized") || !function_exists("imagecopyresampled")){ - $this->testedParams["GD Enabled"] = "No"; - return FALSE; + if (!function_exists("gd_info") || !function_exists("imagecopyresized") || !function_exists("imagecopyresampled")) { + $this->testedParams["GD Enabled"] = "No"; + return FALSE; } $this->testedParams["GD Enabled"] = "Yes"; return TRUE; } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.PHPLimits.php b/core/src/core/tests/test.PHPLimits.php index ce58a5f821..d635dd4773 100644 --- a/core/src/core/tests/test.PHPLimits.php +++ b/core/src/core/tests/test.PHPLimits.php @@ -28,21 +28,19 @@ */ class PHPLimits extends AbstractTest { - function PHPLimits() { parent::AbstractTest("PHP Limits variables", "Testing configs"); } - function doTest() - { - $this->testedParams["Upload Max Size"] = ini_get("upload_max_filesize"); - $this->testedParams["Memory Limit"] = ((ini_get("memory_limit")!="")?ini_get("memory_limit"):get_cfg_var("memory_limit")); - $this->testedParams["Max execution time"] = ini_get("max_execution_time"); - $this->testedParams["Safe Mode"] = (ini_get("safe_mode")?"1":"0"); - $this->testedParams["Safe Mode GID"] = (ini_get("safe_mode_gid")?"1":"0"); - $this->testedParams["Xml parser enabled"] = (function_exists("xml_parser_create")?"1":"0"); - foreach ($this->testedParams as $paramName => $paramValue){ - $this->failedInfo .= "\n$paramName=$paramValue"; - } + public function PHPLimits() { parent::AbstractTest("PHP Limits variables", "Testing configs"); } + public function doTest() + { + $this->testedParams["Upload Max Size"] = ini_get("upload_max_filesize"); + $this->testedParams["Memory Limit"] = ((ini_get("memory_limit")!="")?ini_get("memory_limit"):get_cfg_var("memory_limit")); + $this->testedParams["Max execution time"] = ini_get("max_execution_time"); + $this->testedParams["Safe Mode"] = (ini_get("safe_mode")?"1":"0"); + $this->testedParams["Safe Mode GID"] = (ini_get("safe_mode_gid")?"1":"0"); + $this->testedParams["Xml parser enabled"] = (function_exists("xml_parser_create")?"1":"0"); + foreach ($this->testedParams as $paramName => $paramValue) { + $this->failedInfo .= "\n$paramName=$paramValue"; + } $this->failedLevel = "info"; return FALSE; } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.PHPMCrypt.php b/core/src/core/tests/test.PHPMCrypt.php index 6c811a229f..781e385408 100644 --- a/core/src/core/tests/test.PHPMCrypt.php +++ b/core/src/core/tests/test.PHPMCrypt.php @@ -28,17 +28,15 @@ */ class PHPMCrypt extends AbstractTest { - function PHPMCrypt() { parent::AbstractTest("MCrypt enabled", "MCrypt is required for generating publiclets"); } - function doTest() - { - $this->failedLevel = "warning"; - if (!function_exists("mcrypt_create_iv")){ - $this->testedParams["MCrypt Enabled"] = "No"; - return FALSE; + public function PHPMCrypt() { parent::AbstractTest("MCrypt enabled", "MCrypt is required by all security functions."); } + public function doTest() + { + $this->failedLevel = "error"; + if (!function_exists("mcrypt_create_iv")) { + $this->testedParams["MCrypt Enabled"] = "No"; + return FALSE; } $this->testedParams["MCrypt Enabled"] = "Yes"; return TRUE; } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.PHPOS.php b/core/src/core/tests/test.PHPOS.php index 92892fc9f3..e8f0a161d5 100644 --- a/core/src/core/tests/test.PHPOS.php +++ b/core/src/core/tests/test.PHPOS.php @@ -28,13 +28,11 @@ */ class PHPOS extends AbstractTest { - function PHPOS() { parent::AbstractTest("PHP operating system", "Current operating system ".PHP_OS); } - function doTest() - { - $this->testedParams["Server OS"] = PHP_OS; + public function PHPOS() { parent::AbstractTest("PHP operating system", "Current operating system ".PHP_OS); } + public function doTest() + { + $this->testedParams["Server OS"] = PHP_OS; $this->failedLevel = "info"; return FALSE; } }; - -?> diff --git a/core/src/core/tests/test.PHPSession.php b/core/src/core/tests/test.PHPSession.php index fe0d244629..8265d2f53d 100644 --- a/core/src/core/tests/test.PHPSession.php +++ b/core/src/core/tests/test.PHPSession.php @@ -28,32 +28,30 @@ */ class PHPSession extends AbstractTest { - function PHPSession() { parent::AbstractTest("PHP Session", "Testing configs"); } - function doTest() + public function PHPSession() { parent::AbstractTest("PHP Session", "Testing configs"); } + public function doTest() { $handler = ini_get("session.save_handler"); - if($handler != "files") { + if ($handler != "files") { $this->testedParams["Session Save Path"] = "Handler is not file based"; return TRUE; } - $tmpDir = session_save_path(); - $this->testedParams["Session Save Path"] = $tmpDir; - if($tmpDir != ""){ - $this->testedParams["Session Save Path Writeable"] = @is_writable($tmpDir); - if(!$this->testedParams["Session Save Path Writeable"]){ - $this->failedLevel = "error"; - $this->failedInfo = "The temporary folder used by PHP to save the session data is either incorrect or not writeable! Please check : ".session_save_path(); - $this->failedInfo .= "

    Suggestion : create your own temporary folder for sessions and set the session.save_path parameter in the conf/bootstrap_conf.php

    "; - return FALSE; - } - }else{ - $this->failedLevel = "warning"; - $this->failedInfo = "Warning, it seems that your temporary folder used to save session data is not set. If you are encountering troubles with logging and sessions, please check session.save_path in your php.ini. Otherwise you can ignore this."; - return FALSE; - } + $tmpDir = session_save_path(); + $this->testedParams["Session Save Path"] = $tmpDir; + if ($tmpDir != "") { + $this->testedParams["Session Save Path Writeable"] = @is_writable($tmpDir); + if (!$this->testedParams["Session Save Path Writeable"]) { + $this->failedLevel = "error"; + $this->failedInfo = "The temporary folder used by PHP to save the session data is either incorrect or not writeable! Please check : ".session_save_path(); + $this->failedInfo .= "

    Suggestion : create your own temporary folder for sessions and set the session.save_path parameter in the conf/bootstrap_conf.php

    "; + return FALSE; + } + } else { + $this->failedLevel = "warning"; + $this->failedInfo = "Warning, it seems that your temporary folder used to save session data is not set. If you are encountering troubles with logging and sessions, please check session.save_path in your php.ini. Otherwise you can ignore this."; + return FALSE; + } $this->failedLevel = "info"; return FALSE; } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.PHPVersion.php b/core/src/core/tests/test.PHPVersion.php index 9932911806..6cdcc96fd3 100644 --- a/core/src/core/tests/test.PHPVersion.php +++ b/core/src/core/tests/test.PHPVersion.php @@ -28,12 +28,12 @@ */ class PHPVersion extends AbstractTest { - function PHPVersion() { parent::AbstractTest("PHP version", "Minimum required version is PHP 5.3.0"); } - function doTest() - { - $version = phpversion(); - $this->testedParams["PHP Version"] = $version; - //return false; + public function PHPVersion() { parent::AbstractTest("PHP version", "Minimum required version is PHP 5.3.0"); } + public function doTest() + { + $version = phpversion(); + $this->testedParams["PHP Version"] = $version; + //return false; if (floatval($version) < 5.3) return FALSE; $locale = setlocale(LC_CTYPE, 0); $dirSep = DIRECTORY_SEPARATOR; @@ -43,5 +43,3 @@ function doTest() return TRUE; } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.PHP_APC.php b/core/src/core/tests/test.PHP_APC.php index e8e46b4aa4..a302c8957f 100644 --- a/core/src/core/tests/test.PHP_APC.php +++ b/core/src/core/tests/test.PHP_APC.php @@ -28,15 +28,15 @@ */ class PHP_APC extends AbstractTest { - function PHP_APC() { parent::AbstractTest("PHP APC extension", "AjaXplorer framework loads a lot of PHP files at each query, and using a PHP accelerator is greatly recommanded."); } - function doTest() + public function PHP_APC() { parent::AbstractTest("PHP APC extension", "AjaXplorer framework loads a lot of PHP files at each query, and using a PHP accelerator is greatly recommanded."); } + public function doTest() { $this->failedLevel = "warning"; $v = @extension_loaded('apc'); - if (isSet($v) && (is_numeric($v) || strtolower($v) == "on")){ + if (isSet($v) && (is_numeric($v) || strtolower($v) == "on")) { $this->testedParams["PHP APC extension loaded"] = "No"; return FALSE; - }else if(!isSet($v)){ + } else if (!isSet($v)) { $this->failedInfo = "AjaXplorer framework loads a lot of PHP files at each query, and using a PHP accelerator is greatly recommanded."; return FALSE; } diff --git a/core/src/core/tests/test.PHP_OB.php b/core/src/core/tests/test.PHP_OB.php index f566545d8e..cb2e37aba3 100644 --- a/core/src/core/tests/test.PHP_OB.php +++ b/core/src/core/tests/test.PHP_OB.php @@ -1,47 +1,47 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); -require_once('../classes/class.AbstractTest.php'); - -/** - * Check that DOMXml is enabled - * @package AjaXplorer - * @subpackage Tests - */ -class PHP_OB extends AbstractTest -{ - function PHP_OB() { parent::AbstractTest("PHP Output Buffer disabled", "You should disable php output_buffering parameter for better performances with AjaXplorer."); } - function doTest() - { - $this->failedLevel = "warning"; - $v = @ini_get("output_buffering"); - if (isSet($v) && (is_numeric($v) || strtolower($v) == "on")){ - $this->testedParams["PHP Output Buffer disabled"] = "No"; - return FALSE; - }else if(!isSet($v)){ - $this->failedInfo = "Unable to detect the output_buffering value, please make sure that it is disabled (Off) in your php.ini or your virtual host."; - return FALSE; - } - $this->failedInfo = "PHP Output Buffering is disabled, this is good for better performances"; - $this->testedParams["PHP Output Buffer disabled"] = "Yes"; - return TRUE; - } -}; + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); +require_once('../classes/class.AbstractTest.php'); + +/** + * Check that DOMXml is enabled + * @package AjaXplorer + * @subpackage Tests + */ +class PHP_OB extends AbstractTest +{ + public function PHP_OB() { parent::AbstractTest("PHP Output Buffer disabled", "You should disable php output_buffering parameter for better performances with AjaXplorer."); } + public function doTest() + { + $this->failedLevel = "warning"; + $v = @ini_get("output_buffering"); + if (isSet($v) && (is_numeric($v) || strtolower($v) == "on")) { + $this->testedParams["PHP Output Buffer disabled"] = "No"; + return FALSE; + } else if (!isSet($v)) { + $this->failedInfo = "Unable to detect the output_buffering value, please make sure that it is disabled (Off) in your php.ini or your virtual host."; + return FALSE; + } + $this->failedInfo = "PHP Output Buffering is disabled, this is good for better performances"; + $this->testedParams["PHP Output Buffer disabled"] = "Yes"; + return TRUE; + } +}; diff --git a/core/src/core/tests/test.SSLEncryption.php b/core/src/core/tests/test.SSLEncryption.php index 77cd4f5d1e..9effef64f4 100644 --- a/core/src/core/tests/test.SSLEncryption.php +++ b/core/src/core/tests/test.SSLEncryption.php @@ -28,23 +28,21 @@ */ class SSLEncryption extends AbstractTest { - function SSLEncryption() { parent::AbstractTest("SSL Encryption", "You are not using SSL encryption, or it was not detected by the server. Be aware that it is strongly recommended to secure all communication of data over the network."); } - function doTest() - { + public function SSLEncryption() { parent::AbstractTest("SSL Encryption", "You are not using SSL encryption, or it was not detected by the server. Be aware that it is strongly recommended to secure all communication of data over the network."); } + public function doTest() + { // Get the locale $ssl = false; - if(isSet($_SERVER["HTTPS"]) && strtolower($_SERVER["HTTPS"]) == "on"){ - $ssl = true; - } - if (!$ssl) { - $this->failedLevel = "warning"; + if (isSet($_SERVER["HTTPS"]) && strtolower($_SERVER["HTTPS"]) == "on") { + $ssl = true; + } + if (!$ssl) { + $this->failedLevel = "warning"; $this->failedInfo .= "

    Suggestion : if your server supports HTTPS, set the AJXP_FORCE_REDIRECT_HTTPS parameter in the conf/bootstrap_conf.php file.

    "; - return FALSE; - }else{ - $this->failedInfo .= "Https protocol detected"; - return TRUE; + return FALSE; + } else { + $this->failedInfo .= "Https protocol detected"; + return TRUE; } } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.ServerEncoding.php b/core/src/core/tests/test.ServerEncoding.php index 492a74cd91..0a8afc7907 100644 --- a/core/src/core/tests/test.ServerEncoding.php +++ b/core/src/core/tests/test.ServerEncoding.php @@ -28,9 +28,9 @@ */ class ServerEncoding extends AbstractTest { - function ServerEncoding() { parent::AbstractTest("Server charset encoding", "You must set a correct charset encoding in your locale definition in the form: en_us.UTF-8. Please refer to setlocale man page. If your detected locale is C, please check the F.A.Q.. "); } - function doTest() - { + public function ServerEncoding() { parent::AbstractTest("Server charset encoding", "You must set a correct charset encoding in your locale definition in the form: en_us.UTF-8. Please refer to setlocale man page. If your detected locale is C, please check the F.A.Q.. "); } + public function doTest() + { // Get the locale $locale = setlocale(LC_CTYPE, 0); if ($locale == 'C') { @@ -47,16 +47,13 @@ function doTest() } // Check if we have iconv if (!function_exists("iconv") && floatval(phpversion()) > 5.0) { $this->failedInfo .= "Couldn't find iconv. Please use a PHP version with iconv support"; return FALSE; } - if (floatval(phpversion) > 5.0) - { + if (floatval(phpversion) > 5.0) { // Try converting from a known UTF-8 string to ISO8859-1 string and back to make sure it works. $string = "aéàç"; $iso = iconv("UTF-8", "ISO-8859-1", $string); $back = iconv("ISO-8859-1", "UTF-8", $iso); - if (strlen($iso) != 4 || ord($iso[1]) != 233 || $back != $string) { $this->failedInfo .= "iconv doesn't work on your system: $string $iso $back"; return FALSE; } + if (strlen($iso) != 4 || ord($iso[1]) != 233 || $back != $string) { $this->failedInfo .= "iconv doesn't work on your system: $string $iso $back"; return FALSE; } } return TRUE; } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.Upload.php b/core/src/core/tests/test.Upload.php index 0ef348c597..2102b1e402 100644 --- a/core/src/core/tests/test.Upload.php +++ b/core/src/core/tests/test.Upload.php @@ -28,46 +28,44 @@ */ class Upload extends AbstractTest { - function Upload() { parent::AbstractTest("Upload particularities", "Testing configs"); } - function doTest() - { - $tmpDir = ini_get("upload_tmp_dir"); - if (!$tmpDir) $tmpDir = realpath(sys_get_temp_dir()); - if(ConfService::getCoreConf("AJXP_TMP_DIR") != ""){ + public function Upload() { parent::AbstractTest("Upload particularities", "Testing configs"); } + public function doTest() + { + $tmpDir = ini_get("upload_tmp_dir"); + if (!$tmpDir) $tmpDir = realpath(sys_get_temp_dir()); + if (ConfService::getCoreConf("AJXP_TMP_DIR") != "") { $tmpDir = ConfService::getCoreConf("AJXP_TMP_DIR"); } - if(defined("AJXP_TMP_DIR") && AJXP_TMP_DIR !=""){ - $tmpDir = AJXP_TMP_DIR; - } - $this->testedParams["Upload Tmp Dir Writeable"] = @is_writable($tmpDir); - $this->testedParams["PHP Upload Max Size"] = $this->returnBytes(ini_get("upload_max_filesize")); - $this->testedParams["PHP Post Max Size"] = $this->returnBytes(ini_get("post_max_size")); - //$this->testedParams["AJXP Upload Max Size"] = $this->returnBytes($upload_max_size_per_file); - foreach ($this->testedParams as $paramName => $paramValue){ - $this->failedInfo .= "\n$paramName=$paramValue"; - } - if(!$this->testedParams["Upload Tmp Dir Writeable"]){ - $this->failedLevel = "error"; - $this->failedInfo = "The temporary folder used by PHP to upload files is either incorrect or not writeable! Upload will not work. Please check : ".ini_get("upload_tmp_dir"); + if (defined("AJXP_TMP_DIR") && AJXP_TMP_DIR !="") { + $tmpDir = AJXP_TMP_DIR; + } + $this->testedParams["Upload Tmp Dir Writeable"] = @is_writable($tmpDir); + $this->testedParams["PHP Upload Max Size"] = $this->returnBytes(ini_get("upload_max_filesize")); + $this->testedParams["PHP Post Max Size"] = $this->returnBytes(ini_get("post_max_size")); + //$this->testedParams["AJXP Upload Max Size"] = $this->returnBytes($upload_max_size_per_file); + foreach ($this->testedParams as $paramName => $paramValue) { + $this->failedInfo .= "\n$paramName=$paramValue"; + } + if (!$this->testedParams["Upload Tmp Dir Writeable"]) { + $this->failedLevel = "error"; + $this->failedInfo = "The temporary folder used by PHP to upload files is either incorrect or not writeable! Upload will not work. Please check : ".ini_get("upload_tmp_dir"); $this->failedInfo .= "

    Suggestion : Set the AJXP_TMP_DIR parameter in the conf/bootstrap_conf.php file

    "; - return FALSE; - } + return FALSE; + } /* - if($this->testedParams["AJXP Upload Max Size"] > $this->testedParams["PHP Upload Max Size"]){ - $this->failedLevel = "warning"; - $this->failedInfo .= "\nAjaxplorer cannot override the PHP setting! Unless you edit your php.ini, your upload will be limited to ".ini_get("upload_max_filesize")." per file."; - return FALSE; - } - if($this->testedParams["AJXP Upload Max Size"] > $this->testedParams["PHP Post Max Size"]){ - $this->failedLevel = "warning"; - $this->failedInfo .= "\nAjaxplorer cannot override the PHP setting! Unless you edit your php.ini, your upload will be limited to ".ini_get("post_max_size")." per file."; - return FALSE; - } + if ($this->testedParams["AJXP Upload Max Size"] > $this->testedParams["PHP Upload Max Size"]) { + $this->failedLevel = "warning"; + $this->failedInfo .= "\nAjaxplorer cannot override the PHP setting! Unless you edit your php.ini, your upload will be limited to ".ini_get("upload_max_filesize")." per file."; + return FALSE; + } + if ($this->testedParams["AJXP Upload Max Size"] > $this->testedParams["PHP Post Max Size"]) { + $this->failedLevel = "warning"; + $this->failedInfo .= "\nAjaxplorer cannot override the PHP setting! Unless you edit your php.ini, your upload will be limited to ".ini_get("post_max_size")." per file."; + return FALSE; + } */ - + $this->failedLevel = "info"; return FALSE; } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.UsersConfig.php b/core/src/core/tests/test.UsersConfig.php index fa2bf58f03..97d36d1a86 100644 --- a/core/src/core/tests/test.UsersConfig.php +++ b/core/src/core/tests/test.UsersConfig.php @@ -28,14 +28,12 @@ */ class UsersConfig extends AbstractTest { - function UsersConfig() { parent::AbstractTest("Users Configuration", "Current config for users"); } - function doTest() - { - $this->testedParams["Users enabled"] = AuthService::usersEnabled(); - $this->testedParams["Guest enabled"] = ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth"); + public function UsersConfig() { parent::AbstractTest("Users Configuration", "Current config for users"); } + public function doTest() + { + $this->testedParams["Users enabled"] = AuthService::usersEnabled(); + $this->testedParams["Guest enabled"] = ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth"); $this->failedLevel = "info"; return FALSE; } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.Writeability.php b/core/src/core/tests/test.Writeability.php index 55e67bea1d..fa39f01c84 100644 --- a/core/src/core/tests/test.Writeability.php +++ b/core/src/core/tests/test.Writeability.php @@ -28,56 +28,54 @@ */ class Writeability extends AbstractTest { - function Writeability() { parent::AbstractTest("Required writeable folder", "One of the following folder should be writeable and is not : "); } - function doTest() - { - //include(AJXP_CONF_PATH."/bootstrap_plugins.php"); - $checks = array(); + public function Writeability() { parent::AbstractTest("Required writeable folder", "One of the following folder should be writeable and is not : "); } + public function doTest() + { + //include(AJXP_CONF_PATH."/bootstrap_plugins.php"); + $checks = array(); /* - if(isSet($PLUGINS["CONF_DRIVER"])){ - $confDriver = $PLUGINS["CONF_DRIVER"]; - if(isSet($confDriver["OPTIONS"]) && isSet($confDriver["OPTIONS"]["REPOSITORIES_FILEPATH"])){ - $checks[] = dirname($confDriver["OPTIONS"]["REPOSITORIES_FILEPATH"]); - } - if(isSet($confDriver["OPTIONS"]) && isSet($confDriver["OPTIONS"]["USERS_DIRPATH"])){ - $checks[] = $confDriver["OPTIONS"]["REPOSITORIES_FILEPATH"]; - } - } - if(isset($PLUGINS["AUTH_DRIVER"])){ - $authDriver = $PLUGINS["AUTH_DRIVER"]; - if(isset($authDriver["OPTIONS"]) && isSet($authDriver["OPTIONS"]["USERS_FILEPATH"])){ - $checks[] = dirname($authDriver["OPTIONS"]["USERS_FILEPATH"]); - } - } - if(isset($PLUGINS["LOG_DRIVER"])){ - if(isset($PLUGINS["LOG_DRIVER"]["OPTIONS"]) && isSet($PLUGINS["LOG_DRIVER"]["OPTIONS"]["LOG_PATH"])){ - $checks[] = $PLUGINS["LOG_DRIVER"]["OPTIONS"]["LOG_PATH"]; - } - } + if (isSet($PLUGINS["CONF_DRIVER"])) { + $confDriver = $PLUGINS["CONF_DRIVER"]; + if (isSet($confDriver["OPTIONS"]) && isSet($confDriver["OPTIONS"]["REPOSITORIES_FILEPATH"])) { + $checks[] = dirname($confDriver["OPTIONS"]["REPOSITORIES_FILEPATH"]); + } + if (isSet($confDriver["OPTIONS"]) && isSet($confDriver["OPTIONS"]["USERS_DIRPATH"])) { + $checks[] = $confDriver["OPTIONS"]["REPOSITORIES_FILEPATH"]; + } + } + if (isset($PLUGINS["AUTH_DRIVER"])) { + $authDriver = $PLUGINS["AUTH_DRIVER"]; + if (isset($authDriver["OPTIONS"]) && isSet($authDriver["OPTIONS"]["USERS_FILEPATH"])) { + $checks[] = dirname($authDriver["OPTIONS"]["USERS_FILEPATH"]); + } + } + if (isset($PLUGINS["LOG_DRIVER"])) { + if (isset($PLUGINS["LOG_DRIVER"]["OPTIONS"]) && isSet($PLUGINS["LOG_DRIVER"]["OPTIONS"]["LOG_PATH"])) { + $checks[] = $PLUGINS["LOG_DRIVER"]["OPTIONS"]["LOG_PATH"]; + } + } */ - $checks[] = AJXP_CACHE_DIR; - $checks[] = AJXP_DATA_PATH; - $checked = array(); - $success = true; - foreach ($checks as $check){ - $w = false; - $check = AJXP_VarsFilter::filter($check); - if(!is_dir($check)){// Check parent - $check = dirname($check); - } - $w = is_writable($check); - $checked[basename($check)] = "".basename($check).":".($w?'true':'false'); - $success = $success & $w; - } + $checks[] = AJXP_CACHE_DIR; + $checks[] = AJXP_DATA_PATH; + $checked = array(); + $success = true; + foreach ($checks as $check) { + $w = false; + $check = AJXP_VarsFilter::filter($check); + if (!is_dir($check)) {// Check parent + $check = dirname($check); + } + $w = is_writable($check); + $checked[basename($check)] = "".basename($check).":".($w?'true':'false'); + $success = $success & $w; + } $this->testedParams["Writeable Folders"] = "[".implode(',
    ', array_values($checked))."]"; - if(!$success){ - $this->failedInfo .= implode(",", $checks); - return FALSE; + if (!$success) { + $this->failedInfo .= implode(",", $checks); + return FALSE; } $this->failedLevel = "info"; $this->failedInfo = "[".implode(',
    ', array_values($checked))."]"; return FALSE; } }; - -?> \ No newline at end of file diff --git a/core/src/core/tests/test.Zlib.php b/core/src/core/tests/test.Zlib.php index 8e4323f973..1a5675555e 100644 --- a/core/src/core/tests/test.Zlib.php +++ b/core/src/core/tests/test.Zlib.php @@ -28,19 +28,17 @@ */ class Zlib extends AbstractTest { - function Zlib() { parent::AbstractTest("Zlib extension (ZIP)", "Extension enabled : ".(function_exists('gzopen')?"1":"0")); } - function doTest() - { - $this->testedParams["Zlib Enabled"] = (function_exists('gzopen')?"Yes":"No"); - $os = PHP_OS; - /*if(stristr($os, "win")!==false && $this->testedParams["Zlib Enabled"]){ - $this->failedLevel = "warning"; - $this->failedInfo = "Warning, the zip functions are erraticaly working on Windows, please don't rely too much on them!"; - return FALSE; - }*/ + public function Zlib() { parent::AbstractTest("Zlib extension (ZIP)", "Extension enabled : ".(function_exists('gzopen')?"1":"0")); } + public function doTest() + { + $this->testedParams["Zlib Enabled"] = (function_exists('gzopen')?"Yes":"No"); + $os = PHP_OS; + /*if (stristr($os, "win")!==false && $this->testedParams["Zlib Enabled"]) { + $this->failedLevel = "warning"; + $this->failedInfo = "Warning, the zip functions are erraticaly working on Windows, please don't rely too much on them!"; + return FALSE; + }*/ $this->failedLevel = "info"; return false; } }; - -?> \ No newline at end of file diff --git a/core/src/plugins/access.ajxp_conf/ajxp_confActions.xml b/core/src/plugins/access.ajxp_conf/ajxp_confActions.xml index 14e502ef80..5404cf9a39 100644 --- a/core/src/plugins/access.ajxp_conf/ajxp_confActions.xml +++ b/core/src/plugins/access.ajxp_conf/ajxp_confActions.xml @@ -1,646 +1,646 @@ - - - - - - - - - - - - - - 0){ - path = window.actionArguments[0]; - if(Object.isString(path)){path = new AjxpNode(path,false,getBaseName(path));} - }else{ - userSelection = ajaxplorer.getUserSelection(); - if(userSelection && userSelection.isUnique() && (userSelection.hasDir() || userSelection.hasMime(["zip"]))){ - path = userSelection.getUniqueNode(); - } - } - if(path){ - ajaxplorer.updateContextData(path); - } - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    AJXP_MESSAGE[94] :
    -
    -
    -
    AJXP_MESSAGE[182] :
    -
    -
    -
    AJXP_MESSAGE[199] :
    -
    -
    - - - - ]]>
    - - - - -
    -
    - - - - - - - - - -
    -
    AJXP_MESSAGE[ajxp_conf.76] :
    -
    - - ]]>
    - - - -
    -
    - - - - - - - - - -
    -
    Group ID :
    -
    -
    -
    Group Label :
    -
    - - ]]>
    - - - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    AJXP_MESSAGE[ajxp_conf.95]
    -
    AJXP_MESSAGE[ajxp_conf.96]
    -
    -
    AJXP_MESSAGE[ajxp_conf.8]* :
    -
    AJXP_MESSAGE[ajxp_conf.116]* :
    - -
    -
    -
    AJXP_MESSAGE[ajxp_conf.32]* :
    -
    AJXP_MESSAGE[ajxp_conf.117]* :
    - -
    -
    -
    -
    - - -
    - - ]]>
    - - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    AJXP_MESSAGE[ajxp_conf.83]
    -
    -
    AJXP_MESSAGE[ajxp_conf.71] :
    -
    -
    AJXP_MESSAGE[ajxp_conf.70] :
    -
    -
    -
    - - ]]>
    - - - - - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> - - - - - - - - - - - - - - - - - - ]]> - - - - - - - - - - - - - - - - -
    - - - - - - - - - - -
    - -
    - #{name_string} : #{text} - - ]]> -
    - - - - - - -
    - -
    - #{name_string} : #{text} - - ]]> -
    - - - - - -
    - -
    - - ]]> -
    -
    -
    -
    + + + + + + + + + + + + + + 0){ + path = window.actionArguments[0]; + if(Object.isString(path)){path = new AjxpNode(path,false,getBaseName(path));} + }else{ + userSelection = ajaxplorer.getUserSelection(); + if(userSelection && userSelection.isUnique() && (userSelection.hasDir() || userSelection.hasMime(["zip"]))){ + path = userSelection.getUniqueNode(); + } + } + if(path){ + ajaxplorer.updateContextData(path); + } + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    AJXP_MESSAGE[94] :
    +
    +
    +
    AJXP_MESSAGE[182] :
    +
    +
    +
    AJXP_MESSAGE[199] :
    +
    +
    + + + + ]]>
    + + + + +
    +
    + + + + + + + + + +
    +
    AJXP_MESSAGE[ajxp_conf.76] :
    +
    + + ]]>
    + + + +
    +
    + + + + + + + + + +
    +
    Group ID :
    +
    +
    +
    Group Label :
    +
    + + ]]>
    + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    AJXP_MESSAGE[ajxp_conf.95]
    +
    AJXP_MESSAGE[ajxp_conf.96]
    +
    +
    AJXP_MESSAGE[ajxp_conf.8]* :
    +
    AJXP_MESSAGE[ajxp_conf.116]* :
    + +
    +
    +
    AJXP_MESSAGE[ajxp_conf.32]* :
    +
    AJXP_MESSAGE[ajxp_conf.117]* :
    + +
    +
    +
    +
    + + +
    + + ]]>
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    AJXP_MESSAGE[ajxp_conf.83]
    +
    +
    AJXP_MESSAGE[ajxp_conf.71] :
    +
    +
    AJXP_MESSAGE[ajxp_conf.70] :
    +
    +
    +
    + + ]]>
    + + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + + + + + +
    + + + + + + + + + + +
    + +
    + #{name_string} : #{text} + + ]]> +
    + + + + + + +
    + +
    + #{name_string} : #{text} + + ]]> +
    + + + + + +
    + +
    + + ]]> +
    +
    +
    +
    diff --git a/core/src/plugins/access.ajxp_conf/class.ajxp_confAccessDriver.php b/core/src/plugins/access.ajxp_conf/class.ajxp_confAccessDriver.php index 494782c2ac..21f4babbed 100644 --- a/core/src/plugins/access.ajxp_conf/class.ajxp_confAccessDriver.php +++ b/core/src/plugins/access.ajxp_conf/class.ajxp_confAccessDriver.php @@ -1,2237 +1,2245 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * @package AjaXplorer_Plugins - * @subpackage Access - * @class ajxp_confAccessDriver - * AJXP_Plugin to access the configurations data - */ -class ajxp_confAccessDriver extends AbstractAccessDriver -{ - - private $listSpecialRoles = AJXP_SERVER_DEBUG; - private $currentBookmarks = array(); - - function listAllActions($action, $httpVars, $fileVars){ - if(!isSet($this->actions[$action])) return; - parent::accessPreprocess($action, $httpVars, $fileVars); - $loggedUser = AuthService::getLoggedUser(); - if(AuthService::usersEnabled() && !$loggedUser->isAdmin()) return ; - switch($action) - { - //------------------------------------ - // BASIC LISTING - //------------------------------------ - case "list_all_repositories_json": - - $repositories = ConfService::getRepositoriesList("all"); - $repoOut = array(); - foreach($repositories as $repoObject){ - $repoOut[$repoObject->getId()] = $repoObject->getDisplay(); - } - HTMLWriter::charsetHeader("application/json"); - echo json_encode(array("LEGEND" => "Select a repository", "LIST" => $repoOut)); - - break; - - case "list_all_plugins_actions": - $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//action", "node", false, true, true); - $actions = array(); - foreach($nodes as $node){ - $xPath = new DOMXPath($node->ownerDocument); - $proc = $xPath->query("processing", $node); - if(!$proc->length) continue; - $txt = $xPath->query("gui/@text", $node); - if($txt->length){ - $messId = $txt->item(0)->nodeValue; - }else{ - $messId = ""; - } - $parentPlugin = $node->parentNode->parentNode->parentNode; - $pId = $parentPlugin->attributes->getNamedItem("id")->nodeValue; - if(empty($pId)){ - $pId = $parentPlugin->nodeName ."."; - if($pId == "ajxpdriver.") $pId = "access."; - $pId .= $parentPlugin->attributes->getNamedItem("name")->nodeValue; - } - //echo($pId." : ". $node->attributes->getNamedItem("name")->nodeValue . " (".$messId.")
    "); - if(!is_array($actions[$pId])) $actions[$pId] = array(); - $actionName = $node->attributes->getNamedItem("name")->nodeValue; - $actions[$pId][$actionName] = array( "action" => $actionName , "label" => $messId); - - } - foreach($actions as $actPid => $actionGroup){ - ksort($actionGroup, SORT_STRING); - $actions[$actPid] = array(); - foreach($actionGroup as $k => $v){ - $actions[$actPid][] = $v; - } - } - HTMLWriter::charsetHeader("application/json"); - echo json_encode(array("LIST" => $actions, "HAS_GROUPS" => true)); - break; - case "list_all_plugins_parameters": - $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//param|//global_param", "node", false, true, true); - $actions = array(); - foreach($nodes as $node){ - if($node->parentNode->nodeName != "server_settings") continue; - $parentPlugin = $node->parentNode->parentNode; - $pId = $parentPlugin->attributes->getNamedItem("id")->nodeValue; - if(empty($pId)){ - $pId = $parentPlugin->nodeName ."."; - if($pId == "ajxpdriver.") $pId = "access."; - $pId .= $parentPlugin->attributes->getNamedItem("name")->nodeValue; - } - //echo($pId." : ". $node->attributes->getNamedItem("name")->nodeValue . " (".$messId.")
    "); - if(!is_array($actions[$pId])) $actions[$pId] = array(); - $actionName = $node->attributes->getNamedItem("name")->nodeValue; - $messId = $node->attributes->getNamedItem("label")->nodeValue; - $actions[$pId][$actionName] = array( "parameter" => $actionName , "label" => AJXP_XMLWriter::replaceAjxpXmlKeywords($messId)); - - } - foreach($actions as $actPid => $actionGroup){ - ksort($actionGroup, SORT_STRING); - $actions[$actPid] = array(); - foreach($actionGroup as $k => $v){ - $actions[$actPid][] = $v; - } - } - HTMLWriter::charsetHeader("application/json"); - echo json_encode(array("LIST" => $actions, "HAS_GROUPS" => true)); - break; - case "parameters_to_form_definitions" : - - $data = json_decode(AJXP_Utils::decodeSecureMagic($httpVars["json_parameters"]), true); - AJXP_XMLWriter::header("standard_form"); - foreach($data as $repoScope => $pluginsData){ - echo(""); - foreach($pluginsData as $pluginId => $paramData){ - foreach($paramData as $paramId => $paramValue){ - $query = "//param[@name='$paramId']|//global_param[@name='$paramId']"; - $nodes = AJXP_PluginsService::getInstance()->searchAllManifests($query, "node", false, true, true); - if(!count($nodes)) continue; - $n = $nodes[0]; - if($n->attributes->getNamedItem("group") != null){ - $n->attributes->getNamedItem("group")->nodeValue = "$pluginId"; - }else{ - $n->appendChild($n->ownerDocument->createAttribute("group")); - $n->attributes->getNamedItem("group")->nodeValue = "$pluginId"; - } - if(is_bool($paramValue)) $paramValue = ($paramValue ? "true" : "false"); - if($n->attributes->getNamedItem("default") != null){ - $n->attributes->getNamedItem("default")->nodeValue = $paramValue; - }else{ - $n->appendChild($n->ownerDocument->createAttribute("default")); - $n->attributes->getNamedItem("default")->nodeValue = $paramValue; - } - echo(AJXP_XMLWriter::replaceAjxpXmlKeywords($n->ownerDocument->saveXML($n))); - } - } - echo(""); - } - AJXP_XMLWriter::close("standard_form"); - break; - - default: - break; - } - } - - function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($contribNode->nodeName != "actions") return; - $currentUserIsGroupAdmin = (AuthService::getLoggedUser() != null && AuthService::getLoggedUser()->getGroupPath() != "/"); - if(!$currentUserIsGroupAdmin) return; - $actionXpath=new DOMXPath($contribNode->ownerDocument); - $publicUrlNodeList = $actionXpath->query('action[@name="create_repository"]/subMenu', $contribNode); - if($publicUrlNodeList->length){ - $publicUrlNode = $publicUrlNodeList->item(0); - $publicUrlNode->parentNode->removeChild($publicUrlNode); - } - } - - function preProcessBookmarkAction($action, &$httpVars, $fileVars){ - - if(isSet($httpVars["bm_action"]) && $httpVars["bm_action"] == "add_bookmark" && AuthService::usersEnabled()){ - $bmUser = AuthService::getLoggedUser(); - $bookmarks = $bmUser->getBookmarks(); - $found = false; - foreach($bookmarks as $bm){ - if($bm["PATH"] == $httpVars["bm_path"]){ - $httpVars["bm_action"] = "delete_bookmark"; - break; - } - } - } - - } - - function recursiveSearchGroups($baseGroup, $term){ - - $groups = AuthService::listChildrenGroups($baseGroup); - foreach($groups as $groupId => $groupLabel){ - - if(preg_match("/$term/i", $groupLabel) == TRUE ){ - $nodeKey = "/data/users/".trim($baseGroup, "/")."/".ltrim($groupId,"/"); - $meta = array( - "icon" => "users-folder.png", - "ajxp_mime" => "group" - ); - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - echo AJXP_XMLWriter::renderNode($nodeKey, $groupLabel, false, $meta, true, false); - } - $this->recursiveSearchGroups(rtrim($baseGroup, "/")."/".$groupId, $term); - - } - - $users = AuthService::listUsers($baseGroup, $term); - foreach($users as $userId => $userObject){ - - $nodeKey = "/data/users/".trim($userObject->getGroupPath(),"/")."/".$userId; - $meta = array( - "icon" => "user.png", - "ajxp_mime" => "user" - ); - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - echo AJXP_XMLWriter::renderNode($nodeKey, $userId, false, $meta, true, false); - - } - - } - - - function searchAction($action, $httpVars, $fileVars){ - - if(! AJXP_Utils::decodeSecureMagic($httpVars["dir"]) == "/data/users") return; - $query = AJXP_Utils::decodeSecureMagic($httpVars["query"]); - AJXP_XMLWriter::header(); - - $this->recursiveSearchGroups("/", $query); - AJXP_XMLWriter::close(); - - } - - function switchAction($action, $httpVars, $fileVars){ - if(!isSet($this->actions[$action])) return; - parent::accessPreprocess($action, $httpVars, $fileVars); - $loggedUser = AuthService::getLoggedUser(); - if(AuthService::usersEnabled() && !$loggedUser->isAdmin()) return ; - if(AuthService::usersEnabled()){ - $currentBookmarks = AuthService::getLoggedUser()->getBookmarks(); - // FLATTEN - foreach($currentBookmarks as $bm){ - $this->currentBookmarks[] = $bm["PATH"]; - } - } - - if($action == "edit"){ - if(isSet($httpVars["sub_action"])){ - $action = $httpVars["sub_action"]; - } - } - $mess = ConfService::getMessages(); - $currentUserIsGroupAdmin = (AuthService::getLoggedUser() != null && AuthService::getLoggedUser()->getGroupPath() != "/"); - - switch($action) - { - //------------------------------------ - // BASIC LISTING - //------------------------------------ - case "ls": - - $rootNodes = array( - "data" => array( - "LABEL" => $mess["ajxp_conf.110"], - "ICON" => "user.png", - "DESCRIPTION" => "Day-to-day administration of the application : who accesses to what, create roles, etc.", - "CHILDREN" => array( - "repositories" => array( - "LABEL" => $mess["ajxp_conf.3"], - "DESCRIPTION" => "Create and delete workspaces, add features to them using meta sources.", - "ICON" => "hdd_external_unmount.png", - "LIST" => "listRepositories"), - "users" => array( - "LABEL" => $mess["ajxp_conf.2"], - "DESCRIPTION" => "Manage users and groups", - "ICON" => "users-folder.png", - "LIST" => "listUsers" - ), - "roles" => array( - "LABEL" => $mess["ajxp_conf.69"], - "DESCRIPTION" => "Define profiles that can be applied at once to whole bunch of users.", - "ICON" => "user-acl.png", - "LIST" => "listRoles"), - ) - ), - "config" => array( - "LABEL" => $mess["ajxp_conf.109"], - "ICON" => "preferences_desktop.png", - "DESCRIPTION" => "Global configurations of the application core and of each plugin. Enable/disable plugins", - "CHILDREN" => array( - "core" => array( - "LABEL" => $mess["ajxp_conf.98"], - "DESCRIPTION" => "Core application parameters", - "ICON" => "preferences_desktop.png", - "LIST" => "listPlugins"), - "core_plugins" => array( - "LABEL" => "Core Plugins", - "DESCRIPTION" => "Enable/disable core plugins (auth, conf, mail, etc), check if they are correctly working. Configuration of these plugins are generally done through the Main Options", - "ICON" => "folder_development.png", - "LIST" => "listPlugins"), - "plugins" => array( - "LABEL" => $mess["ajxp_conf.99"], - "DESCRIPTION" => "Enable/disable additional feature-oriented plugins, check if they are correctly working, set up global parameters of the plugins.", - "ICON" => "folder_development.png", - "LIST" => "listPlugins") - ) - ), - "admin" => array( - "LABEL" => $mess["ajxp_conf.111"], - "ICON" => "toggle_log.png", - "DESCRIPTION" => "Administrator tasks to monitor the application state.", - "CHILDREN" => array( - "logs" => array( - "LABEL" => $mess["ajxp_conf.4"], - "DESCRIPTION" => "Monitor all activities happening on the server", - "ICON" => "toggle_log.png", - "LIST" => "listLogFiles"), - "files" => array( - "LABEL" => $mess["ajxp_shared.3"], - "DESCRIPTION" => "Monitor all files shared as public links by every users", - "ICON" => "html.png", - "LIST" => "listSharedFiles"), - "diagnostic" => array( - "LABEL" => $mess["ajxp_conf.5"], - "DESCRIPTION" => "Read the start-up diagnostic generated by AjaXplorer", - "ICON" => "susehelpcenter.png", "LIST" => "printDiagnostic") - ) - ), - "developer" => array( - "LABEL" => "Developer Resources", - "ICON" => "applications_engineering.png", - "DESCRIPTION" => "Generated documentations for developers", - "CHILDREN" => array( - "actions" => array( - "LABEL" => "Actions API", - "DESCRIPTION" => "List all actions contributed by all plugins and visualize their input parameters", - "ICON" => "book.png", - "LIST" => "listActions"), - "hooks" => array( - "LABEL" => "Hooks Definitions", - "DESCRIPTION" => "List all hooks triggered in the application, their documentation, where there are triggered and which plugin listen to them.", - "ICON" => "book.png", - "LIST" => "listHooks") - ) - ) - ); - if($currentUserIsGroupAdmin){ - unset($rootNodes["config"]); - unset($rootNodes["admin"]); - unset($rootNodes["developer"]); - } - AJXP_Controller::applyHook("ajxp_conf.list_config_nodes", array(&$rootNodes)); - $dir = trim(AJXP_Utils::decodeSecureMagic((isset($httpVars["dir"])?$httpVars["dir"]:"")), " /"); - if($dir != ""){ - $hash = null; - if(strstr(urldecode($dir), "#") !== false){ - list($dir, $hash) = explode("#", urldecode($dir)); - } - $splits = explode("/", $dir); - $root = array_shift($splits); - if(count($splits)){ - $returnNodes = false; - if(isSet($httpVars["file"])){ - $returnNodes = true; - } - $child = $splits[0]; - if(isSet($rootNodes[$root]["CHILDREN"][$child])){ - $atts = array(); - if($child == "users"){ - $atts["remote_indexation"] = "admin_search"; - } - $callback = $rootNodes[$root]["CHILDREN"][$child]["LIST"]; - if(is_string($callback) && method_exists($this, $callback)){ - if(!$returnNodes) AJXP_XMLWriter::header("tree", $atts); - $res = call_user_func(array($this, $callback), implode("/", $splits), $root, $hash, $returnNodes, isSet($httpVars["file"])?$httpVars["file"]:''); - if(!$returnNodes) AJXP_XMLWriter::close(); - }else if(is_array($callback)){ - $res = call_user_func($callback, implode("/", $splits), $root, $hash, $returnNodes, isSet($httpVars["file"])?$httpVars["file"]:''); - } - if($returnNodes){ - AJXP_XMLWriter::header("tree", $atts); - if(isSet($res["/".$dir."/".$httpVars["file"]])){ - print $res["/".$dir."/".$httpVars["file"]]; - } - AJXP_XMLWriter::close(); - } - return; - } - }else{ - $parentName = "/".$root."/"; - $nodes = $rootNodes[$root]["CHILDREN"]; - } - }else{ - $parentName = "/"; - $nodes = $rootNodes; - } - if(isSet($httpVars["file"])){ - $parentName = $httpVars["dir"]."/"; - $nodes = array(basename($httpVars["file"]) => array("LABEL" => basename($httpVars["file"]))); - } - if(isSet($nodes)){ - AJXP_XMLWriter::header(); - if(!isSet($httpVars["file"])) AJXP_XMLWriter::sendFilesListComponentConfig(''); - foreach ($nodes as $key => $data){ - $bmString = ''; - if(in_array($parentName.$key, $this->currentBookmarks)) $bmString = ' ajxp_bookmarked="true" overlay_icon="bookmark.png" '; - if($key == "users") $bmString .= ' remote_indexation="admin_search"'; - print ''; - } - AJXP_XMLWriter::close(); - - } - - break; - - case "stat" : - - header("Content-type:application/json"); - print '{"mode":true}'; - return; - - break; - - case "create_group": - - if(isSet($httpVars["group_path"])){ - $basePath = AJXP_Utils::forwardSlashDirname($httpVars["group_path"]); - if(empty($basePath)) $basePath = "/"; - $gName = AJXP_Utils::sanitize(AJXP_Utils::decodeSecureMagic(basename($httpVars["group_path"])), AJXP_SANITIZE_ALPHANUM); - }else{ - $basePath = substr($httpVars["dir"], strlen("/data/users")); - $gName = AJXP_Utils::sanitize(SystemTextEncoding::magicDequote($httpVars["group_name"]), AJXP_SANITIZE_ALPHANUM); - } - $gLabel = AJXP_Utils::decodeSecureMagic($httpVars["group_label"]); - AuthService::createGroup($basePath, $gName, $gLabel); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - - break; - - case "create_role": - $roleId = AJXP_Utils::sanitize(SystemTextEncoding::magicDequote($httpVars["role_id"]), AJXP_SANITIZE_HTML_STRICT); - if(!strlen($roleId)){ - throw new Exception($mess[349]); - } - if(AuthService::getRole($roleId) !== false){ - throw new Exception($mess["ajxp_conf.65"]); - } - $r = new AJXP_Role($roleId); - if(AuthService::getLoggedUser()!=null && AuthService::getLoggedUser()->getGroupPath()!=null){ - $r->setGroupPath(AuthService::getLoggedUser()->getGroupPath()); - } - AuthService::updateRole($r); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.66"], null); - AJXP_XMLWriter::reloadDataNode("", $httpVars["role_id"]); - AJXP_XMLWriter::close(); - break; - - case "edit_role" : - $roleId = SystemTextEncoding::magicDequote($httpVars["role_id"]); - $roleGroup = false; - if(strpos($roleId, "AJXP_GRP_") === 0){ - $groupPath = substr($roleId, strlen("AJXP_GRP_")); - $filteredGroupPath = AuthService::filterBaseGroup($groupPath); - $groups = AuthService::listChildrenGroups(AJXP_Utils::forwardSlashDirname($groupPath)); - $key = "/".basename($groupPath); - if(!array_key_exists($key, $groups)){ - throw new Exception("Cannot find group with this id!"); - } - $roleId = "AJXP_GRP_".$filteredGroupPath; - $groupLabel = $groups[$key]; - $roleGroup = true; - } - if(strpos($roleId, "AJXP_USR_") === 0){ - $usrId = str_replace("AJXP_USR_/", "", $roleId); - $userObject = ConfService::getConfStorageImpl()->createUserObject($usrId); - $role = $userObject->personalRole; - }else{ - $role = AuthService::getRole($roleId, $roleGroup); - } - if($role === false) { - throw new Exception("Cant find role! "); - } - if(isSet($httpVars["format"]) && $httpVars["format"] == "json"){ - HTMLWriter::charsetHeader("application/json"); - $roleData = $role->getDataArray(); - $repos = ConfService::getAccessibleRepositories($userObject, true, true, ($userObject == null ? true:false)); - $data = array( - "ROLE" => $roleData, - "ALL" => array( - "REPOSITORIES" => $repos - ) - ); - if(isSet($userObject)){ - $data["USER"] = array(); - $data["USER"]["LOCK"] = $userObject->getLock(); - $data["USER"]["DEFAULT_REPOSITORY"] = $userObject->getPref("force_default_repository"); - $data["USER"]["PROFILE"] = $userObject->getProfile(); - $data["ALL"]["PROFILES"] = array("standard|Standard","admin|Administrator","shared|Shared","guest|Guest"); - $data["USER"]["ROLES"] = array_keys($userObject->getRoles()); - $data["ALL"]["ROLES"] = array_keys(AuthService::getRolesList(array(), true)); - if(isSet($userObject->parentRole)){ - $data["PARENT_ROLE"] = $userObject->parentRole->getDataArray(); - } - }else if(isSet($groupPath)){ - $data["GROUP"] = array("PATH" => $groupPath, "LABEL" => $groupLabel); - } - - $scope = "role"; - if($roleGroup) $scope = "group"; - else if(isSet($userObject)) $scope = "user"; - $data["SCOPE_PARAMS"] = array(); - $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//param[contains(@scope,'".$scope."')]|//global_param[contains(@scope,'".$scope."')]", "node", false, true, true); - foreach($nodes as $node){ - $pId = $node->parentNode->parentNode->attributes->getNamedItem("id")->nodeValue; - $origName = $node->attributes->getNamedItem("name")->nodeValue; - $node->attributes->getNamedItem("name")->nodeValue = "AJXP_REPO_SCOPE_ALL/".$pId."/".$origName; - $nArr = array(); - foreach($node->attributes as $attrib){ - $nArr[$attrib->nodeName] = AJXP_XMLWriter::replaceAjxpXmlKeywords($attrib->nodeValue); - } - $data["SCOPE_PARAMS"][] = $nArr; - } - - echo json_encode($data); - } - break; - - case "post_json_role" : - - $roleId = SystemTextEncoding::magicDequote($httpVars["role_id"]); - $roleGroup = false; - if(strpos($roleId, "AJXP_GRP_") === 0){ - $groupPath = substr($roleId, strlen("AJXP_GRP_")); - $filteredGroupPath = AuthService::filterBaseGroup($groupPath); - $roleId = "AJXP_GRP_".$filteredGroupPath; - $groups = AuthService::listChildrenGroups(AJXP_Utils::forwardSlashDirname($groupPath)); - $key = "/".basename($groupPath); - if(!array_key_exists($key, $groups)){ - throw new Exception("Cannot find group with this id!"); - } - $groupLabel = $groups[$key]; - $roleGroup = true; - } - if(strpos($roleId, "AJXP_USR_") === 0){ - $usrId = str_replace("AJXP_USR_/", "", $roleId); - $userObject = ConfService::getConfStorageImpl()->createUserObject($usrId); - $originalRole = $userObject->personalRole; - }else{ - // second param = create if not exists. - $originalRole = AuthService::getRole($roleId, $roleGroup); - } - if($originalRole === false) { - throw new Exception("Cant find role! "); - } - - $jsonData = AJXP_Utils::decodeSecureMagic($httpVars["json_data"]); - $data = json_decode($jsonData, true); - $roleData = $data["ROLE"]; - $forms = $data["FORMS"]; - $binariesContext = array(); - if(isset($userObject)){ - $binariesContext = array("USER" => $userObject->getId()); - } - foreach($forms as $repoScope => $plugData){ - foreach($plugData as $plugId => $formsData){ - $parsed = array(); - AJXP_Utils::parseStandardFormParameters( - $formsData, - $parsed, - ($userObject!=null?$usrId:null), - "ROLE_PARAM_", - $binariesContext - ); - $roleData["PARAMETERS"][$repoScope][$plugId] = $parsed; - } - } - if(isSet($userObject) && isSet($data["USER"]) && isSet($data["USER"]["PROFILE"])){ - $userObject->setAdmin(($data["USER"]["PROFILE"] == "admin")); - $userObject->setProfile($data["USER"]["PROFILE"]); - } - if(isSet($data["GROUP_LABEL"]) && isSet($groupLabel) && $groupLabel != $data["GROUP_LABEL"]){ - ConfService::getConfStorageImpl()->relabelGroup($filteredGroupPath, $data["GROUP_LABEL"]); - } - - $output = array(); - try{ - $originalRole->bunchUpdate($roleData); - if(isSet($userObject)){ - $userObject->personalRole = $originalRole; - $userObject->save("superuser"); - //AuthService::updateRole($originalRole, $userObject); - }else{ - AuthService::updateRole($originalRole); - } - $output = array("ROLE" => $originalRole->getDataArray(), "SUCCESS" => true); - }catch (Exception $e){ - $output = array("ERROR" => $e->getMessage()); - } - HTMLWriter::charsetHeader("application/json"); - echo(json_encode($output)); - - break; - - - case "user_set_lock" : - - $userId = AJXP_Utils::decodeSecureMagic($httpVars["user_id"]); - $lock = ($httpVars["lock"] == "true" ? true : false); - $lockType = $httpVars["lock_type"]; - if(AuthService::userExists($userId)){ - $userObject = ConfService::getConfStorageImpl()->createUserObject($userId); - if($lock){ - $userObject->setLock($lockType); - }else{ - $userObject->removeLock(); - } - $userObject->save("superuser"); - } - - break; - - case "create_user" : - - if(!isset($httpVars["new_user_login"]) || $httpVars["new_user_login"] == "" ||!isset($httpVars["new_user_pwd"]) || $httpVars["new_user_pwd"] == "") - { - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.61"]); - AJXP_XMLWriter::close(); - return; - } - $new_user_login = AJXP_Utils::sanitize(SystemTextEncoding::magicDequote($httpVars["new_user_login"]), AJXP_SANITIZE_EMAILCHARS); - if(AuthService::userExists($new_user_login, "w") || AuthService::isReservedUserId($new_user_login)) - { - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.43"]); - AJXP_XMLWriter::close(); - return; - } - - AuthService::createUser($new_user_login, $httpVars["new_user_pwd"]); - $confStorage = ConfService::getConfStorageImpl(); - $newUser = $confStorage->createUserObject($new_user_login); - $basePath = AuthService::getLoggedUser()->getGroupPath(); - if(empty ($basePath)) $basePath = "/"; - if(!empty($httpVars["group_path"])){ - $newUser->setGroupPath(rtrim($basePath, "/")."/".ltrim($httpVars["group_path"], "/")); - }else{ - $newUser->setGroupPath($basePath); - } - - $newUser->save("superuser"); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.44"], null); - AJXP_XMLWriter::reloadDataNode("", $new_user_login); - AJXP_XMLWriter::close(); - - break; - - case "change_admin_right" : - $userId = $httpVars["user_id"]; - if(!AuthService::userExists($userId)){ - throw new Exception("Invalid user id!"); - } - $confStorage = ConfService::getConfStorageImpl(); - $user = $confStorage->createUserObject($userId); - $user->setAdmin(($httpVars["right_value"]=="1"?true:false)); - $user->save("superuser"); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.45"].$httpVars["user_id"], null); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - - break; - - case "user_update_right" : - if(!isSet($httpVars["user_id"]) - || !isSet($httpVars["repository_id"]) - || !isSet($httpVars["right"]) - || !AuthService::userExists($httpVars["user_id"])) - { - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.61"]); - print(""); - AJXP_XMLWriter::close(); - return; - } - $confStorage = ConfService::getConfStorageImpl(); - $user = $confStorage->createUserObject($httpVars["user_id"]); - $user->personalRole->setAcl(AJXP_Utils::sanitize($httpVars["repository_id"], AJXP_SANITIZE_ALPHANUM), AJXP_Utils::sanitize($httpVars["right"], AJXP_SANITIZE_ALPHANUM)); - $user->save(); - $loggedUser = AuthService::getLoggedUser(); - if($loggedUser->getId() == $user->getId()){ - AuthService::updateUser($user); - } - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.46"].$httpVars["user_id"], null); - print("canRead($httpVars["repository_id"])."\" write=\"".$user->canWrite($httpVars["repository_id"])."\"/>"); - AJXP_XMLWriter::reloadRepositoryList(); - AJXP_XMLWriter::close(); - return ; - break; - - case "user_update_group": - - $userSelection = new UserSelection(); - $userSelection->initFromHttpVars($httpVars); - $dir = $httpVars["dir"]; - $dest = $httpVars["dest"]; - if(isSet($httpVars["group_path"])){ - // API Case - $groupPath = $httpVars["group_path"]; - }else{ - if(strpos($dir, "/data/users",0)!==0 || strpos($dest, "/data/users",0)!==0){ - break; - } - $groupPath = substr($dest, strlen("/data/users")); - } - - $confStorage = ConfService::getConfStorageImpl(); - - foreach($userSelection->getFiles() as $selectedUser){ - $userId = basename($selectedUser); - if(!AuthService::userExists($userId)){ - continue; - } - $user = $confStorage->createUserObject($userId); - $basePath = (AuthService::getLoggedUser()!=null ? AuthService::getLoggedUser()->getGroupPath(): "/"); - if(empty ($basePath)) $basePath = "/"; - if(!empty($groupPath)){ - $user->setGroupPath(rtrim($basePath, "/")."/".ltrim($groupPath, "/"), true); - }else{ - $user->setGroupPath($basePath, true); - } - $user->save("superuser"); - } - AJXP_XMLWriter::header(); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::reloadDataNode($dest, $userId); - AJXP_XMLWriter::close(); - - break; - - case "user_add_role" : - case "user_delete_role": - - if(!isSet($httpVars["user_id"]) || !isSet($httpVars["role_id"]) || !AuthService::userExists($httpVars["user_id"]) || !AuthService::getRole($httpVars["role_id"])){ - throw new Exception($mess["ajxp_conf.61"]); - } - if($action == "user_add_role"){ - $act = "add"; - $messId = "73"; - }else{ - $act = "remove"; - $messId = "74"; - } - $this->updateUserRole($httpVars["user_id"], $httpVars["role_id"], $act); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.".$messId].$httpVars["user_id"], null); - AJXP_XMLWriter::close(); - return ; - - break; - - case "user_update_role" : - - $confStorage = ConfService::getConfStorageImpl(); - $selection = new UserSelection(); - $selection->initFromHttpVars($httpVars); - $files = $selection->getFiles(); - $detectedRoles = array(); - - if(isSet($httpVars["role_id"]) && isset($httpVars["update_role_action"])){ - $update = $httpVars["update_role_action"]; - $roleId = $httpVars["role_id"]; - if(AuthService::getRole($roleId) === false){ - throw new Exception("Invalid role id"); - } - } - foreach ($files as $index => $file){ - $userId = basename($file); - if(isSet($update)){ - $userObject = $this->updateUserRole($userId, $roleId, $update); - }else{ - $userObject = $confStorage->createUserObject($userId); - } - if($userObject->hasParent()){ - unset($files[$index]); - continue; - } - $userRoles = $userObject->getRoles(); - foreach ($userRoles as $roleIndex => $bool){ - if(!isSet($detectedRoles[$roleIndex])) $detectedRoles[$roleIndex] = 0; - if($bool === true) $detectedRoles[$roleIndex] ++; - } - } - $count = count($files); - AJXP_XMLWriter::header("admin_data"); - print(""); - foreach ($detectedRoles as $roleId => $roleCount){ - if($roleCount < $count) continue; - print(""); - } - print(""); - print(""); - foreach (AuthService::getRolesList(array(), !$this->listSpecialRoles) as $roleId => $roleObject){ - print(""); - } - print(""); - AJXP_XMLWriter::close("admin_data"); - - break; - - case "save_custom_user_params" : - $userId = $httpVars["user_id"]; - if($userId == $loggedUser->getId()){ - $user = $loggedUser; - }else{ - $confStorage = ConfService::getConfStorageImpl(); - $user = $confStorage->createUserObject($userId); - } - $custom = $user->getPref("CUSTOM_PARAMS"); - if(!is_array($custom)) $custom = array(); - - $options = $custom; - $this->parseParameters($httpVars, $options, $userId); - $custom = $options; - $user->setPref("CUSTOM_PARAMS", $custom); - $user->save(); - - if($loggedUser->getId() == $user->getId()){ - AuthService::updateUser($user); - } - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.47"].$httpVars["user_id"], null); - AJXP_XMLWriter::close(); - - break; - - case "save_repository_user_params" : - $userId = $httpVars["user_id"]; - if($userId == $loggedUser->getId()){ - $user = $loggedUser; - }else{ - $confStorage = ConfService::getConfStorageImpl(); - $user = $confStorage->createUserObject($userId); - } - $wallet = $user->getPref("AJXP_WALLET"); - if(!is_array($wallet)) $wallet = array(); - $repoID = $httpVars["repository_id"]; - if(!array_key_exists($repoID, $wallet)){ - $wallet[$repoID] = array(); - } - $options = $wallet[$repoID]; - $this->parseParameters($httpVars, $options, $userId); - $wallet[$repoID] = $options; - $user->setPref("AJXP_WALLET", $wallet); - $user->save(); - - if($loggedUser->getId() == $user->getId()){ - AuthService::updateUser($user); - } - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.47"].$httpVars["user_id"], null); - AJXP_XMLWriter::close(); - - break; - - case "update_user_pwd" : - if(!isSet($httpVars["user_id"]) || !isSet($httpVars["user_pwd"]) || !AuthService::userExists($httpVars["user_id"]) || trim($httpVars["user_pwd"]) == "") - { - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.61"]); - AJXP_XMLWriter::close(); - return; - } - $res = AuthService::updatePassword($httpVars["user_id"], $httpVars["user_pwd"]); - AJXP_XMLWriter::header(); - if($res === true) - { - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.48"].$httpVars["user_id"], null); - } - else - { - AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.49"]." : $res"); - } - AJXP_XMLWriter::close(); - - break; - - case "save_user_preference": - - if(!isSet($httpVars["user_id"]) || !AuthService::userExists($httpVars["user_id"]) ){ - throw new Exception($mess["ajxp_conf.61"]); - } - $userId = $httpVars["user_id"]; - if($userId == $loggedUser->getId()){ - $userObject = $loggedUser; - }else{ - $confStorage = ConfService::getConfStorageImpl(); - $userObject = $confStorage->createUserObject($userId); - } - $i = 0; - while(isSet($httpVars["pref_name_".$i]) && isSet($httpVars["pref_value_".$i])) - { - $prefName = AJXP_Utils::sanitize($httpVars["pref_name_".$i], AJXP_SANITIZE_ALPHANUM); - $prefValue = AJXP_Utils::sanitize(SystemTextEncoding::magicDequote(($httpVars["pref_value_".$i]))); - if($prefName == "password") continue; - if($prefName != "pending_folder" && $userObject == null){ - $i++; - continue; - } - $userObject->setPref($prefName, $prefValue); - $userObject->save("user"); - $i++; - } - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage("Succesfully saved user preference", null); - AJXP_XMLWriter::close(); - - break; - - case "get_drivers_definition": - - AJXP_XMLWriter::header("drivers", array("allowed" => $currentUserIsGroupAdmin ? "false" : "true")); - print(AJXP_XMLWriter::replaceAjxpXmlKeywords(ConfService::availableDriversToXML("param", "", true))); - AJXP_XMLWriter::close("drivers"); - - - break; - - case "get_templates_definition": - - AJXP_XMLWriter::header("repository_templates"); - $repositories = ConfService::getRepositoriesList("all"); - foreach ($repositories as $repo){ - if(!$repo->isTemplate) continue; - $repoId = $repo->getId(); - $repoLabel = $repo->getDisplay(); - $repoType = $repo->getAccessType(); - print(""); - } - AJXP_XMLWriter::close("repository_templates"); - - - break; - - case "create_repository" : - - $repDef = $httpVars; - $isTemplate = isSet($httpVars["sf_checkboxes_active"]); - unset($repDef["get_action"]); - unset($repDef["sf_checkboxes_active"]); - if(isSet($httpVars["json_data"])){ - $options = json_decode($httpVars["json_data"], true); - }else{ - $options = array(); - $this->parseParameters($repDef, $options, null, true); - } - if(count($options)){ - $repDef["DRIVER_OPTIONS"] = $options; - unset($repDef["DRIVER_OPTIONS"]["AJXP_GROUP_PATH_PARAMETER"]); - } - if(strstr($repDef["DRIVER"], "ajxp_template_") !== false){ - $templateId = substr($repDef["DRIVER"], 14); - $templateRepo = ConfService::getRepositoryById($templateId); - $newRep = $templateRepo->createTemplateChild($repDef["DISPLAY"], $repDef["DRIVER_OPTIONS"]); - }else{ - if($currentUserIsGroupAdmin){ - throw new Exception("You are not allowed to create a repository from a driver. Use a template instead."); - } - $pServ = AJXP_PluginsService::getInstance(); - $driver = $pServ->getPluginByTypeName("access", $repDef["DRIVER"]); - - $newRep = ConfService::createRepositoryFromArray(0, $repDef); - $testFile = $driver->getBaseDir()."/test.".$newRep->getAccessType()."Access.php"; - if(!$isTemplate && is_file($testFile)) - { - //chdir(AJXP_TESTS_FOLDER."/plugins"); - $className = $newRep->getAccessType()."AccessTest"; - if (!class_exists($className)) - include($testFile); - $class = new $className(); - $result = $class->doRepositoryTest($newRep); - if(!$result){ - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, $class->failedInfo); - AJXP_XMLWriter::close(); - return; - } - } - // Apply default metasource if any - if($driver != null && $driver->getConfigs()!=null ){ - $confs = $driver->getConfigs(); - if(!empty($confs["DEFAULT_METASOURCES"])){ - $metaIds = AJXP_Utils::parseCSL($confs["DEFAULT_METASOURCES"]); - $metaSourceOptions = array(); - foreach($metaIds as $metaID){ - $metaPlug = $pServ->getPluginById($metaID); - if($metaPlug == null) continue; - $pNodes = $metaPlug->getManifestRawContent("//param[@default]", "nodes"); - $defaultParams = array(); - foreach($pNodes as $domNode){ - $defaultParams[$domNode->getAttribute("name")] = $domNode->getAttribute("default"); - } - $metaSourceOptions[$metaID] = $defaultParams; - } - $newRep->addOption("META_SOURCES", $metaSourceOptions); - } - } - } - - if ($this->repositoryExists($newRep->getDisplay())) - { - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.50"]); - AJXP_XMLWriter::close(); - return; - } - if($isTemplate){ - $newRep->isTemplate = true; - } - if($currentUserIsGroupAdmin){ - $newRep->setGroupPath(AuthService::getLoggedUser()->getGroupPath()); - }else if(!empty($options["AJXP_GROUP_PATH_PARAMETER"])){ - $basePath = "/"; - if(AuthService::getLoggedUser()!=null && AuthService::getLoggedUser()->getGroupPath()!=null){ - $basePath = AuthService::getLoggedUser()->getGroupPath(); - } - $value = AJXP_Utils::securePath(rtrim($basePath, "/")."/".ltrim($options["AJXP_GROUP_PATH_PARAMETER"], "/")); - $newRep->setGroupPath($value); - } - - $res = ConfService::addRepository($newRep); - AJXP_XMLWriter::header(); - if($res == -1){ - AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.51"]); - }else{ - $loggedUser = AuthService::getLoggedUser(); - $loggedUser->personalRole->setAcl($newRep->getUniqueId(), "rw"); - $loggedUser->recomputeMergedRole(); - $loggedUser->save("superuser"); - AuthService::updateUser($loggedUser); - - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.52"], null); - AJXP_XMLWriter::reloadDataNode("", $newRep->getUniqueId()); - AJXP_XMLWriter::reloadRepositoryList(); - } - AJXP_XMLWriter::close(); - - - - break; - - case "edit_repository" : - $repId = $httpVars["repository_id"]; - $repository = ConfService::getRepositoryById($repId); - if($repository == null){ - throw new Exception("Cannot find repository with id $repId"); - } - if(!AuthService::canAdministrate($repository)){ - throw new Exception("You are not allowed to edit this repository!"); - } - $pServ = AJXP_PluginsService::getInstance(); - $plug = $pServ->getPluginById("access.".$repository->accessType); - if($plug == null){ - throw new Exception("Cannot find access driver (".$repository->accessType.") for repository!"); - } - AJXP_XMLWriter::header("admin_data"); - $slug = $repository->getSlug(); - if($slug == "" && $repository->isWriteable()){ - $repository->setSlug(); - ConfService::replaceRepository($repId, $repository); - } - if(AuthService::getLoggedUser()!=null && AuthService::getLoggedUser()->getGroupPath() != null){ - $rgp = $repository->getGroupPath(); - if($rgp == null) $rgp = "/"; - if(strlen($rgp) < strlen(AuthService::getLoggedUser()->getGroupPath())) { - $repository->setWriteable(false); - } - } - $nested = array(); - print(" $option){ - if(strstr($name, " ")>-1) continue; - if(!is_array($option)){ - if(is_bool($option)){ - $option = ($option?"true":"false"); - } - print(" $name=\"".SystemTextEncoding::toUTF8(AJXP_Utils::xmlEntities($option))."\" "); - }else if(is_array($option)){ - $nested[] = $option; - } - } - if(count($nested)){ - print(">"); - foreach ($nested as $option){ - foreach ($option as $key => $optValue){ - if(is_array($optValue) && count($optValue)){ - print(""); - }else{ - if(is_bool($optValue)){ - $optValue = ($optValue?"true":"false"); - } - $optValue = AJXP_Utils::xmlEntities($optValue, true); - print(""); - } - } - } - // Add SLUG - if(!$repository->isTemplate) print("getSlug()."\"/>"); - if($repository->getGroupPath() != null) { - $basePath = "/"; - if(AuthService::getLoggedUser()!=null && AuthService::getLoggedUser()->getGroupPath()!=null){ - $basePath = AuthService::getLoggedUser()->getGroupPath(); - } - $groupPath = $repository->getGroupPath(); - if($basePath != "/") $groupPath = substr($repository->getGroupPath(), strlen($basePath)); - print(""); - } - - print(""); - }else{ - print("/>"); - } - if($repository->hasParent()){ - $parent = ConfService::getRepositoryById($repository->getParentId()); - if(isSet($parent) && $parent->isTemplate){ - $parentLabel = $parent->getDisplay(); - $parentType = $parent->getAccessType(); - print(""); - } - } - $manifest = $plug->getManifestRawContent("server_settings/param"); - $manifest = AJXP_XMLWriter::replaceAjxpXmlKeywords($manifest); - print("accessType."\">$manifest"); - print(""); - $metas = $pServ->getPluginsByType("metastore"); - $metas = array_merge($metas, $pServ->getPluginsByType("meta")); - $metas = array_merge($metas, $pServ->getPluginsByType("index")); - foreach ($metas as $metaPlug){ - print("getId()."\" label=\"".AJXP_Utils::xmlEntities($metaPlug->getManifestLabel())."\">"); - $manifest = $metaPlug->getManifestRawContent("server_settings/param"); - $manifest = AJXP_XMLWriter::replaceAjxpXmlKeywords($manifest); - print($manifest); - print(""); - } - print(""); - AJXP_XMLWriter::close("admin_data"); - return ; - break; - - case "edit_repository_label" : - case "edit_repository_data" : - $repId = $httpVars["repository_id"]; - $repo = ConfService::getRepositoryById($repId); - $res = 0; - if(isSet($httpVars["newLabel"])){ - $newLabel = AJXP_Utils::decodeSecureMagic($httpVars["newLabel"]); - if ($this->repositoryExists($newLabel)) - { - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.50"]); - AJXP_XMLWriter::close(); - return; - } - $repo->setDisplay($newLabel); - $res = ConfService::replaceRepository($repId, $repo); - }else{ - $options = array(); - $this->parseParameters($httpVars, $options, null, true); - if(count($options)){ - foreach ($options as $key=>$value) { - if($key == "AJXP_SLUG"){ - $repo->setSlug($value); - continue; - }elseif($key == "AJXP_GROUP_PATH_PARAMETER"){ - $basePath = "/"; - if(AuthService::getLoggedUser()!=null && AuthService::getLoggedUser()->getGroupPath()!=null){ - $basePath = AuthService::getLoggedUser()->getGroupPath(); - } - $value = AJXP_Utils::securePath(rtrim($basePath, "/")."/".ltrim($value, "/")); - $repo->setGroupPath($value); - continue; - } - $repo->addOption($key, $value); - } - } - if($repo->getOption("DEFAULT_RIGHTS")){ - $gp = $repo->getGroupPath(); - if(empty($gp) || $gp == "/"){ - $defRole = AuthService::getRole("ROOT_ROLE"); - }else{ - $defRole = AuthService::getRole("AJXP_GRP_".$gp, true); - } - if($defRole !== false){ - $defRole->setAcl($repId, $repo->getOption("DEFAULT_RIGHTS")); - AuthService::updateRole($defRole); - } - } - if(is_file(AJXP_TESTS_FOLDER."/plugins/test.ajxp_".$repo->getAccessType().".php")){ - chdir(AJXP_TESTS_FOLDER."/plugins"); - include(AJXP_TESTS_FOLDER."/plugins/test.ajxp_".$repo->getAccessType().".php"); - $className = "ajxp_".$repo->getAccessType(); - $class = new $className(); - $result = $class->doRepositoryTest($repo); - if(!$result){ - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, $class->failedInfo); - AJXP_XMLWriter::close(); - return; - } - } - - ConfService::replaceRepository($repId, $repo); - } - AJXP_XMLWriter::header(); - if($res == -1){ - AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.53"]); - }else{ - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.54"], null); - AJXP_XMLWriter::reloadDataNode("", (isSet($httpVars["newLabel"])?$repId:false)); - AJXP_XMLWriter::reloadRepositoryList(); - } - AJXP_XMLWriter::close(); - - break; - - case "meta_source_add" : - $repId = $httpVars["repository_id"]; - $repo = ConfService::getRepositoryById($repId); - if(!is_object($repo)){ - throw new Exception("Invalid repository id! $repId"); - } - $metaSourceType = AJXP_Utils::sanitize($httpVars["new_meta_source"], AJXP_SANITIZE_ALPHANUM); - if(isSet($httpVars["json_data"])){ - $options = json_decode($httpVars["json_data"], true); - }else{ - $options = array(); - $this->parseParameters($httpVars, $options, null, true); - } - $repoOptions = $repo->getOption("META_SOURCES"); - if(is_array($repoOptions) && isSet($repoOptions[$metaSourceType])){ - throw new Exception($mess["ajxp_conf.55"]); - } - if(!is_array($repoOptions)){ - $repoOptions = array(); - } - $repoOptions[$metaSourceType] = $options; - uksort($repoOptions, array($this,"metaSourceOrderingFunction")); - $repo->addOption("META_SOURCES", $repoOptions); - ConfService::replaceRepository($repId, $repo); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.56"],null); - AJXP_XMLWriter::close(); - break; - - case "meta_source_delete" : - - $repId = $httpVars["repository_id"]; - $repo = ConfService::getRepositoryById($repId); - if(!is_object($repo)){ - throw new Exception("Invalid repository id! $repId"); - } - $metaSourceId = $httpVars["plugId"]; - $repoOptions = $repo->getOption("META_SOURCES"); - if(is_array($repoOptions) && array_key_exists($metaSourceId, $repoOptions)){ - unset($repoOptions[$metaSourceId]); - uksort($repoOptions, array($this,"metaSourceOrderingFunction")); - $repo->addOption("META_SOURCES", $repoOptions); - ConfService::replaceRepository($repId, $repo); - } - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.57"],null); - AJXP_XMLWriter::close(); - - break; - - case "meta_source_edit" : - $repId = $httpVars["repository_id"]; - $repo = ConfService::getRepositoryById($repId); - if(!is_object($repo)){ - throw new Exception("Invalid repository id! $repId"); - } - $metaSourceId = $httpVars["plugId"]; - $repoOptions = $repo->getOption("META_SOURCES"); - if(!is_array($repoOptions)){ - $repoOptions = array(); - } - if(isSet($httpVars["json_data"])){ - $options = json_decode($httpVars["json_data"], true); - }else{ - $options = array(); - $this->parseParameters($httpVars, $options, null, true); - } - $repoOptions[$metaSourceId] = $options; - uksort($repoOptions, array($this,"metaSourceOrderingFunction")); - $repo->addOption("META_SOURCES", $repoOptions); - ConfService::replaceRepository($repId, $repo); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.58"],null); - AJXP_XMLWriter::close(); - break; - - - case "delete" : - // REST API mapping - if(isSet($httpVars["data_type"])){ - switch($httpVars["data_type"]){ - case "repository": - $httpVars["repository_id"] = basename($httpVars["data_id"]); - break; - case "shared_file": - $httpVars["shared_file"] = basename($httpVars["data_id"]); - break; - case "role": - $httpVars["role_id"] = basename($httpVars["data_id"]); - break; - case "user": - $httpVars["user_id"] = basename($httpVars["data_id"]); - break; - case "group": - $httpVars["group"] = "/data/users".$httpVars["data_id"]; - break; - default: - break; - } - unset($httpVars["data_type"]); - unset($httpVars["data_id"]); - } - if(isSet($httpVars["repository_id"])){ - $repId = $httpVars["repository_id"]; - $res = ConfService::deleteRepository($repId); - AJXP_XMLWriter::header(); - if($res == -1){ - AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.51"]); - }else{ - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.59"], null); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::reloadRepositoryList(); - } - AJXP_XMLWriter::close(); - return; - }else if(isSet($httpVars["shared_file"])){ - AJXP_XMLWriter::header(); - $element = basename($httpVars["shared_file"]); - $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); - $publicletData = $this->loadPublicletData($dlFolder."/".$element.".php"); - unlink($dlFolder."/".$element.".php"); - AJXP_XMLWriter::sendMessage($mess["ajxp_shared.13"], null); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - }else if(isSet($httpVars["role_id"])){ - $roleId = $httpVars["role_id"]; - if(AuthService::getRole($roleId) === false){ - throw new Exception($mess["ajxp_conf.67"]); - } - AuthService::deleteRole($roleId); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.68"], null); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - }else if(isSet($httpVars["group"])){ - $groupPath = $httpVars["group"]; - $basePath = substr(AJXP_Utils::forwardSlashDirname($groupPath), strlen("/data/users")); - $gName = basename($groupPath); - AuthService::deleteGroup($basePath, $gName); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - }else{ - if(!isset($httpVars["user_id"]) || $httpVars["user_id"]=="" - || AuthService::isReservedUserId($httpVars["user_id"]) - || $loggedUser->getId() == $httpVars["user_id"]) - { - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.61"]); - AJXP_XMLWriter::close(); - } - $res = AuthService::deleteUser($httpVars["user_id"]); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.60"], null); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - - } - break; - - case "clear_expired" : - - $deleted = $this->clearExpiredFiles(); - AJXP_XMLWriter::header(); - if(count($deleted)){ - AJXP_XMLWriter::sendMessage(sprintf($mess["ajxp_shared.23"], count($deleted).""), null); - AJXP_XMLWriter::reloadDataNode(); - }else{ - AJXP_XMLWriter::sendMessage($mess["ajxp_shared.24"], null); - } - AJXP_XMLWriter::close(); - - break; - - case "get_plugin_manifest" : - - $ajxpPlugin = AJXP_PluginsService::getInstance()->getPluginById($httpVars["plugin_id"]); - AJXP_XMLWriter::header("admin_data"); - - $fullManifest = $ajxpPlugin->getManifestRawContent("", "xml"); - $xPath = new DOMXPath($fullManifest->ownerDocument); - $addParams = ""; - $pInstNodes = $xPath->query("server_settings/global_param[contains(@type, 'plugin_instance:')]"); - foreach($pInstNodes as $pInstNode){ - $type = $pInstNode->getAttribute("type"); - $instType = str_replace("plugin_instance:", "", $type); - $fieldName = $pInstNode->getAttribute("name"); - $pInstNode->setAttribute("type", "group_switch:".$fieldName); - $typePlugs = AJXP_PluginsService::getInstance()->getPluginsByType($instType); - foreach($typePlugs as $typePlug){ - if($typePlug->getId() == "auth.multi") continue; - $checkErrorMessage = ""; - try{ - $typePlug->performChecks(); - }catch (Exception $e){ - $checkErrorMessage = " (Warning : ".$e->getMessage().")"; - } - $tParams = AJXP_XMLWriter::replaceAjxpXmlKeywords($typePlug->getManifestRawContent("server_settings/param[not(@group_switch_name)]")); - $addParams .= ''; - $addParams .= str_replace("getManifestLabel().$checkErrorMessage."\" group_switch_value=\"".$typePlug->getId()."\" ", $tParams); - $addParams .= str_replace("getManifestRawContent("server_settings/param[@group_switch_name]"))); - $addParams .= AJXP_XMLWriter::replaceAjxpXmlKeywords($typePlug->getManifestRawContent("server_settings/global_param")); - } - } - $allParams = AJXP_XMLWriter::replaceAjxpXmlKeywords($fullManifest->ownerDocument->saveXML($fullManifest)); - $allParams = str_replace('type="plugin_instance:', 'type="group_switch:', $allParams); - $allParams = str_replace("", $addParams."", $allParams); - - echo($allParams); - $definitions = $ajxpPlugin->getConfigsDefinitions(); - $values = $ajxpPlugin->getConfigs(); - if(!is_array($values)) $values = array(); - echo(""); - foreach($values as $key => $value){ - $attribute = true; - $type = $definitions[$key]["type"]; - if($type == "array" && is_array($value)){ - $value = implode(",", $value); - }else if((strpos($type, "group_switch:") === 0 || strpos($type, "plugin_instance:") === 0 ) && is_array($value)){ - $res = array(); - $this->flattenKeyValues($res, $value, $key); - foreach($res as $newKey => $newVal){ - echo(""); - } - continue; - }else if($type == "boolean"){ - $value = ($value === true || $value === "true" || $value == 1?"true":"false"); - }else if($type == "textarea"){ - $attribute = false; - } - if($attribute){ - echo(""); - }else{ - echo(""); - } - } - if($ajxpPlugin->getType() != "core"){ - echo("isEnabled()?"true":"false")."\"/>"); - } - echo(""); - echo("".$ajxpPlugin->getPluginInformationHTML("Charles du Jeu", "http://ajaxplorer.info/plugins/")."

    "); - if(file_exists($ajxpPlugin->getBaseDir()."/plugin_doc.html")){ - echo(file_get_contents($ajxpPlugin->getBaseDir()."/plugin_doc.html")); - } - echo("]]>
    "); - AJXP_XMLWriter::close("admin_data"); - - break; - - case "run_plugin_action": - - $options = array(); - $this->parseParameters($httpVars, $options, null, true); - $pluginId = $httpVars["action_plugin_id"]; - if(isSet($httpVars["button_key"])){ - $options = $options[$httpVars["button_key"]]; - } - $plugin = AJXP_PluginsService::getInstance()->softLoad($pluginId, $options); - if(method_exists($plugin, $httpVars["action_plugin_method"])){ - try{ - $res = call_user_func(array($plugin, $httpVars["action_plugin_method"]), $options); - }catch (Exception $e){ - echo("ERROR:" . $e->getMessage()); - break; - } - echo($res); - }else{ - echo 'ERROR: Plugin '.$httpVars["action_plugin_id"].' does not implement '.$httpVars["action_plugin_method"].' method!'; - } - - break; - - case "edit_plugin_options": - - $options = array(); - $this->parseParameters($httpVars, $options, null, true); - $confStorage = ConfService::getConfStorageImpl(); - $confStorage->savePluginConfig($httpVars["plugin_id"], $options); - @unlink(AJXP_PLUGINS_CACHE_FILE); - @unlink(AJXP_PLUGINS_REQUIRES_FILE); - @unlink(AJXP_PLUGINS_MESSAGES_FILE); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["ajxp_conf.97"], null); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - - - break; - - default: - break; - } - - return; - } - - - function listPlugins($dir, $root = NULL, $hash = null, $returnNodes = false){ - $dir = "/$dir"; - $allNodes = array(); - AJXP_Logger::logAction("Listing plugins"); // make sure that the logger is started! - $pServ = AJXP_PluginsService::getInstance(); - $types = $pServ->getDetectedPlugins(); - $uniqTypes = array("core"); - $coreTypes = array("auth", "conf", "boot", "feed", "log", "mailer", "mq"); - if($dir == "/plugins" || $dir == "/core_plugins"){ - if($dir == "/core_plugins") $uniqTypes = $coreTypes; - else $uniqTypes = array_diff(array_keys($types), $coreTypes); - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' - - '); - ksort($types); - foreach( $types as $t => $tPlugs){ - if(!in_array($t, $uniqTypes))continue; - $nodeKey = "/".$root.$dir."/".$t; - $meta = array( - "icon" => "folder_development.png", - "plugin_id" => $t - ); - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - $xml = AJXP_XMLWriter::renderNode($nodeKey, ucfirst($t), false, $meta, true, false); - if($returnNodes) $allNodes[$nodeKey] = $xml; - else print($xml); - } - }else if($dir == "/core"){ - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' - - - - '); - $mess = ConfService::getMessages(); - $all = $first = ""; - foreach($uniqTypes as $type){ - if(!isset($types[$type])) continue; - foreach($types[$type] as $pId => $pObject){ - $isMain = ($pObject->getId() == "core.ajaxplorer"); - $meta = array( - "icon" => ($isMain?"preferences_desktop.png":"desktop.png"), - "ajxp_mime" => "ajxp_plugin", - "plugin_id" => $pObject->getId(), - "plugin_description" => $pObject->getManifestDescription() - ); - // Check if there are actually any parameters to display! - if($pObject->getManifestRawContent("server_settings", "xml")->length == 0) continue; - $label = $pObject->getManifestLabel(); - $nodeKey = "/$root".$dir."/".$pObject->getId(); - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - $nodeString =AJXP_XMLWriter::renderNode($nodeKey, $label, true, $meta, true, false); - if($returnNodes) $allNodes[$nodeKey] = $nodeString; - if($isMain){ - $first = $nodeString; - }else{ - $all .= $nodeString; - } - } - } - if(!$returnNodes) print($first.$all); - }else{ - $split = explode("/", $dir); - if(empty($split[0])) array_shift($split); - $type = $split[1]; - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' - - - - - - '); - $mess = ConfService::getMessages(); - foreach($types[$type] as $pId => $pObject){ - $errors = "OK"; - try{ - $pObject->performChecks(); - }catch(Exception $e){ - $errors = "ERROR : ".$e->getMessage(); - } - $meta = array( - "icon" => "preferences_plugin.png", - "ajxp_mime" => "ajxp_plugin", - "can_active" => $errors, - "enabled" => ($pObject->isEnabled()?$mess[440]:$mess[441]), - "plugin_id" => $pObject->getId(), - "plugin_description" => $pObject->getManifestDescription() - ); - $nodeKey = "/$root".$dir."/".$pObject->getId(); - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - $xml = AJXP_XMLWriter::renderNode($nodeKey, $pObject->getManifestLabel(), true, $meta, true, false); - if($returnNodes) $allNodes[$nodeKey] = $xml; - else print $xml; - } - } - return $allNodes; - } - - function listUsers($root, $child, $hashValue = null, $returnNodes = false, $findNodePosition=null){ - - $USER_PER_PAGE = 50; - if($root == "users") $baseGroup = "/"; - else $baseGroup = substr($root, strlen("users")); - - if($findNodePosition != null && $hashValue == null){ - - // Loop on each page to find the correct page. - $count = AuthService::authCountUsers($baseGroup); - $pages = ceil($count / $USER_PER_PAGE); - for($i = 0; $i < $pages ; $i ++){ - - $tests = $this->listUsers($root, $child, $i+1, true, $findNodePosition); - if(is_array($tests) && isSet($tests["/data/".$root."/".$findNodePosition])){ - return array("/data/".$root."/".$findNodePosition => str_replace("ajxp_mime", "page_position='".($i+1)."' ajxp_mime", $tests["/data/".$root."/".$findNodePosition])); - } - - } - - return array(); - - } - - $allNodes = array(); - $columns = ' - - - - - '; - if(AuthService::driverSupportsAuthSchemes()){ - $columns = ' - - - - - - '; - } - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig($columns); - if(!AuthService::usersEnabled()) return ; - if(empty($hashValue)) $hashValue = 1; - - $count = AuthService::authCountUsers($baseGroup); - if(AuthService::authSupportsPagination() && $count >= $USER_PER_PAGE){ - $offset = ($hashValue - 1) * $USER_PER_PAGE; - if(!$returnNodes) AJXP_XMLWriter::renderPaginationData($count, $hashValue, ceil($count/$USER_PER_PAGE)); - $users = AuthService::listUsers($baseGroup, "", $offset, $USER_PER_PAGE); - if($hashValue == 1){ - $groups = AuthService::listChildrenGroups($baseGroup); - }else{ - $groups = array(); - } - }else{ - $users = AuthService::listUsers($baseGroup); - $groups = AuthService::listChildrenGroups($baseGroup); - } - foreach($groups as $groupId => $groupLabel){ - - $nodeKey = "/data/".$root."/".ltrim($groupId,"/"); - $meta = array( - "icon" => "users-folder.png", - "ajxp_mime" => "group" - ); - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - $xml = AJXP_XMLWriter::renderNode($nodeKey, - $groupLabel, false, $meta, true, false); - if(!$returnNodes) print($xml); - else $allNodes[$nodeKey] = $xml; - - } - $mess = ConfService::getMessages(); - $repos = ConfService::getRepositoriesList("all"); - $loggedUser = AuthService::getLoggedUser(); - $userArray = array(); - foreach ($users as $userIndex => $userObject){ - $label = $userObject->getId(); - if($userObject->hasParent()){ - $label = $userObject->getParent()."000".$label; - } - $userArray[$label] = $userObject; - } - ksort($userArray); - foreach($userArray as $userObject) { - $isAdmin = $userObject->isAdmin(); - $userId = $userObject->getId(); - $icon = "user".($userId=="guest"?"_guest":($isAdmin?"_admin":"")); - if($userObject->hasParent()){ - $icon = "user_child"; - } - $rightsString = ""; - if($isAdmin) { - $rightsString = $mess["ajxp_conf.63"]; - }else{ - $r = array(); - foreach ($repos as $repoId => $repository){ - if($repository->getAccessType() == "ajxp_shared") continue; - if(!$userObject->canRead($repoId) && !$userObject->canWrite($repoId)) continue; - $rs = ($userObject->canRead($repoId) ? "r" : ""); - $rs .= ($userObject->canWrite($repoId) ? "w" : ""); - $r[] = $repository->getDisplay()." (".$rs.")"; - } - $rightsString = implode(", ", $r); - } - $nodeLabel = $userId; - $test = $userObject->personalRole->filterParameterValue("core.conf", "USER_DISPLAY_NAME", AJXP_REPO_SCOPE_ALL, ""); - if(!empty($test)) $nodeLabel = $test; - $scheme = AuthService::getAuthScheme($userId); - $nodeKey = "/data/$root/".$userId; - $meta = array( - "isAdmin" => $mess[($isAdmin?"ajxp_conf.14":"ajxp_conf.15")], - "icon" => $icon.".png", - "auth_scheme" => ($scheme != null? $scheme : ""), - "rights_summary" => $rightsString, - "ajxp_roles" => implode(", ", array_keys($userObject->getRoles())), - "ajxp_mime" => "user".(($userId!="guest"&&$userId!=$loggedUser->getId())?"_editable":"") - ); - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - $xml = AJXP_XMLWriter::renderNode($nodeKey, $nodeLabel, true, $meta, true, false); - if(!$returnNodes) print($xml); - else $allNodes[$nodeKey] = $xml; - } - return $allNodes; - } - - function listRoles($root, $child, $hashValue = null, $returnNodes = false){ - $allNodes = array(); - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' - - - - '); - if(!AuthService::usersEnabled()) return ; - $roles = AuthService::getRolesList(array(), !$this->listSpecialRoles); - $mess = ConfService::getMessages(); - $repos = ConfService::getRepositoriesList("all"); - ksort($roles); - foreach($roles as $roleId => $roleObject) { - //if(strpos($roleId, "AJXP_GRP_") === 0 && !$this->listSpecialRoles) continue; - $r = array(); - if(!AuthService::canAdministrate($roleObject)) continue; - foreach ($repos as $repoId => $repository){ - if($repository->getAccessType() == "ajxp_shared") continue; - if(!$roleObject->canRead($repoId) && !$roleObject->canWrite($repoId)) continue; - $rs = ($roleObject->canRead($repoId) ? "r" : ""); - $rs .= ($roleObject->canWrite($repoId) ? "w" : ""); - $r[] = $repository->getDisplay()." (".$rs.")"; - } - $rightsString = implode(", ", $r); - $nodeKey = "/roles/".$roleId; - $meta = array( - "icon" => "user-acl.png", - "rights_summary" => $rightsString, - "is_default" => implode(",", $roleObject->listAutoApplies()), //($roleObject->autoAppliesTo("standard") ? $mess[440]:$mess[441]), - "ajxp_mime" => "role", - "text" => $roleObject->getLabel() - ); - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - $xml = AJXP_XMLWriter::renderNode($nodeKey, $roleId, true, $meta, true, false); - if(!$returnNodes) echo $xml; - else $allNodes[$nodeKey] = $xml; - } - return $allNodes; - } - - function repositoryExists($name) - { - $repos = ConfService::getRepositoriesList(); - foreach ($repos as $obj) - if ($obj->getDisplay() == $name) return true; - - return false; - } - - /** - * @param Repository $a - * @param Repository $b - * @return integer - */ - function sortReposByLabel($a, $b){ - return strcasecmp($a->getDisplay(), $b->getDisplay()); - } - - function listRepositories($root, $child, $hashValue = null, $returnNodes = false){ - $repos = ConfService::getRepositoriesList("all"); - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' - - - - - '); - $repoArray = array(); - $childRepos = array(); - $templateRepos = array(); - $flatChildrenRepos = array(); - $allNodes = array(); - //uasort($repos, array($this, "sortReposByLabel")); - foreach ($repos as $repoIndex => $repoObject){ - if(!AuthService::canAdministrate($repoObject)){ - continue; - } - if($repoObject->getAccessType() == "ajxp_conf" || $repoObject->getAccessType() == "ajxp_shared") continue; - if(is_numeric($repoIndex)) $repoIndex = "".$repoIndex; - $name = AJXP_Utils::xmlEntities(SystemTextEncoding::toUTF8($repoObject->getDisplay())); - if($repoObject->hasOwner() || $repoObject->hasParent()) { - $parentId = $repoObject->getParentId(); - if(isSet($repos[$parentId]) && AuthService::canAdministrate($repos[$parentId])){ - if(!isSet($childRepos[$parentId])) $childRepos[$parentId] = array(); - $childRepos[$parentId][] = array("name" => $name, "index" => $repoIndex); - $flatChildrenRepos[] = $repoIndex; - continue; - } - } - if($repoObject->isTemplate){ - $templateRepos[$name] = $repoIndex; - }else{ - $repoArray[$name] = $repoIndex; - } - } - // Sort the list now by name - ksort($templateRepos); - ksort($repoArray); - $repoArray = array_merge($templateRepos, $repoArray); - // Append child repositories - $sortedArray = array(); - foreach ($repoArray as $name => $repoIndex) { - $sortedArray[$name] = $repoIndex; - if(isSet($childRepos[$repoIndex]) && is_array($childRepos[$repoIndex])){ - foreach ($childRepos[$repoIndex] as $childData){ - $sortedArray[$childData["name"]] = $childData["index"]; - } - } - } - foreach ($sortedArray as $name => $repoIndex) { - $repoObject =& $repos[$repoIndex]; - $icon = (in_array($repoIndex, $flatChildrenRepos)?"repo_child.png":"hdd_external_unmount.png"); - $editable = $repoObject->isWriteable(); - if($repoObject->isTemplate) { - $icon = "hdd_external_mount.png"; - if(AuthService::getLoggedUser() != null && AuthService::getLoggedUser()->getGroupPath() != "/"){ - $editable = false; - } - } - $meta = array( - "repository_id" => $repoIndex, - "accessType" => ($repoObject->isTemplate?"Template for ":"").$repoObject->getAccessType(), - "icon" => $icon, - "owner" => ($repoObject->hasOwner()?$repoObject->getOwner():""), - "openicon" => $icon, - "parentname" => "/repositories", - "ajxp_mime" => "repository".($editable?"_editable":"") - ); - $nodeKey = "/data/repositories/$repoIndex"; - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - $xml = AJXP_XMLWriter::renderNode($nodeKey, $name, true, $meta, true, false); - if($returnNodes) $allNodes[$nodeKey] = $xml; - else print($xml); - } - return $allNodes; - } - - function listActions($dir, $root = NULL, $hash = null, $returnNodes = false){ - $allNodes = array(); - $parts = explode("/",$dir); - $pServ = AJXP_PluginsService::getInstance(); - $activePlugins = $pServ->getActivePlugins(); - $types = $pServ->getDetectedPlugins(); - if(count($parts) == 1){ - // list all types - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' - - '); - ksort($types); - foreach( $types as $t => $tPlugs){ - $meta = array( - "icon" => "folder_development.png", - "plugin_id" => $t - ); - $nodeKey = "/$root/actions/".$t; - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - $xml = AJXP_XMLWriter::renderNode($nodeKey, ucfirst($t), false, $meta, true, false); - if($returnNodes) $allNodes[$nodeKey] = $xml; - else print($xml); - } - - }else if(count($parts) == 2){ - // list plugs - $type = $parts[1]; - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' - - - '); - $pObject = new AJXP_Plugin("",""); - foreach($types[$type] as $pId => $pObject){ - $actions = $pObject->getManifestRawContent("//action/@name", "xml", true); - $actLabel = array(); - if($actions->length){ - foreach($actions as $node){ - $actLabel[] = $node->nodeValue; - } - } - $meta = array( - "icon" => "preferences_plugin.png", - "plugin_id" => $pObject->getId(), - "actions" => implode(", ", $actLabel) - ); - $nodeKey = "/$root/actions/$type/".$pObject->getName(); - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - $xml = AJXP_XMLWriter::renderNode($nodeKey, $pObject->getManifestLabel(), false, $meta, true, false); - if($returnNodes) $allNodes[$nodeKey] = $xml; - else print($xml); - - } - - }else if(count($parts) == 3){ - // list actions - $type = $parts[1]; - $name = $parts[2]; - $mess = ConfService::getMessages(); - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' - - - '); - $pObject = new AJXP_Plugin("",""); - $pObject = $types[$type][$name]; - - $actions = $pObject->getManifestRawContent("//action", "xml", true); - $allNodesAcc = array(); - if($actions->length){ - foreach($actions as $node){ - $xPath = new DOMXPath($node->ownerDocument); - $callbacks = $xPath->query("processing/serverCallback", $node); - if(!$callbacks->length) continue; - $callback = $callbacks->item(0); - - $actName = $actLabel = $node->attributes->getNamedItem("name")->nodeValue; - $text = $xPath->query("gui/@text", $node); - if($text->length) { - $actLabel = $actName ." (" . $mess[$text->item(0)->nodeValue].")"; - } - $params = $xPath->query("processing/serverCallback/input_param", $node); - $paramLabel = array(); - if($callback->getAttribute("developerComment") != ""){ - $paramLabel[] = "".$callback->getAttribute("developerComment").""; - } - $restPath = ""; - if($callback->getAttribute("restParams")){ - $restPath = "/api/$actName/". ltrim($callback->getAttribute("restParams"), "/"); - } - if($restPath != null){ - $paramLabel[] = ""."API Access : ".$restPath.""; - } - if($params->length){ - $paramLabel[] = "Expected Parameters :"; - foreach($params as $param){ - $paramLabel[]= '. ['.$param->getAttribute("type").'] '.$param->getAttribute("name").($param->getAttribute("mandatory") == "true" ? '*':'').' : '.$param->getAttribute("description"); - } - } - $parameters = ""; - $meta = array( - "icon" => "preferences_plugin.png", - "action_id" => $actName, - "parameters"=> '
    '.implode("
    ", $paramLabel).'
    ', - "rest_params"=> $restPath - ); - $nodeKey = "/$root/actions/$type/".$pObject->getName()."/$actName"; - if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - $allNodes[$nodeKey] = $allNodesAcc[$actName] = AJXP_XMLWriter::renderNode( - $nodeKey, - $actLabel, - true, - $meta, - true, - false - ); - } - ksort($allNodesAcc); - if(!$returnNodes) print(implode("", array_values($allNodesAcc))); - } - - } - return $allNodes; - } - - function listHooks($dir, $root = NULL, $hash = null, $returnNodes = false){ - $jsonContent = json_decode(file_get_contents(AJXP_Utils::getHooksFile()), true); - $config = ' - - - - - - '; - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig($config); - $allNodes = array(); - foreach($jsonContent as $hookName => $hookData){ - $metadata = array( - "icon" => "preferences_plugin.png", - "description" => $hookData["DESCRIPTION"], - "sample" => $hookData["PARAMETER_SAMPLE"], - ); - $trigs = array(); - foreach($hookData["TRIGGERS"] as $trigger){ - $trigs[] = "".$trigger["FILE"]." (".$trigger["LINE"].")"; - } - $metadata["triggers"] = implode("
    ", $trigs); - $listeners = array(); - foreach($hookData["LISTENERS"] as $listener){ - $listeners[] = "Plugin ".$listener["PLUGIN_ID"].", in method ".$listener["METHOD"].""; - } - $metadata["listeners"] = implode("
    ", $listeners); - $nodeKey = "/$root/hooks/$hookName/$hookName"; - if(in_array($nodeKey, $this->currentBookmarks)) $metadata = array_merge($metadata, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); - $xml = AJXP_XMLWriter::renderNode($nodeKey, $hookName, true, $metadata, true, false); - if($returnNodes) $allNodes[$nodeKey] = $xml; - else print($xml); - } - return $allNodes; - } - - function listLogFiles($dir, $root = NULL, $hash = null, $returnNodes = false){ - $dir = "/$dir"; - $allNodes = array(); - $logger = AJXP_Logger::getInstance(); - $parts = explode("/", $dir); - if(count($parts)>4){ - $config = ' - - - - - - - '; - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig($config); - $date = $parts[count($parts)-1]; - $logger->xmlLogs($dir, $date, "tree", "/".$root."/logs"); - }else{ - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(''); - $nodes = $logger->xmlListLogFiles("tree", (count($parts)>2?$parts[2]:null), (count($parts)>3?$parts[3]:null), "/".$root."/logs", false); - foreach($nodes as $last => $nodeXML){ - if(is_numeric($last) && $last < 10) $last = "0".$last; - $key = "/$root$dir/$last"; - if(in_array($key, $this->currentBookmarks)){ - $nodeXML = str_replace("/>", ' ajxp_bookmarked="true" overlay_icon="bookmark.png"/>', $nodeXML); - } - $allNodes[$key] = $nodeXML; - if(!$returnNodes){ - print($nodeXML); - } - } - } - return $allNodes; - } - - function printDiagnostic($dir, $root = NULL, $hash = null, $returnNodes = false){ - $outputArray = array(); - $testedParams = array(); - $allNodes = array(); - $passed = AJXP_Utils::runTests($outputArray, $testedParams); - AJXP_Utils::testResultsToFile($outputArray, $testedParams); - if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(''); - if(is_file(TESTS_RESULT_FILE)){ - include_once(TESTS_RESULT_FILE); - if(isset($diagResults)){ - foreach ($diagResults as $id => $value){ - $value = AJXP_Utils::xmlEntities($value); - $xml = ""; - if(!$returnNodes) print($xml); - else $allNodes["/$dir/$id"] = $xml; - } - } - } - return $allNodes; - } - - function listSharedFiles(){ - AJXP_XMLWriter::sendFilesListComponentConfig(' - - - - - - - '); - $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); - if(!is_dir($dlFolder)) return ; - $files = glob($dlFolder."/*.php"); - if($files === false) return ; - $mess = ConfService::getMessages(); - $loggedUser = AuthService::getLoggedUser(); - $userId = $loggedUser->getId(); - $dlURL = ConfService::getCoreConf("PUBLIC_DOWNLOAD_URL"); - if($dlURL!= ""){ - $downloadBase = rtrim($dlURL, "/"); - }else{ - $fullUrl = AJXP_Utils::detectServerURL() . dirname($_SERVER['REQUEST_URI']); - $downloadBase = str_replace("\\", "/", $fullUrl.rtrim(str_replace(AJXP_INSTALL_PATH, "", $dlFolder), "/")); - } - - foreach ($files as $file){ - $publicletData = $this->loadPublicletData($file); - if(!is_a($publicletData["REPOSITORY"], "Repository")){ - continue; - } - AJXP_XMLWriter::renderNode(str_replace(".php", "", basename($file)), "".SystemTextEncoding::toUTF8($publicletData["REPOSITORY"]->getDisplay()).":/".SystemTextEncoding::toUTF8($publicletData["FILE_PATH"]), true, array( - "icon" => "html.png", - "password" => ($publicletData["PASSWORD"]!=""?$publicletData["PASSWORD"]:"-"), - "expiration" => ($publicletData["EXPIRE_TIME"]!=0?date($mess["date_format"], $publicletData["EXPIRE_TIME"]):"-"), - "expired" => ($publicletData["EXPIRE_TIME"]!=0?($publicletData["EXPIRE_TIME"] (!$publicletData["SECURITY_MODIFIED"]?$mess["ajxp_shared.15"]:$mess["ajxp_shared.16"]), - "download_url" => $downloadBase . "/".basename($file), - "owner" => (isset($publicletData["OWNER_ID"])?$publicletData["OWNER_ID"]:"-"), - "ajxp_mime" => "shared_file") - ); - } - } - - function metaSourceOrderingFunction($key1, $key2){ - $a1 = explode(".", $key1); - $t1 = array_shift($a1); - $a2 = explode(".", $key2); - $t2 = array_shift($a2); - if($t1 == "index") return 1; - if($t1 == "metastore") return -1; - if($t2 == "index") return -1; - if($t2 == "metastore") return 1; - if($key1 == "meta.git" || $key1 == "meta.svn") return 1; - if($key2 == "meta.git" || $key2 == "meta.svn") return -1; - return 0; - } - - function clearExpiredFiles(){ - $files = glob(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")."/*.php"); - $loggedUser = AuthService::getLoggedUser(); - $userId = $loggedUser->getId(); - $deleted = array(); - foreach ($files as $file){ - $publicletData = $this->loadPublicletData($file); - if(isSet($publicletData["EXPIRATION_TIME"]) && is_numeric($publicletData["EXPIRATION_TIME"]) && $publicletData["EXPIRATION_TIME"] > 0 && $publicletData["EXPIRATION_TIME"] < time()){ - unlink($file); - $deleted[] = basename($file); - } - } - return $deleted; - } - - protected function loadPublicletData($file){ - $inputData = null; - $lines = file($file); - $id = str_replace(".php", "", basename($file)); - $code = trim($lines[3] . $lines[4] . $lines[5]); - if(strpos($code, '$cypheredData =') !== 0) return null; - eval($code); - $dataModified = !ShareCenter::checkHash($inputData, $id); - $publicletData = unserialize($inputData); - if(!is_array($publicletData)) return null; - $publicletData["SECURITY_MODIFIED"] = $dataModified; - return $publicletData; - } - - function updateUserRole($userId, $roleId, $addOrRemove, $updateSubUsers = false){ - $confStorage = ConfService::getConfStorageImpl(); - $user = $confStorage->createUserObject($userId); - //if($user->hasParent()) return $user; - if($addOrRemove == "add"){ - $roleObject = AuthService::getRole($roleId); - $user->addRole($roleObject); - }else{ - $user->removeRole($roleId); - } - $user->save("superuser"); - $loggedUser = AuthService::getLoggedUser(); - if($loggedUser->getId() == $user->getId()){ - AuthService::updateUser($user); - } - return $user; - - } - - - function parseParameters(&$repDef, &$options, $userId = null, $globalBinaries = false){ - - AJXP_Utils::parseStandardFormParameters($repDef, $options, $userId, "DRIVER_OPTION_", ($globalBinaries?array():null)); - - } - - function flattenKeyValues(&$result, $values, $parent = ""){ - foreach($values as $key => $value){ - if(is_array($value)){ - $this->flattenKeyValues($result, $value, $parent."/".$key); - }else{ - if($key == "group_switch_value" || $key == "instance_name"){ - $result[$parent] = $value; - }else{ - $result[$parent.'/'.$key] = $value; - } - } - } - } - -} + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * @package AjaXplorer_Plugins + * @subpackage Access + * @class ajxp_confAccessDriver + * AJXP_Plugin to access the configurations data + */ +class ajxp_confAccessDriver extends AbstractAccessDriver +{ + + private $listSpecialRoles = AJXP_SERVER_DEBUG; + private $currentBookmarks = array(); + + public function listAllActions($action, $httpVars, $fileVars) + { + if(!isSet($this->actions[$action])) return; + parent::accessPreprocess($action, $httpVars, $fileVars); + $loggedUser = AuthService::getLoggedUser(); + if(AuthService::usersEnabled() && !$loggedUser->isAdmin()) return ; + switch ($action) { + //------------------------------------ + // BASIC LISTING + //------------------------------------ + case "list_all_repositories_json": + + $repositories = ConfService::getRepositoriesList("all"); + $repoOut = array(); + foreach ($repositories as $repoObject) { + $repoOut[$repoObject->getId()] = $repoObject->getDisplay(); + } + HTMLWriter::charsetHeader("application/json"); + echo json_encode(array("LEGEND" => "Select a repository", "LIST" => $repoOut)); + + break; + + case "list_all_plugins_actions": + $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//action", "node", false, true, true); + $actions = array(); + foreach ($nodes as $node) { + $xPath = new DOMXPath($node->ownerDocument); + $proc = $xPath->query("processing", $node); + if(!$proc->length) continue; + $txt = $xPath->query("gui/@text", $node); + if ($txt->length) { + $messId = $txt->item(0)->nodeValue; + } else { + $messId = ""; + } + $parentPlugin = $node->parentNode->parentNode->parentNode; + $pId = $parentPlugin->attributes->getNamedItem("id")->nodeValue; + if (empty($pId)) { + $pId = $parentPlugin->nodeName ."."; + if($pId == "ajxpdriver.") $pId = "access."; + $pId .= $parentPlugin->attributes->getNamedItem("name")->nodeValue; + } + //echo($pId." : ". $node->attributes->getNamedItem("name")->nodeValue . " (".$messId.")
    "); + if(!is_array($actions[$pId])) $actions[$pId] = array(); + $actionName = $node->attributes->getNamedItem("name")->nodeValue; + $actions[$pId][$actionName] = array( "action" => $actionName , "label" => $messId); + + } + foreach ($actions as $actPid => $actionGroup) { + ksort($actionGroup, SORT_STRING); + $actions[$actPid] = array(); + foreach ($actionGroup as $k => $v) { + $actions[$actPid][] = $v; + } + } + HTMLWriter::charsetHeader("application/json"); + echo json_encode(array("LIST" => $actions, "HAS_GROUPS" => true)); + break; + case "list_all_plugins_parameters": + $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//param|//global_param", "node", false, true, true); + $actions = array(); + foreach ($nodes as $node) { + if($node->parentNode->nodeName != "server_settings") continue; + $parentPlugin = $node->parentNode->parentNode; + $pId = $parentPlugin->attributes->getNamedItem("id")->nodeValue; + if (empty($pId)) { + $pId = $parentPlugin->nodeName ."."; + if($pId == "ajxpdriver.") $pId = "access."; + $pId .= $parentPlugin->attributes->getNamedItem("name")->nodeValue; + } + //echo($pId." : ". $node->attributes->getNamedItem("name")->nodeValue . " (".$messId.")
    "); + if(!is_array($actions[$pId])) $actions[$pId] = array(); + $actionName = $node->attributes->getNamedItem("name")->nodeValue; + $messId = $node->attributes->getNamedItem("label")->nodeValue; + $actions[$pId][$actionName] = array( "parameter" => $actionName , "label" => AJXP_XMLWriter::replaceAjxpXmlKeywords($messId)); + + } + foreach ($actions as $actPid => $actionGroup) { + ksort($actionGroup, SORT_STRING); + $actions[$actPid] = array(); + foreach ($actionGroup as $k => $v) { + $actions[$actPid][] = $v; + } + } + HTMLWriter::charsetHeader("application/json"); + echo json_encode(array("LIST" => $actions, "HAS_GROUPS" => true)); + break; + case "parameters_to_form_definitions" : + + $data = json_decode(AJXP_Utils::decodeSecureMagic($httpVars["json_parameters"]), true); + AJXP_XMLWriter::header("standard_form"); + foreach ($data as $repoScope => $pluginsData) { + echo(""); + foreach ($pluginsData as $pluginId => $paramData) { + foreach ($paramData as $paramId => $paramValue) { + $query = "//param[@name='$paramId']|//global_param[@name='$paramId']"; + $nodes = AJXP_PluginsService::getInstance()->searchAllManifests($query, "node", false, true, true); + if(!count($nodes)) continue; + $n = $nodes[0]; + if ($n->attributes->getNamedItem("group") != null) { + $n->attributes->getNamedItem("group")->nodeValue = "$pluginId"; + } else { + $n->appendChild($n->ownerDocument->createAttribute("group")); + $n->attributes->getNamedItem("group")->nodeValue = "$pluginId"; + } + if(is_bool($paramValue)) $paramValue = ($paramValue ? "true" : "false"); + if ($n->attributes->getNamedItem("default") != null) { + $n->attributes->getNamedItem("default")->nodeValue = $paramValue; + } else { + $n->appendChild($n->ownerDocument->createAttribute("default")); + $n->attributes->getNamedItem("default")->nodeValue = $paramValue; + } + echo(AJXP_XMLWriter::replaceAjxpXmlKeywords($n->ownerDocument->saveXML($n))); + } + } + echo(""); + } + AJXP_XMLWriter::close("standard_form"); + break; + + default: + break; + } + } + + public function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if($contribNode->nodeName != "actions") return; + $currentUserIsGroupAdmin = (AuthService::getLoggedUser() != null && AuthService::getLoggedUser()->getGroupPath() != "/"); + if(!$currentUserIsGroupAdmin) return; + $actionXpath=new DOMXPath($contribNode->ownerDocument); + $publicUrlNodeList = $actionXpath->query('action[@name="create_repository"]/subMenu', $contribNode); + if ($publicUrlNodeList->length) { + $publicUrlNode = $publicUrlNodeList->item(0); + $publicUrlNode->parentNode->removeChild($publicUrlNode); + } + } + + public function preProcessBookmarkAction($action, &$httpVars, $fileVars) + { + if (isSet($httpVars["bm_action"]) && $httpVars["bm_action"] == "add_bookmark" && AuthService::usersEnabled()) { + $bmUser = AuthService::getLoggedUser(); + $bookmarks = $bmUser->getBookmarks(); + $found = false; + foreach ($bookmarks as $bm) { + if ($bm["PATH"] == $httpVars["bm_path"]) { + $httpVars["bm_action"] = "delete_bookmark"; + break; + } + } + } + + } + + public function recursiveSearchGroups($baseGroup, $term) + { + $groups = AuthService::listChildrenGroups($baseGroup); + foreach ($groups as $groupId => $groupLabel) { + + if (preg_match("/$term/i", $groupLabel) == TRUE ) { + $nodeKey = "/data/users/".trim($baseGroup, "/")."/".ltrim($groupId,"/"); + $meta = array( + "icon" => "users-folder.png", + "ajxp_mime" => "group" + ); + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + echo AJXP_XMLWriter::renderNode($nodeKey, $groupLabel, false, $meta, true, false); + } + $this->recursiveSearchGroups(rtrim($baseGroup, "/")."/".$groupId, $term); + + } + + $users = AuthService::listUsers($baseGroup, $term); + foreach ($users as $userId => $userObject) { + + $nodeKey = "/data/users/".trim($userObject->getGroupPath(),"/")."/".$userId; + $meta = array( + "icon" => "user.png", + "ajxp_mime" => "user" + ); + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + echo AJXP_XMLWriter::renderNode($nodeKey, $userId, false, $meta, true, false); + + } + + } + + + public function searchAction($action, $httpVars, $fileVars) + { + if(! AJXP_Utils::decodeSecureMagic($httpVars["dir"]) == "/data/users") return; + $query = AJXP_Utils::decodeSecureMagic($httpVars["query"]); + AJXP_XMLWriter::header(); + + $this->recursiveSearchGroups("/", $query); + AJXP_XMLWriter::close(); + + } + + public function switchAction($action, $httpVars, $fileVars) + { + if(!isSet($this->actions[$action])) return; + parent::accessPreprocess($action, $httpVars, $fileVars); + $loggedUser = AuthService::getLoggedUser(); + if(AuthService::usersEnabled() && !$loggedUser->isAdmin()) return ; + if (AuthService::usersEnabled()) { + $currentBookmarks = AuthService::getLoggedUser()->getBookmarks(); + // FLATTEN + foreach ($currentBookmarks as $bm) { + $this->currentBookmarks[] = $bm["PATH"]; + } + } + + if ($action == "edit") { + if (isSet($httpVars["sub_action"])) { + $action = $httpVars["sub_action"]; + } + } + $mess = ConfService::getMessages(); + $currentUserIsGroupAdmin = (AuthService::getLoggedUser() != null && AuthService::getLoggedUser()->getGroupPath() != "/"); + if ($currentUserIsGroupAdmin && ConfService::getAuthDriverImpl()->isAjxpAdmin(AuthService::getLoggedUser()->getId())) { + $currentUserIsGroupAdmin = false; + } + + switch ($action) { + //------------------------------------ + // BASIC LISTING + //------------------------------------ + case "ls": + + $rootNodes = array( + "data" => array( + "LABEL" => $mess["ajxp_conf.110"], + "ICON" => "user.png", + "DESCRIPTION" => "Day-to-day administration of the application : who accesses to what, create roles, etc.", + "CHILDREN" => array( + "repositories" => array( + "LABEL" => $mess["ajxp_conf.3"], + "DESCRIPTION" => "Create and delete workspaces, add features to them using meta sources.", + "ICON" => "hdd_external_unmount.png", + "LIST" => "listRepositories"), + "users" => array( + "LABEL" => $mess["ajxp_conf.2"], + "DESCRIPTION" => "Manage users and groups", + "ICON" => "users-folder.png", + "LIST" => "listUsers" + ), + "roles" => array( + "LABEL" => $mess["ajxp_conf.69"], + "DESCRIPTION" => "Define profiles that can be applied at once to whole bunch of users.", + "ICON" => "user-acl.png", + "LIST" => "listRoles"), + ) + ), + "config" => array( + "LABEL" => $mess["ajxp_conf.109"], + "ICON" => "preferences_desktop.png", + "DESCRIPTION" => "Global configurations of the application core and of each plugin. Enable/disable plugins", + "CHILDREN" => array( + "core" => array( + "LABEL" => $mess["ajxp_conf.98"], + "DESCRIPTION" => "Core application parameters", + "ICON" => "preferences_desktop.png", + "LIST" => "listPlugins"), + "core_plugins" => array( + "LABEL" => "Core Plugins", + "DESCRIPTION" => "Enable/disable core plugins (auth, conf, mail, etc), check if they are correctly working. Configuration of these plugins are generally done through the Main Options", + "ICON" => "folder_development.png", + "LIST" => "listPlugins"), + "plugins" => array( + "LABEL" => $mess["ajxp_conf.99"], + "DESCRIPTION" => "Enable/disable additional feature-oriented plugins, check if they are correctly working, set up global parameters of the plugins.", + "ICON" => "folder_development.png", + "LIST" => "listPlugins") + ) + ), + "admin" => array( + "LABEL" => $mess["ajxp_conf.111"], + "ICON" => "toggle_log.png", + "DESCRIPTION" => "Administrator tasks to monitor the application state.", + "CHILDREN" => array( + "logs" => array( + "LABEL" => $mess["ajxp_conf.4"], + "DESCRIPTION" => "Monitor all activities happening on the server", + "ICON" => "toggle_log.png", + "LIST" => "listLogFiles"), + "files" => array( + "LABEL" => $mess["ajxp_shared.3"], + "DESCRIPTION" => "Monitor all files shared as public links by every users", + "ICON" => "html.png", + "LIST" => "listSharedFiles"), + "diagnostic" => array( + "LABEL" => $mess["ajxp_conf.5"], + "DESCRIPTION" => "Read the start-up diagnostic generated by AjaXplorer", + "ICON" => "susehelpcenter.png", "LIST" => "printDiagnostic") + ) + ), + "developer" => array( + "LABEL" => "Developer Resources", + "ICON" => "applications_engineering.png", + "DESCRIPTION" => "Generated documentations for developers", + "CHILDREN" => array( + "actions" => array( + "LABEL" => "Actions API", + "DESCRIPTION" => "List all actions contributed by all plugins and visualize their input parameters", + "ICON" => "book.png", + "LIST" => "listActions"), + "hooks" => array( + "LABEL" => "Hooks Definitions", + "DESCRIPTION" => "List all hooks triggered in the application, their documentation, where there are triggered and which plugin listen to them.", + "ICON" => "book.png", + "LIST" => "listHooks") + ) + ) + ); + if ($currentUserIsGroupAdmin) { + unset($rootNodes["config"]); + unset($rootNodes["admin"]); + unset($rootNodes["developer"]); + } + AJXP_Controller::applyHook("ajxp_conf.list_config_nodes", array(&$rootNodes)); + $dir = trim(AJXP_Utils::decodeSecureMagic((isset($httpVars["dir"])?$httpVars["dir"]:"")), " /"); + if ($dir != "") { + $hash = null; + if (strstr(urldecode($dir), "#") !== false) { + list($dir, $hash) = explode("#", urldecode($dir)); + } + $splits = explode("/", $dir); + $root = array_shift($splits); + if (count($splits)) { + $returnNodes = false; + if (isSet($httpVars["file"])) { + $returnNodes = true; + } + $child = $splits[0]; + if (isSet($rootNodes[$root]["CHILDREN"][$child])) { + $atts = array(); + if ($child == "users") { + $atts["remote_indexation"] = "admin_search"; + } + $callback = $rootNodes[$root]["CHILDREN"][$child]["LIST"]; + if (is_string($callback) && method_exists($this, $callback)) { + if(!$returnNodes) AJXP_XMLWriter::header("tree", $atts); + $res = call_user_func(array($this, $callback), implode("/", $splits), $root, $hash, $returnNodes, isSet($httpVars["file"])?$httpVars["file"]:''); + if(!$returnNodes) AJXP_XMLWriter::close(); + } else if (is_array($callback)) { + $res = call_user_func($callback, implode("/", $splits), $root, $hash, $returnNodes, isSet($httpVars["file"])?$httpVars["file"]:''); + } + if ($returnNodes) { + AJXP_XMLWriter::header("tree", $atts); + if (isSet($res["/".$dir."/".$httpVars["file"]])) { + print $res["/".$dir."/".$httpVars["file"]]; + } + AJXP_XMLWriter::close(); + } + return; + } + } else { + $parentName = "/".$root."/"; + $nodes = $rootNodes[$root]["CHILDREN"]; + } + } else { + $parentName = "/"; + $nodes = $rootNodes; + } + if (isSet($httpVars["file"])) { + $parentName = $httpVars["dir"]."/"; + $nodes = array(basename($httpVars["file"]) => array("LABEL" => basename($httpVars["file"]))); + } + if (isSet($nodes)) { + AJXP_XMLWriter::header(); + if(!isSet($httpVars["file"])) AJXP_XMLWriter::sendFilesListComponentConfig(''); + foreach ($nodes as $key => $data) { + $bmString = ''; + if(in_array($parentName.$key, $this->currentBookmarks)) $bmString = ' ajxp_bookmarked="true" overlay_icon="bookmark.png" '; + if($key == "users") $bmString .= ' remote_indexation="admin_search"'; + print ''; + } + AJXP_XMLWriter::close(); + + } + + break; + + case "stat" : + + header("Content-type:application/json"); + print '{"mode":true}'; + return; + + break; + + case "create_group": + + if (isSet($httpVars["group_path"])) { + $basePath = AJXP_Utils::forwardSlashDirname($httpVars["group_path"]); + if(empty($basePath)) $basePath = "/"; + $gName = AJXP_Utils::sanitize(AJXP_Utils::decodeSecureMagic(basename($httpVars["group_path"])), AJXP_SANITIZE_ALPHANUM); + } else { + $basePath = substr($httpVars["dir"], strlen("/data/users")); + $gName = AJXP_Utils::sanitize(SystemTextEncoding::magicDequote($httpVars["group_name"]), AJXP_SANITIZE_ALPHANUM); + } + $gLabel = AJXP_Utils::decodeSecureMagic($httpVars["group_label"]); + AuthService::createGroup($basePath, $gName, $gLabel); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + + break; + + case "create_role": + $roleId = AJXP_Utils::sanitize(SystemTextEncoding::magicDequote($httpVars["role_id"]), AJXP_SANITIZE_HTML_STRICT); + if (!strlen($roleId)) { + throw new Exception($mess[349]); + } + if (AuthService::getRole($roleId) !== false) { + throw new Exception($mess["ajxp_conf.65"]); + } + $r = new AJXP_Role($roleId); + if (AuthService::getLoggedUser()!=null && AuthService::getLoggedUser()->getGroupPath()!=null) { + $r->setGroupPath(AuthService::getLoggedUser()->getGroupPath()); + } + AuthService::updateRole($r); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.66"], null); + AJXP_XMLWriter::reloadDataNode("", $httpVars["role_id"]); + AJXP_XMLWriter::close(); + break; + + case "edit_role" : + $roleId = SystemTextEncoding::magicDequote($httpVars["role_id"]); + $roleGroup = false; + if (strpos($roleId, "AJXP_GRP_") === 0) { + $groupPath = substr($roleId, strlen("AJXP_GRP_")); + $filteredGroupPath = AuthService::filterBaseGroup($groupPath); + $groups = AuthService::listChildrenGroups(AJXP_Utils::forwardSlashDirname($groupPath)); + $key = "/".basename($groupPath); + if (!array_key_exists($key, $groups)) { + throw new Exception("Cannot find group with this id!"); + } + $roleId = "AJXP_GRP_".$filteredGroupPath; + $groupLabel = $groups[$key]; + $roleGroup = true; + } + if (strpos($roleId, "AJXP_USR_") === 0) { + $usrId = str_replace("AJXP_USR_/", "", $roleId); + $userObject = ConfService::getConfStorageImpl()->createUserObject($usrId); + $role = $userObject->personalRole; + } else { + $role = AuthService::getRole($roleId, $roleGroup); + } + if ($role === false) { + throw new Exception("Cant find role! "); + } + if (isSet($httpVars["format"]) && $httpVars["format"] == "json") { + HTMLWriter::charsetHeader("application/json"); + $roleData = $role->getDataArray(); + $repos = ConfService::getAccessibleRepositories($userObject, true, true, ($userObject == null ? true:false)); + $data = array( + "ROLE" => $roleData, + "ALL" => array( + "REPOSITORIES" => $repos + ) + ); + if (isSet($userObject)) { + $data["USER"] = array(); + $data["USER"]["LOCK"] = $userObject->getLock(); + $data["USER"]["DEFAULT_REPOSITORY"] = $userObject->getPref("force_default_repository"); + $data["USER"]["PROFILE"] = $userObject->getProfile(); + $data["ALL"]["PROFILES"] = array("standard|Standard","admin|Administrator","shared|Shared","guest|Guest"); + $data["USER"]["ROLES"] = array_keys($userObject->getRoles()); + $data["ALL"]["ROLES"] = array_keys(AuthService::getRolesList(array(), true)); + if (isSet($userObject->parentRole)) { + $data["PARENT_ROLE"] = $userObject->parentRole->getDataArray(); + } + } else if (isSet($groupPath)) { + $data["GROUP"] = array("PATH" => $groupPath, "LABEL" => $groupLabel); + } + + $scope = "role"; + if($roleGroup) $scope = "group"; + else if(isSet($userObject)) $scope = "user"; + $data["SCOPE_PARAMS"] = array(); + $nodes = AJXP_PluginsService::getInstance()->searchAllManifests("//param[contains(@scope,'".$scope."')]|//global_param[contains(@scope,'".$scope."')]", "node", false, true, true); + foreach ($nodes as $node) { + $pId = $node->parentNode->parentNode->attributes->getNamedItem("id")->nodeValue; + $origName = $node->attributes->getNamedItem("name")->nodeValue; + $node->attributes->getNamedItem("name")->nodeValue = "AJXP_REPO_SCOPE_ALL/".$pId."/".$origName; + $nArr = array(); + foreach ($node->attributes as $attrib) { + $nArr[$attrib->nodeName] = AJXP_XMLWriter::replaceAjxpXmlKeywords($attrib->nodeValue); + } + $data["SCOPE_PARAMS"][] = $nArr; + } + + echo json_encode($data); + } + break; + + case "post_json_role" : + + $roleId = SystemTextEncoding::magicDequote($httpVars["role_id"]); + $roleGroup = false; + if (strpos($roleId, "AJXP_GRP_") === 0) { + $groupPath = substr($roleId, strlen("AJXP_GRP_")); + $filteredGroupPath = AuthService::filterBaseGroup($groupPath); + $roleId = "AJXP_GRP_".$filteredGroupPath; + $groups = AuthService::listChildrenGroups(AJXP_Utils::forwardSlashDirname($groupPath)); + $key = "/".basename($groupPath); + if (!array_key_exists($key, $groups)) { + throw new Exception("Cannot find group with this id!"); + } + $groupLabel = $groups[$key]; + $roleGroup = true; + } + if (strpos($roleId, "AJXP_USR_") === 0) { + $usrId = str_replace("AJXP_USR_/", "", $roleId); + $userObject = ConfService::getConfStorageImpl()->createUserObject($usrId); + $originalRole = $userObject->personalRole; + } else { + // second param = create if not exists. + $originalRole = AuthService::getRole($roleId, $roleGroup); + } + if ($originalRole === false) { + throw new Exception("Cant find role! "); + } + + $jsonData = AJXP_Utils::decodeSecureMagic($httpVars["json_data"]); + $data = json_decode($jsonData, true); + $roleData = $data["ROLE"]; + $forms = $data["FORMS"]; + $binariesContext = array(); + if (isset($userObject)) { + $binariesContext = array("USER" => $userObject->getId()); + } + foreach ($forms as $repoScope => $plugData) { + foreach ($plugData as $plugId => $formsData) { + $parsed = array(); + AJXP_Utils::parseStandardFormParameters( + $formsData, + $parsed, + ($userObject!=null?$usrId:null), + "ROLE_PARAM_", + $binariesContext + ); + $roleData["PARAMETERS"][$repoScope][$plugId] = $parsed; + } + } + if (isSet($userObject) && isSet($data["USER"]) && isSet($data["USER"]["PROFILE"])) { + $userObject->setAdmin(($data["USER"]["PROFILE"] == "admin")); + $userObject->setProfile($data["USER"]["PROFILE"]); + } + if (isSet($data["GROUP_LABEL"]) && isSet($groupLabel) && $groupLabel != $data["GROUP_LABEL"]) { + ConfService::getConfStorageImpl()->relabelGroup($filteredGroupPath, $data["GROUP_LABEL"]); + } + + $output = array(); + try { + $originalRole->bunchUpdate($roleData); + if (isSet($userObject)) { + $userObject->personalRole = $originalRole; + $userObject->save("superuser"); + //AuthService::updateRole($originalRole, $userObject); + } else { + AuthService::updateRole($originalRole); + } + $output = array("ROLE" => $originalRole->getDataArray(), "SUCCESS" => true); + } catch (Exception $e) { + $output = array("ERROR" => $e->getMessage()); + } + HTMLWriter::charsetHeader("application/json"); + echo(json_encode($output)); + + break; + + + case "user_set_lock" : + + $userId = AJXP_Utils::decodeSecureMagic($httpVars["user_id"]); + $lock = ($httpVars["lock"] == "true" ? true : false); + $lockType = $httpVars["lock_type"]; + if (AuthService::userExists($userId)) { + $userObject = ConfService::getConfStorageImpl()->createUserObject($userId); + if ($lock) { + $userObject->setLock($lockType); + } else { + $userObject->removeLock(); + } + $userObject->save("superuser"); + } + + break; + + case "create_user" : + + if (!isset($httpVars["new_user_login"]) || $httpVars["new_user_login"] == "" ||!isset($httpVars["new_user_pwd"]) || $httpVars["new_user_pwd"] == "") { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.61"]); + AJXP_XMLWriter::close(); + return; + } + $new_user_login = AJXP_Utils::sanitize(SystemTextEncoding::magicDequote($httpVars["new_user_login"]), AJXP_SANITIZE_EMAILCHARS); + if (AuthService::userExists($new_user_login, "w") || AuthService::isReservedUserId($new_user_login)) { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.43"]); + AJXP_XMLWriter::close(); + return; + } + + AuthService::createUser($new_user_login, $httpVars["new_user_pwd"]); + $confStorage = ConfService::getConfStorageImpl(); + $newUser = $confStorage->createUserObject($new_user_login); + $basePath = AuthService::getLoggedUser()->getGroupPath(); + if(empty ($basePath)) $basePath = "/"; + if (!empty($httpVars["group_path"])) { + $newUser->setGroupPath(rtrim($basePath, "/")."/".ltrim($httpVars["group_path"], "/")); + } else { + $newUser->setGroupPath($basePath); + } + + $newUser->save("superuser"); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.44"], null); + AJXP_XMLWriter::reloadDataNode("", $new_user_login); + AJXP_XMLWriter::close(); + + break; + + case "change_admin_right" : + $userId = $httpVars["user_id"]; + if (!AuthService::userExists($userId)) { + throw new Exception("Invalid user id!"); + } + $confStorage = ConfService::getConfStorageImpl(); + $user = $confStorage->createUserObject($userId); + $user->setAdmin(($httpVars["right_value"]=="1"?true:false)); + $user->save("superuser"); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.45"].$httpVars["user_id"], null); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + + break; + + case "user_update_right" : + if(!isSet($httpVars["user_id"]) + || !isSet($httpVars["repository_id"]) + || !isSet($httpVars["right"]) + || !AuthService::userExists($httpVars["user_id"])) + { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.61"]); + print(""); + AJXP_XMLWriter::close(); + return; + } + $confStorage = ConfService::getConfStorageImpl(); + $user = $confStorage->createUserObject($httpVars["user_id"]); + $user->personalRole->setAcl(AJXP_Utils::sanitize($httpVars["repository_id"], AJXP_SANITIZE_ALPHANUM), AJXP_Utils::sanitize($httpVars["right"], AJXP_SANITIZE_ALPHANUM)); + $user->save(); + $loggedUser = AuthService::getLoggedUser(); + if ($loggedUser->getId() == $user->getId()) { + AuthService::updateUser($user); + } + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.46"].$httpVars["user_id"], null); + print("canRead($httpVars["repository_id"])."\" write=\"".$user->canWrite($httpVars["repository_id"])."\"/>"); + AJXP_XMLWriter::reloadRepositoryList(); + AJXP_XMLWriter::close(); + return ; + break; + + case "user_update_group": + + $userSelection = new UserSelection(); + $userSelection->initFromHttpVars($httpVars); + $dir = $httpVars["dir"]; + $dest = $httpVars["dest"]; + if (isSet($httpVars["group_path"])) { + // API Case + $groupPath = $httpVars["group_path"]; + } else { + if (strpos($dir, "/data/users",0)!==0 || strpos($dest, "/data/users",0)!==0) { + break; + } + $groupPath = substr($dest, strlen("/data/users")); + } + + $confStorage = ConfService::getConfStorageImpl(); + + foreach ($userSelection->getFiles() as $selectedUser) { + $userId = basename($selectedUser); + if (!AuthService::userExists($userId)) { + continue; + } + $user = $confStorage->createUserObject($userId); + $basePath = (AuthService::getLoggedUser()!=null ? AuthService::getLoggedUser()->getGroupPath(): "/"); + if(empty ($basePath)) $basePath = "/"; + if (!empty($groupPath)) { + $user->setGroupPath(rtrim($basePath, "/")."/".ltrim($groupPath, "/"), true); + } else { + $user->setGroupPath($basePath, true); + } + $user->save("superuser"); + } + AJXP_XMLWriter::header(); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::reloadDataNode($dest, $userId); + AJXP_XMLWriter::close(); + + break; + + case "user_add_role" : + case "user_delete_role": + + if (!isSet($httpVars["user_id"]) || !isSet($httpVars["role_id"]) || !AuthService::userExists($httpVars["user_id"]) || !AuthService::getRole($httpVars["role_id"])) { + throw new Exception($mess["ajxp_conf.61"]); + } + if ($action == "user_add_role") { + $act = "add"; + $messId = "73"; + } else { + $act = "remove"; + $messId = "74"; + } + $this->updateUserRole($httpVars["user_id"], $httpVars["role_id"], $act); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.".$messId].$httpVars["user_id"], null); + AJXP_XMLWriter::close(); + return ; + + break; + + case "user_update_role" : + + $confStorage = ConfService::getConfStorageImpl(); + $selection = new UserSelection(); + $selection->initFromHttpVars($httpVars); + $files = $selection->getFiles(); + $detectedRoles = array(); + + if (isSet($httpVars["role_id"]) && isset($httpVars["update_role_action"])) { + $update = $httpVars["update_role_action"]; + $roleId = $httpVars["role_id"]; + if (AuthService::getRole($roleId) === false) { + throw new Exception("Invalid role id"); + } + } + foreach ($files as $index => $file) { + $userId = basename($file); + if (isSet($update)) { + $userObject = $this->updateUserRole($userId, $roleId, $update); + } else { + $userObject = $confStorage->createUserObject($userId); + } + if ($userObject->hasParent()) { + unset($files[$index]); + continue; + } + $userRoles = $userObject->getRoles(); + foreach ($userRoles as $roleIndex => $bool) { + if(!isSet($detectedRoles[$roleIndex])) $detectedRoles[$roleIndex] = 0; + if($bool === true) $detectedRoles[$roleIndex] ++; + } + } + $count = count($files); + AJXP_XMLWriter::header("admin_data"); + print(""); + foreach ($detectedRoles as $roleId => $roleCount) { + if($roleCount < $count) continue; + print(""); + } + print(""); + print(""); + foreach (AuthService::getRolesList(array(), !$this->listSpecialRoles) as $roleId => $roleObject) { + print(""); + } + print(""); + AJXP_XMLWriter::close("admin_data"); + + break; + + case "save_custom_user_params" : + $userId = $httpVars["user_id"]; + if ($userId == $loggedUser->getId()) { + $user = $loggedUser; + } else { + $confStorage = ConfService::getConfStorageImpl(); + $user = $confStorage->createUserObject($userId); + } + $custom = $user->getPref("CUSTOM_PARAMS"); + if(!is_array($custom)) $custom = array(); + + $options = $custom; + $this->parseParameters($httpVars, $options, $userId); + $custom = $options; + $user->setPref("CUSTOM_PARAMS", $custom); + $user->save(); + + if ($loggedUser->getId() == $user->getId()) { + AuthService::updateUser($user); + } + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.47"].$httpVars["user_id"], null); + AJXP_XMLWriter::close(); + + break; + + case "save_repository_user_params" : + $userId = $httpVars["user_id"]; + if ($userId == $loggedUser->getId()) { + $user = $loggedUser; + } else { + $confStorage = ConfService::getConfStorageImpl(); + $user = $confStorage->createUserObject($userId); + } + $wallet = $user->getPref("AJXP_WALLET"); + if(!is_array($wallet)) $wallet = array(); + $repoID = $httpVars["repository_id"]; + if (!array_key_exists($repoID, $wallet)) { + $wallet[$repoID] = array(); + } + $options = $wallet[$repoID]; + $this->parseParameters($httpVars, $options, $userId); + $wallet[$repoID] = $options; + $user->setPref("AJXP_WALLET", $wallet); + $user->save(); + + if ($loggedUser->getId() == $user->getId()) { + AuthService::updateUser($user); + } + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.47"].$httpVars["user_id"], null); + AJXP_XMLWriter::close(); + + break; + + case "update_user_pwd" : + if (!isSet($httpVars["user_id"]) || !isSet($httpVars["user_pwd"]) || !AuthService::userExists($httpVars["user_id"]) || trim($httpVars["user_pwd"]) == "") { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.61"]); + AJXP_XMLWriter::close(); + return; + } + $res = AuthService::updatePassword($httpVars["user_id"], $httpVars["user_pwd"]); + AJXP_XMLWriter::header(); + if ($res === true) { + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.48"].$httpVars["user_id"], null); + } else { + AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.49"]." : $res"); + } + AJXP_XMLWriter::close(); + + break; + + case "save_user_preference": + + if (!isSet($httpVars["user_id"]) || !AuthService::userExists($httpVars["user_id"]) ) { + throw new Exception($mess["ajxp_conf.61"]); + } + $userId = $httpVars["user_id"]; + if ($userId == $loggedUser->getId()) { + $userObject = $loggedUser; + } else { + $confStorage = ConfService::getConfStorageImpl(); + $userObject = $confStorage->createUserObject($userId); + } + $i = 0; + while (isSet($httpVars["pref_name_".$i]) && isSet($httpVars["pref_value_".$i])) { + $prefName = AJXP_Utils::sanitize($httpVars["pref_name_".$i], AJXP_SANITIZE_ALPHANUM); + $prefValue = AJXP_Utils::sanitize(SystemTextEncoding::magicDequote(($httpVars["pref_value_".$i]))); + if($prefName == "password") continue; + if ($prefName != "pending_folder" && $userObject == null) { + $i++; + continue; + } + $userObject->setPref($prefName, $prefValue); + $userObject->save("user"); + $i++; + } + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage("Succesfully saved user preference", null); + AJXP_XMLWriter::close(); + + break; + + case "get_drivers_definition": + + AJXP_XMLWriter::header("drivers", array("allowed" => $currentUserIsGroupAdmin ? "false" : "true")); + print(AJXP_XMLWriter::replaceAjxpXmlKeywords(ConfService::availableDriversToXML("param", "", true))); + AJXP_XMLWriter::close("drivers"); + + + break; + + case "get_templates_definition": + + AJXP_XMLWriter::header("repository_templates"); + $repositories = ConfService::getRepositoriesList("all"); + foreach ($repositories as $repo) { + if(!$repo->isTemplate) continue; + $repoId = $repo->getId(); + $repoLabel = $repo->getDisplay(); + $repoType = $repo->getAccessType(); + print(""); + } + AJXP_XMLWriter::close("repository_templates"); + + + break; + + case "create_repository" : + + $repDef = $httpVars; + $isTemplate = isSet($httpVars["sf_checkboxes_active"]); + unset($repDef["get_action"]); + unset($repDef["sf_checkboxes_active"]); + if (isSet($httpVars["json_data"])) { + $options = json_decode($httpVars["json_data"], true); + } else { + $options = array(); + $this->parseParameters($repDef, $options, null, true); + } + if (count($options)) { + $repDef["DRIVER_OPTIONS"] = $options; + unset($repDef["DRIVER_OPTIONS"]["AJXP_GROUP_PATH_PARAMETER"]); + } + if (strstr($repDef["DRIVER"], "ajxp_template_") !== false) { + $templateId = substr($repDef["DRIVER"], 14); + $templateRepo = ConfService::getRepositoryById($templateId); + $newRep = $templateRepo->createTemplateChild($repDef["DISPLAY"], $repDef["DRIVER_OPTIONS"]); + } else { + if ($currentUserIsGroupAdmin) { + throw new Exception("You are not allowed to create a repository from a driver. Use a template instead."); + } + $pServ = AJXP_PluginsService::getInstance(); + $driver = $pServ->getPluginByTypeName("access", $repDef["DRIVER"]); + + $newRep = ConfService::createRepositoryFromArray(0, $repDef); + $testFile = $driver->getBaseDir()."/test.".$newRep->getAccessType()."Access.php"; + if (!$isTemplate && is_file($testFile)) { + //chdir(AJXP_TESTS_FOLDER."/plugins"); + $className = $newRep->getAccessType()."AccessTest"; + if (!class_exists($className)) + include($testFile); + $class = new $className(); + $result = $class->doRepositoryTest($newRep); + if (!$result) { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, $class->failedInfo); + AJXP_XMLWriter::close(); + return; + } + } + // Apply default metasource if any + if ($driver != null && $driver->getConfigs()!=null ) { + $confs = $driver->getConfigs(); + if (!empty($confs["DEFAULT_METASOURCES"])) { + $metaIds = AJXP_Utils::parseCSL($confs["DEFAULT_METASOURCES"]); + $metaSourceOptions = array(); + foreach ($metaIds as $metaID) { + $metaPlug = $pServ->getPluginById($metaID); + if($metaPlug == null) continue; + $pNodes = $metaPlug->getManifestRawContent("//param[@default]", "nodes"); + $defaultParams = array(); + foreach ($pNodes as $domNode) { + $defaultParams[$domNode->getAttribute("name")] = $domNode->getAttribute("default"); + } + $metaSourceOptions[$metaID] = $defaultParams; + } + $newRep->addOption("META_SOURCES", $metaSourceOptions); + } + } + } + + if ($this->repositoryExists($newRep->getDisplay())) { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.50"]); + AJXP_XMLWriter::close(); + return; + } + if ($isTemplate) { + $newRep->isTemplate = true; + } + if ($currentUserIsGroupAdmin) { + $newRep->setGroupPath(AuthService::getLoggedUser()->getGroupPath()); + } else if (!empty($options["AJXP_GROUP_PATH_PARAMETER"])) { + $basePath = "/"; + if (AuthService::getLoggedUser()!=null && AuthService::getLoggedUser()->getGroupPath()!=null) { + $basePath = AuthService::getLoggedUser()->getGroupPath(); + } + $value = AJXP_Utils::securePath(rtrim($basePath, "/")."/".ltrim($options["AJXP_GROUP_PATH_PARAMETER"], "/")); + $newRep->setGroupPath($value); + } + + $res = ConfService::addRepository($newRep); + AJXP_XMLWriter::header(); + if ($res == -1) { + AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.51"]); + } else { + $loggedUser = AuthService::getLoggedUser(); + $loggedUser->personalRole->setAcl($newRep->getUniqueId(), "rw"); + $loggedUser->recomputeMergedRole(); + $loggedUser->save("superuser"); + AuthService::updateUser($loggedUser); + + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.52"], null); + AJXP_XMLWriter::reloadDataNode("", $newRep->getUniqueId()); + AJXP_XMLWriter::reloadRepositoryList(); + } + AJXP_XMLWriter::close(); + + + + break; + + case "edit_repository" : + $repId = $httpVars["repository_id"]; + $repository = ConfService::getRepositoryById($repId); + if ($repository == null) { + throw new Exception("Cannot find repository with id $repId"); + } + if (!AuthService::canAdministrate($repository)) { + throw new Exception("You are not allowed to edit this repository!"); + } + $pServ = AJXP_PluginsService::getInstance(); + $plug = $pServ->getPluginById("access.".$repository->accessType); + if ($plug == null) { + throw new Exception("Cannot find access driver (".$repository->accessType.") for repository!"); + } + AJXP_XMLWriter::header("admin_data"); + $slug = $repository->getSlug(); + if ($slug == "" && $repository->isWriteable()) { + $repository->setSlug(); + ConfService::replaceRepository($repId, $repository); + } + if (AuthService::getLoggedUser()!=null && AuthService::getLoggedUser()->getGroupPath() != null) { + $rgp = $repository->getGroupPath(); + if($rgp == null) $rgp = "/"; + if (strlen($rgp) < strlen(AuthService::getLoggedUser()->getGroupPath())) { + $repository->setWriteable(false); + } + } + $nested = array(); + print(" $option) { + if(strstr($name, " ")>-1) continue; + if (!is_array($option)) { + if (is_bool($option)) { + $option = ($option?"true":"false"); + } + print(" $name=\"".SystemTextEncoding::toUTF8(AJXP_Utils::xmlEntities($option))."\" "); + } else if (is_array($option)) { + $nested[] = $option; + } + } + if (count($nested)) { + print(">"); + foreach ($nested as $option) { + foreach ($option as $key => $optValue) { + if (is_array($optValue) && count($optValue)) { + print(""); + } else { + if (is_bool($optValue)) { + $optValue = ($optValue?"true":"false"); + } + $optValue = AJXP_Utils::xmlEntities($optValue, true); + print(""); + } + } + } + // Add SLUG + if(!$repository->isTemplate) print("getSlug()."\"/>"); + if ($repository->getGroupPath() != null) { + $basePath = "/"; + if (AuthService::getLoggedUser()!=null && AuthService::getLoggedUser()->getGroupPath()!=null) { + $basePath = AuthService::getLoggedUser()->getGroupPath(); + } + $groupPath = $repository->getGroupPath(); + if($basePath != "/") $groupPath = substr($repository->getGroupPath(), strlen($basePath)); + print(""); + } + + print(""); + } else { + print("/>"); + } + if ($repository->hasParent()) { + $parent = ConfService::getRepositoryById($repository->getParentId()); + if (isSet($parent) && $parent->isTemplate) { + $parentLabel = $parent->getDisplay(); + $parentType = $parent->getAccessType(); + print(""); + } + } + $manifest = $plug->getManifestRawContent("server_settings/param"); + $manifest = AJXP_XMLWriter::replaceAjxpXmlKeywords($manifest); + print("accessType."\">$manifest"); + print(""); + $metas = $pServ->getPluginsByType("metastore"); + $metas = array_merge($metas, $pServ->getPluginsByType("meta")); + $metas = array_merge($metas, $pServ->getPluginsByType("index")); + foreach ($metas as $metaPlug) { + print("getId()."\" label=\"".AJXP_Utils::xmlEntities($metaPlug->getManifestLabel())."\">"); + $manifest = $metaPlug->getManifestRawContent("server_settings/param"); + $manifest = AJXP_XMLWriter::replaceAjxpXmlKeywords($manifest); + print($manifest); + print(""); + } + print(""); + AJXP_XMLWriter::close("admin_data"); + return ; + break; + + case "edit_repository_label" : + case "edit_repository_data" : + $repId = $httpVars["repository_id"]; + $repo = ConfService::getRepositoryById($repId); + $res = 0; + if (isSet($httpVars["newLabel"])) { + $newLabel = AJXP_Utils::decodeSecureMagic($httpVars["newLabel"]); + if ($this->repositoryExists($newLabel)) { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.50"]); + AJXP_XMLWriter::close(); + return; + } + $repo->setDisplay($newLabel); + $res = ConfService::replaceRepository($repId, $repo); + } else { + $options = array(); + $this->parseParameters($httpVars, $options, null, true); + if (count($options)) { + foreach ($options as $key=>$value) { + if ($key == "AJXP_SLUG") { + $repo->setSlug($value); + continue; + } elseif ($key == "AJXP_GROUP_PATH_PARAMETER") { + $basePath = "/"; + if (AuthService::getLoggedUser()!=null && AuthService::getLoggedUser()->getGroupPath()!=null) { + $basePath = AuthService::getLoggedUser()->getGroupPath(); + } + $value = AJXP_Utils::securePath(rtrim($basePath, "/")."/".ltrim($value, "/")); + $repo->setGroupPath($value); + continue; + } + $repo->addOption($key, $value); + } + } + if ($repo->getOption("DEFAULT_RIGHTS")) { + $gp = $repo->getGroupPath(); + if (empty($gp) || $gp == "/") { + $defRole = AuthService::getRole("ROOT_ROLE"); + } else { + $defRole = AuthService::getRole("AJXP_GRP_".$gp, true); + } + if ($defRole !== false) { + $defRole->setAcl($repId, $repo->getOption("DEFAULT_RIGHTS")); + AuthService::updateRole($defRole); + } + } + if (is_file(AJXP_TESTS_FOLDER."/plugins/test.ajxp_".$repo->getAccessType().".php")) { + chdir(AJXP_TESTS_FOLDER."/plugins"); + include(AJXP_TESTS_FOLDER."/plugins/test.ajxp_".$repo->getAccessType().".php"); + $className = "ajxp_".$repo->getAccessType(); + $class = new $className(); + $result = $class->doRepositoryTest($repo); + if (!$result) { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, $class->failedInfo); + AJXP_XMLWriter::close(); + return; + } + } + + ConfService::replaceRepository($repId, $repo); + } + AJXP_XMLWriter::header(); + if ($res == -1) { + AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.53"]); + } else { + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.54"], null); + AJXP_XMLWriter::reloadDataNode("", (isSet($httpVars["newLabel"])?$repId:false)); + AJXP_XMLWriter::reloadRepositoryList(); + } + AJXP_XMLWriter::close(); + + break; + + case "meta_source_add" : + $repId = $httpVars["repository_id"]; + $repo = ConfService::getRepositoryById($repId); + if (!is_object($repo)) { + throw new Exception("Invalid repository id! $repId"); + } + $metaSourceType = AJXP_Utils::sanitize($httpVars["new_meta_source"], AJXP_SANITIZE_ALPHANUM); + if (isSet($httpVars["json_data"])) { + $options = json_decode($httpVars["json_data"], true); + } else { + $options = array(); + $this->parseParameters($httpVars, $options, null, true); + } + $repoOptions = $repo->getOption("META_SOURCES"); + if (is_array($repoOptions) && isSet($repoOptions[$metaSourceType])) { + throw new Exception($mess["ajxp_conf.55"]); + } + if (!is_array($repoOptions)) { + $repoOptions = array(); + } + $repoOptions[$metaSourceType] = $options; + uksort($repoOptions, array($this,"metaSourceOrderingFunction")); + $repo->addOption("META_SOURCES", $repoOptions); + ConfService::replaceRepository($repId, $repo); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.56"],null); + AJXP_XMLWriter::close(); + break; + + case "meta_source_delete" : + + $repId = $httpVars["repository_id"]; + $repo = ConfService::getRepositoryById($repId); + if (!is_object($repo)) { + throw new Exception("Invalid repository id! $repId"); + } + $metaSourceId = $httpVars["plugId"]; + $repoOptions = $repo->getOption("META_SOURCES"); + if (is_array($repoOptions) && array_key_exists($metaSourceId, $repoOptions)) { + unset($repoOptions[$metaSourceId]); + uksort($repoOptions, array($this,"metaSourceOrderingFunction")); + $repo->addOption("META_SOURCES", $repoOptions); + ConfService::replaceRepository($repId, $repo); + } + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.57"],null); + AJXP_XMLWriter::close(); + + break; + + case "meta_source_edit" : + $repId = $httpVars["repository_id"]; + $repo = ConfService::getRepositoryById($repId); + if (!is_object($repo)) { + throw new Exception("Invalid repository id! $repId"); + } + $metaSourceId = $httpVars["plugId"]; + $repoOptions = $repo->getOption("META_SOURCES"); + if (!is_array($repoOptions)) { + $repoOptions = array(); + } + if (isSet($httpVars["json_data"])) { + $options = json_decode($httpVars["json_data"], true); + } else { + $options = array(); + $this->parseParameters($httpVars, $options, null, true); + } + $repoOptions[$metaSourceId] = $options; + uksort($repoOptions, array($this,"metaSourceOrderingFunction")); + $repo->addOption("META_SOURCES", $repoOptions); + ConfService::replaceRepository($repId, $repo); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.58"],null); + AJXP_XMLWriter::close(); + break; + + + case "delete" : + // REST API mapping + if (isSet($httpVars["data_type"])) { + switch ($httpVars["data_type"]) { + case "repository": + $httpVars["repository_id"] = basename($httpVars["data_id"]); + break; + case "shared_file": + $httpVars["shared_file"] = basename($httpVars["data_id"]); + break; + case "role": + $httpVars["role_id"] = basename($httpVars["data_id"]); + break; + case "user": + $httpVars["user_id"] = basename($httpVars["data_id"]); + break; + case "group": + $httpVars["group"] = "/data/users".$httpVars["data_id"]; + break; + default: + break; + } + unset($httpVars["data_type"]); + unset($httpVars["data_id"]); + } + if (isSet($httpVars["repository_id"])) { + $repId = $httpVars["repository_id"]; + $res = ConfService::deleteRepository($repId); + AJXP_XMLWriter::header(); + if ($res == -1) { + AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.51"]); + } else { + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.59"], null); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::reloadRepositoryList(); + } + AJXP_XMLWriter::close(); + return; + } else if (isSet($httpVars["shared_file"])) { + AJXP_XMLWriter::header(); + $element = basename($httpVars["shared_file"]); + $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); + $publicletData = $this->loadPublicletData($dlFolder."/".$element.".php"); + unlink($dlFolder."/".$element.".php"); + AJXP_XMLWriter::sendMessage($mess["ajxp_shared.13"], null); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + } else if (isSet($httpVars["role_id"])) { + $roleId = $httpVars["role_id"]; + if (AuthService::getRole($roleId) === false) { + throw new Exception($mess["ajxp_conf.67"]); + } + AuthService::deleteRole($roleId); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.68"], null); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + } else if (isSet($httpVars["group"])) { + $groupPath = $httpVars["group"]; + $basePath = substr(AJXP_Utils::forwardSlashDirname($groupPath), strlen("/data/users")); + $gName = basename($groupPath); + AuthService::deleteGroup($basePath, $gName); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + } else { + if(!isset($httpVars["user_id"]) || $httpVars["user_id"]=="" + || AuthService::isReservedUserId($httpVars["user_id"]) + || $loggedUser->getId() == $httpVars["user_id"]) + { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage(null, $mess["ajxp_conf.61"]); + AJXP_XMLWriter::close(); + } + $res = AuthService::deleteUser($httpVars["user_id"]); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.60"], null); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + + } + break; + + case "clear_expired" : + + $deleted = $this->clearExpiredFiles(); + AJXP_XMLWriter::header(); + if (count($deleted)) { + AJXP_XMLWriter::sendMessage(sprintf($mess["ajxp_shared.23"], count($deleted).""), null); + AJXP_XMLWriter::reloadDataNode(); + } else { + AJXP_XMLWriter::sendMessage($mess["ajxp_shared.24"], null); + } + AJXP_XMLWriter::close(); + + break; + + case "get_plugin_manifest" : + + $ajxpPlugin = AJXP_PluginsService::getInstance()->getPluginById($httpVars["plugin_id"]); + AJXP_XMLWriter::header("admin_data"); + + $fullManifest = $ajxpPlugin->getManifestRawContent("", "xml"); + $xPath = new DOMXPath($fullManifest->ownerDocument); + $addParams = ""; + $pInstNodes = $xPath->query("server_settings/global_param[contains(@type, 'plugin_instance:')]"); + foreach ($pInstNodes as $pInstNode) { + $type = $pInstNode->getAttribute("type"); + $instType = str_replace("plugin_instance:", "", $type); + $fieldName = $pInstNode->getAttribute("name"); + $pInstNode->setAttribute("type", "group_switch:".$fieldName); + $typePlugs = AJXP_PluginsService::getInstance()->getPluginsByType($instType); + foreach ($typePlugs as $typePlug) { + if($typePlug->getId() == "auth.multi") continue; + $checkErrorMessage = ""; + try { + $typePlug->performChecks(); + } catch (Exception $e) { + $checkErrorMessage = " (Warning : ".$e->getMessage().")"; + } + $tParams = AJXP_XMLWriter::replaceAjxpXmlKeywords($typePlug->getManifestRawContent("server_settings/param[not(@group_switch_name)]")); + $addParams .= ''; + $addParams .= str_replace("getManifestLabel().$checkErrorMessage."\" group_switch_value=\"".$typePlug->getId()."\" ", $tParams); + $addParams .= str_replace("getManifestRawContent("server_settings/param[@group_switch_name]"))); + $addParams .= AJXP_XMLWriter::replaceAjxpXmlKeywords($typePlug->getManifestRawContent("server_settings/global_param")); + } + } + $allParams = AJXP_XMLWriter::replaceAjxpXmlKeywords($fullManifest->ownerDocument->saveXML($fullManifest)); + $allParams = str_replace('type="plugin_instance:', 'type="group_switch:', $allParams); + $allParams = str_replace("", $addParams."", $allParams); + + echo($allParams); + $definitions = $ajxpPlugin->getConfigsDefinitions(); + $values = $ajxpPlugin->getConfigs(); + if(!is_array($values)) $values = array(); + echo(""); + foreach ($values as $key => $value) { + $attribute = true; + $type = $definitions[$key]["type"]; + if ($type == "array" && is_array($value)) { + $value = implode(",", $value); + } else if ((strpos($type, "group_switch:") === 0 || strpos($type, "plugin_instance:") === 0 ) && is_array($value)) { + $res = array(); + $this->flattenKeyValues($res, $value, $key); + foreach ($res as $newKey => $newVal) { + echo(""); + } + continue; + } else if ($type == "boolean") { + $value = ($value === true || $value === "true" || $value == 1?"true":"false"); + } else if ($type == "textarea") { + $attribute = false; + } + if ($attribute) { + echo(""); + } else { + echo(""); + } + } + if ($ajxpPlugin->getType() != "core") { + echo("isEnabled()?"true":"false")."\"/>"); + } + echo(""); + echo("".$ajxpPlugin->getPluginInformationHTML("Charles du Jeu", "http://ajaxplorer.info/plugins/")."

    "); + if (file_exists($ajxpPlugin->getBaseDir()."/plugin_doc.html")) { + echo(file_get_contents($ajxpPlugin->getBaseDir()."/plugin_doc.html")); + } + echo("]]>
    "); + AJXP_XMLWriter::close("admin_data"); + + break; + + case "run_plugin_action": + + $options = array(); + $this->parseParameters($httpVars, $options, null, true); + $pluginId = $httpVars["action_plugin_id"]; + if (isSet($httpVars["button_key"])) { + $options = $options[$httpVars["button_key"]]; + } + $plugin = AJXP_PluginsService::getInstance()->softLoad($pluginId, $options); + if (method_exists($plugin, $httpVars["action_plugin_method"])) { + try { + $res = call_user_func(array($plugin, $httpVars["action_plugin_method"]), $options); + } catch (Exception $e) { + echo("ERROR:" . $e->getMessage()); + break; + } + echo($res); + } else { + echo 'ERROR: Plugin '.$httpVars["action_plugin_id"].' does not implement '.$httpVars["action_plugin_method"].' method!'; + } + + break; + + case "edit_plugin_options": + + $options = array(); + $this->parseParameters($httpVars, $options, null, true); + $confStorage = ConfService::getConfStorageImpl(); + $confStorage->savePluginConfig($httpVars["plugin_id"], $options); + @unlink(AJXP_PLUGINS_CACHE_FILE); + @unlink(AJXP_PLUGINS_REQUIRES_FILE); + @unlink(AJXP_PLUGINS_MESSAGES_FILE); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["ajxp_conf.97"], null); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + + + break; + + default: + break; + } + + return; + } + + + public function listPlugins($dir, $root = NULL, $hash = null, $returnNodes = false) + { + $dir = "/$dir"; + $allNodes = array(); + AJXP_Logger::logAction("Listing plugins"); // make sure that the logger is started! + $pServ = AJXP_PluginsService::getInstance(); + $types = $pServ->getDetectedPlugins(); + $uniqTypes = array("core"); + $coreTypes = array("auth", "conf", "boot", "feed", "log", "mailer", "mq"); + if ($dir == "/plugins" || $dir == "/core_plugins") { + if($dir == "/core_plugins") $uniqTypes = $coreTypes; + else $uniqTypes = array_diff(array_keys($types), $coreTypes); + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' + + '); + ksort($types); + foreach ($types as $t => $tPlugs) { + if(!in_array($t, $uniqTypes))continue; + $nodeKey = "/".$root.$dir."/".$t; + $meta = array( + "icon" => "folder_development.png", + "plugin_id" => $t + ); + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + $xml = AJXP_XMLWriter::renderNode($nodeKey, ucfirst($t), false, $meta, true, false); + if($returnNodes) $allNodes[$nodeKey] = $xml; + else print($xml); + } + } else if ($dir == "/core") { + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' + + + + '); + $mess = ConfService::getMessages(); + $all = $first = ""; + foreach ($uniqTypes as $type) { + if(!isset($types[$type])) continue; + foreach ($types[$type] as $pId => $pObject) { + $isMain = ($pObject->getId() == "core.ajaxplorer"); + $meta = array( + "icon" => ($isMain?"preferences_desktop.png":"desktop.png"), + "ajxp_mime" => "ajxp_plugin", + "plugin_id" => $pObject->getId(), + "plugin_description" => $pObject->getManifestDescription() + ); + // Check if there are actually any parameters to display! + if($pObject->getManifestRawContent("server_settings", "xml")->length == 0) continue; + $label = $pObject->getManifestLabel(); + $nodeKey = "/$root".$dir."/".$pObject->getId(); + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + $nodeString =AJXP_XMLWriter::renderNode($nodeKey, $label, true, $meta, true, false); + if($returnNodes) $allNodes[$nodeKey] = $nodeString; + if ($isMain) { + $first = $nodeString; + } else { + $all .= $nodeString; + } + } + } + if(!$returnNodes) print($first.$all); + } else { + $split = explode("/", $dir); + if(empty($split[0])) array_shift($split); + $type = $split[1]; + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' + + + + + + '); + $mess = ConfService::getMessages(); + foreach ($types[$type] as $pId => $pObject) { + $errors = "OK"; + try { + $pObject->performChecks(); + } catch (Exception $e) { + $errors = "ERROR : ".$e->getMessage(); + } + $meta = array( + "icon" => "preferences_plugin.png", + "ajxp_mime" => "ajxp_plugin", + "can_active" => $errors, + "enabled" => ($pObject->isEnabled()?$mess[440]:$mess[441]), + "plugin_id" => $pObject->getId(), + "plugin_description" => $pObject->getManifestDescription() + ); + $nodeKey = "/$root".$dir."/".$pObject->getId(); + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + $xml = AJXP_XMLWriter::renderNode($nodeKey, $pObject->getManifestLabel(), true, $meta, true, false); + if($returnNodes) $allNodes[$nodeKey] = $xml; + else print $xml; + } + } + return $allNodes; + } + + public function listUsers($root, $child, $hashValue = null, $returnNodes = false, $findNodePosition=null) + { + $USER_PER_PAGE = 50; + if($root == "users") $baseGroup = "/"; + else $baseGroup = substr($root, strlen("users")); + + if ($findNodePosition != null && $hashValue == null) { + + // Loop on each page to find the correct page. + $count = AuthService::authCountUsers($baseGroup); + $pages = ceil($count / $USER_PER_PAGE); + for ($i = 0; $i < $pages ; $i ++) { + + $tests = $this->listUsers($root, $child, $i+1, true, $findNodePosition); + if (is_array($tests) && isSet($tests["/data/".$root."/".$findNodePosition])) { + return array("/data/".$root."/".$findNodePosition => str_replace("ajxp_mime", "page_position='".($i+1)."' ajxp_mime", $tests["/data/".$root."/".$findNodePosition])); + } + + } + + return array(); + + } + + $allNodes = array(); + $columns = ' + + + + + '; + if (AuthService::driverSupportsAuthSchemes()) { + $columns = ' + + + + + + '; + } + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig($columns); + if(!AuthService::usersEnabled()) return ; + if(empty($hashValue)) $hashValue = 1; + + $count = AuthService::authCountUsers($baseGroup); + if (AuthService::authSupportsPagination() && $count >= $USER_PER_PAGE) { + $offset = ($hashValue - 1) * $USER_PER_PAGE; + if(!$returnNodes) AJXP_XMLWriter::renderPaginationData($count, $hashValue, ceil($count/$USER_PER_PAGE)); + $users = AuthService::listUsers($baseGroup, "", $offset, $USER_PER_PAGE); + if ($hashValue == 1) { + $groups = AuthService::listChildrenGroups($baseGroup); + } else { + $groups = array(); + } + } else { + $users = AuthService::listUsers($baseGroup); + $groups = AuthService::listChildrenGroups($baseGroup); + } + foreach ($groups as $groupId => $groupLabel) { + + $nodeKey = "/data/".$root."/".ltrim($groupId,"/"); + $meta = array( + "icon" => "users-folder.png", + "ajxp_mime" => "group" + ); + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + $xml = AJXP_XMLWriter::renderNode($nodeKey, + $groupLabel, false, $meta, true, false); + if(!$returnNodes) print($xml); + else $allNodes[$nodeKey] = $xml; + + } + $mess = ConfService::getMessages(); + $repos = ConfService::getRepositoriesList("all"); + $loggedUser = AuthService::getLoggedUser(); + $userArray = array(); + foreach ($users as $userIndex => $userObject) { + $label = $userObject->getId(); + if ($userObject->hasParent()) { + $label = $userObject->getParent()."000".$label; + } + $userArray[$label] = $userObject; + } + ksort($userArray); + foreach ($userArray as $userObject) { + $isAdmin = $userObject->isAdmin(); + $userId = $userObject->getId(); + $icon = "user".($userId=="guest"?"_guest":($isAdmin?"_admin":"")); + if ($userObject->hasParent()) { + $icon = "user_child"; + } + $rightsString = ""; + if ($isAdmin) { + $rightsString = $mess["ajxp_conf.63"]; + } else { + $r = array(); + foreach ($repos as $repoId => $repository) { + if($repository->getAccessType() == "ajxp_shared") continue; + if(!$userObject->canRead($repoId) && !$userObject->canWrite($repoId)) continue; + $rs = ($userObject->canRead($repoId) ? "r" : ""); + $rs .= ($userObject->canWrite($repoId) ? "w" : ""); + $r[] = $repository->getDisplay()." (".$rs.")"; + } + $rightsString = implode(", ", $r); + } + $nodeLabel = $userId; + $test = $userObject->personalRole->filterParameterValue("core.conf", "USER_DISPLAY_NAME", AJXP_REPO_SCOPE_ALL, ""); + if(!empty($test)) $nodeLabel = $test; + $scheme = AuthService::getAuthScheme($userId); + $nodeKey = "/data/$root/".$userId; + $meta = array( + "isAdmin" => $mess[($isAdmin?"ajxp_conf.14":"ajxp_conf.15")], + "icon" => $icon.".png", + "auth_scheme" => ($scheme != null? $scheme : ""), + "rights_summary" => $rightsString, + "ajxp_roles" => implode(", ", array_keys($userObject->getRoles())), + "ajxp_mime" => "user".(($userId!="guest"&&$userId!=$loggedUser->getId())?"_editable":"") + ); + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + $xml = AJXP_XMLWriter::renderNode($nodeKey, $nodeLabel, true, $meta, true, false); + if(!$returnNodes) print($xml); + else $allNodes[$nodeKey] = $xml; + } + return $allNodes; + } + + public function listRoles($root, $child, $hashValue = null, $returnNodes = false) + { + $allNodes = array(); + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' + + + + '); + if(!AuthService::usersEnabled()) return ; + $roles = AuthService::getRolesList(array(), !$this->listSpecialRoles); + $mess = ConfService::getMessages(); + $repos = ConfService::getRepositoriesList("all"); + ksort($roles); + foreach ($roles as $roleId => $roleObject) { + //if(strpos($roleId, "AJXP_GRP_") === 0 && !$this->listSpecialRoles) continue; + $r = array(); + if(!AuthService::canAdministrate($roleObject)) continue; + foreach ($repos as $repoId => $repository) { + if($repository->getAccessType() == "ajxp_shared") continue; + if(!$roleObject->canRead($repoId) && !$roleObject->canWrite($repoId)) continue; + $rs = ($roleObject->canRead($repoId) ? "r" : ""); + $rs .= ($roleObject->canWrite($repoId) ? "w" : ""); + $r[] = $repository->getDisplay()." (".$rs.")"; + } + $rightsString = implode(", ", $r); + $nodeKey = "/roles/".$roleId; + $meta = array( + "icon" => "user-acl.png", + "rights_summary" => $rightsString, + "is_default" => implode(",", $roleObject->listAutoApplies()), //($roleObject->autoAppliesTo("standard") ? $mess[440]:$mess[441]), + "ajxp_mime" => "role", + "text" => $roleObject->getLabel() + ); + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + $xml = AJXP_XMLWriter::renderNode($nodeKey, $roleId, true, $meta, true, false); + if(!$returnNodes) echo $xml; + else $allNodes[$nodeKey] = $xml; + } + return $allNodes; + } + + public function repositoryExists($name) + { + $repos = ConfService::getRepositoriesList(); + foreach ($repos as $obj) + if ($obj->getDisplay() == $name) return true; + + return false; + } + + /** + * @param Repository $a + * @param Repository $b + * @return integer + */ + public function sortReposByLabel($a, $b) + { + return strcasecmp($a->getDisplay(), $b->getDisplay()); + } + + public function listRepositories($root, $child, $hashValue = null, $returnNodes = false) + { + $repos = ConfService::getRepositoriesList("all"); + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' + + + + + '); + $repoArray = array(); + $childRepos = array(); + $templateRepos = array(); + $flatChildrenRepos = array(); + $allNodes = array(); + //uasort($repos, array($this, "sortReposByLabel")); + foreach ($repos as $repoIndex => $repoObject) { + if (!AuthService::canAdministrate($repoObject)) { + continue; + } + if($repoObject->getAccessType() == "ajxp_conf" || $repoObject->getAccessType() == "ajxp_shared") continue; + if(is_numeric($repoIndex)) $repoIndex = "".$repoIndex; + $name = AJXP_Utils::xmlEntities(SystemTextEncoding::toUTF8($repoObject->getDisplay())); + if ($repoObject->hasOwner() || $repoObject->hasParent()) { + $parentId = $repoObject->getParentId(); + if (isSet($repos[$parentId]) && AuthService::canAdministrate($repos[$parentId])) { + if(!isSet($childRepos[$parentId])) $childRepos[$parentId] = array(); + $childRepos[$parentId][] = array("name" => $name, "index" => $repoIndex); + $flatChildrenRepos[] = $repoIndex; + continue; + } + } + if ($repoObject->isTemplate) { + $templateRepos[$name] = $repoIndex; + } else { + $repoArray[$name] = $repoIndex; + } + } + // Sort the list now by name + ksort($templateRepos); + ksort($repoArray); + $repoArray = array_merge($templateRepos, $repoArray); + // Append child repositories + $sortedArray = array(); + foreach ($repoArray as $name => $repoIndex) { + $sortedArray[$name] = $repoIndex; + if (isSet($childRepos[$repoIndex]) && is_array($childRepos[$repoIndex])) { + foreach ($childRepos[$repoIndex] as $childData) { + $sortedArray[$childData["name"]] = $childData["index"]; + } + } + } + foreach ($sortedArray as $name => $repoIndex) { + $repoObject =& $repos[$repoIndex]; + $icon = (in_array($repoIndex, $flatChildrenRepos)?"repo_child.png":"hdd_external_unmount.png"); + $editable = $repoObject->isWriteable(); + if ($repoObject->isTemplate) { + $icon = "hdd_external_mount.png"; + if (AuthService::getLoggedUser() != null && AuthService::getLoggedUser()->getGroupPath() != "/") { + $editable = false; + } + } + $meta = array( + "repository_id" => $repoIndex, + "accessType" => ($repoObject->isTemplate?"Template for ":"").$repoObject->getAccessType(), + "icon" => $icon, + "owner" => ($repoObject->hasOwner()?$repoObject->getOwner():""), + "openicon" => $icon, + "parentname" => "/repositories", + "ajxp_mime" => "repository".($editable?"_editable":"") + ); + $nodeKey = "/data/repositories/$repoIndex"; + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + $xml = AJXP_XMLWriter::renderNode($nodeKey, $name, true, $meta, true, false); + if($returnNodes) $allNodes[$nodeKey] = $xml; + else print($xml); + } + return $allNodes; + } + + public function listActions($dir, $root = NULL, $hash = null, $returnNodes = false) + { + $allNodes = array(); + $parts = explode("/",$dir); + $pServ = AJXP_PluginsService::getInstance(); + $activePlugins = $pServ->getActivePlugins(); + $types = $pServ->getDetectedPlugins(); + if (count($parts) == 1) { + // list all types + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' + + '); + ksort($types); + foreach ($types as $t => $tPlugs) { + $meta = array( + "icon" => "folder_development.png", + "plugin_id" => $t + ); + $nodeKey = "/$root/actions/".$t; + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + $xml = AJXP_XMLWriter::renderNode($nodeKey, ucfirst($t), false, $meta, true, false); + if($returnNodes) $allNodes[$nodeKey] = $xml; + else print($xml); + } + + } else if (count($parts) == 2) { + // list plugs + $type = $parts[1]; + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' + + + '); + $pObject = new AJXP_Plugin("",""); + foreach ($types[$type] as $pId => $pObject) { + $actions = $pObject->getManifestRawContent("//action/@name", "xml", true); + $actLabel = array(); + if ($actions->length) { + foreach ($actions as $node) { + $actLabel[] = $node->nodeValue; + } + } + $meta = array( + "icon" => "preferences_plugin.png", + "plugin_id" => $pObject->getId(), + "actions" => implode(", ", $actLabel) + ); + $nodeKey = "/$root/actions/$type/".$pObject->getName(); + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + $xml = AJXP_XMLWriter::renderNode($nodeKey, $pObject->getManifestLabel(), false, $meta, true, false); + if($returnNodes) $allNodes[$nodeKey] = $xml; + else print($xml); + + } + + } else if (count($parts) == 3) { + // list actions + $type = $parts[1]; + $name = $parts[2]; + $mess = ConfService::getMessages(); + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(' + + + '); + $pObject = new AJXP_Plugin("",""); + $pObject = $types[$type][$name]; + + $actions = $pObject->getManifestRawContent("//action", "xml", true); + $allNodesAcc = array(); + if ($actions->length) { + foreach ($actions as $node) { + $xPath = new DOMXPath($node->ownerDocument); + $callbacks = $xPath->query("processing/serverCallback", $node); + if(!$callbacks->length) continue; + $callback = $callbacks->item(0); + + $actName = $actLabel = $node->attributes->getNamedItem("name")->nodeValue; + $text = $xPath->query("gui/@text", $node); + if ($text->length) { + $actLabel = $actName ." (" . $mess[$text->item(0)->nodeValue].")"; + } + $params = $xPath->query("processing/serverCallback/input_param", $node); + $paramLabel = array(); + if ($callback->getAttribute("developerComment") != "") { + $paramLabel[] = "".$callback->getAttribute("developerComment").""; + } + $restPath = ""; + if ($callback->getAttribute("restParams")) { + $restPath = "/api/$actName/". ltrim($callback->getAttribute("restParams"), "/"); + } + if ($restPath != null) { + $paramLabel[] = ""."API Access : ".$restPath.""; + } + if ($params->length) { + $paramLabel[] = "Expected Parameters :"; + foreach ($params as $param) { + $paramLabel[]= '. ['.$param->getAttribute("type").'] '.$param->getAttribute("name").($param->getAttribute("mandatory") == "true" ? '*':'').' : '.$param->getAttribute("description"); + } + } + $parameters = ""; + $meta = array( + "icon" => "preferences_plugin.png", + "action_id" => $actName, + "parameters"=> '
    '.implode("
    ", $paramLabel).'
    ', + "rest_params"=> $restPath + ); + $nodeKey = "/$root/actions/$type/".$pObject->getName()."/$actName"; + if(in_array($nodeKey, $this->currentBookmarks)) $meta = array_merge($meta, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + $allNodes[$nodeKey] = $allNodesAcc[$actName] = AJXP_XMLWriter::renderNode( + $nodeKey, + $actLabel, + true, + $meta, + true, + false + ); + } + ksort($allNodesAcc); + if(!$returnNodes) print(implode("", array_values($allNodesAcc))); + } + + } + return $allNodes; + } + + public function listHooks($dir, $root = NULL, $hash = null, $returnNodes = false) + { + $jsonContent = json_decode(file_get_contents(AJXP_Utils::getHooksFile()), true); + $config = ' + + + + + + '; + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig($config); + $allNodes = array(); + foreach ($jsonContent as $hookName => $hookData) { + $metadata = array( + "icon" => "preferences_plugin.png", + "description" => $hookData["DESCRIPTION"], + "sample" => $hookData["PARAMETER_SAMPLE"], + ); + $trigs = array(); + foreach ($hookData["TRIGGERS"] as $trigger) { + $trigs[] = "".$trigger["FILE"]." (".$trigger["LINE"].")"; + } + $metadata["triggers"] = implode("
    ", $trigs); + $listeners = array(); + foreach ($hookData["LISTENERS"] as $listener) { + $listeners[] = "Plugin ".$listener["PLUGIN_ID"].", in method ".$listener["METHOD"].""; + } + $metadata["listeners"] = implode("
    ", $listeners); + $nodeKey = "/$root/hooks/$hookName/$hookName"; + if(in_array($nodeKey, $this->currentBookmarks)) $metadata = array_merge($metadata, array("ajxp_bookmarked" => "true", "overlay_icon" => "bookmark.png")); + $xml = AJXP_XMLWriter::renderNode($nodeKey, $hookName, true, $metadata, true, false); + if($returnNodes) $allNodes[$nodeKey] = $xml; + else print($xml); + } + return $allNodes; + } + + public function listLogFiles($dir, $root = NULL, $hash = null, $returnNodes = false) + { + $dir = "/$dir"; + $allNodes = array(); + $logger = AJXP_Logger::getInstance(); + $parts = explode("/", $dir); + if (count($parts)>4) { + $config = ' + + + + + + + '; + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig($config); + $date = $parts[count($parts)-1]; + $logger->xmlLogs($dir, $date, "tree", "/".$root."/logs"); + } else { + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(''); + $nodes = $logger->xmlListLogFiles("tree", (count($parts)>2?$parts[2]:null), (count($parts)>3?$parts[3]:null), "/".$root."/logs", false); + foreach ($nodes as $last => $nodeXML) { + if(is_numeric($last) && $last < 10) $last = "0".$last; + $key = "/$root$dir/$last"; + if (in_array($key, $this->currentBookmarks)) { + $nodeXML = str_replace("/>", ' ajxp_bookmarked="true" overlay_icon="bookmark.png"/>', $nodeXML); + } + $allNodes[$key] = $nodeXML; + if (!$returnNodes) { + print($nodeXML); + } + } + } + return $allNodes; + } + + public function printDiagnostic($dir, $root = NULL, $hash = null, $returnNodes = false) + { + $outputArray = array(); + $testedParams = array(); + $allNodes = array(); + $passed = AJXP_Utils::runTests($outputArray, $testedParams); + AJXP_Utils::testResultsToFile($outputArray, $testedParams); + if(!$returnNodes) AJXP_XMLWriter::sendFilesListComponentConfig(''); + if (is_file(TESTS_RESULT_FILE)) { + include_once(TESTS_RESULT_FILE); + if (isset($diagResults)) { + foreach ($diagResults as $id => $value) { + $value = AJXP_Utils::xmlEntities($value); + $xml = ""; + if(!$returnNodes) print($xml); + else $allNodes["/$dir/$id"] = $xml; + } + } + } + return $allNodes; + } + + public function listSharedFiles() + { + AJXP_XMLWriter::sendFilesListComponentConfig(' + + + + + + + '); + $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); + if(!is_dir($dlFolder)) return ; + $files = glob($dlFolder."/*.php"); + if($files === false) return ; + $mess = ConfService::getMessages(); + $loggedUser = AuthService::getLoggedUser(); + $userId = $loggedUser->getId(); + $dlURL = ConfService::getCoreConf("PUBLIC_DOWNLOAD_URL"); + if ($dlURL!= "") { + $downloadBase = rtrim($dlURL, "/"); + } else { + $fullUrl = AJXP_Utils::detectServerURL() . dirname($_SERVER['REQUEST_URI']); + $downloadBase = str_replace("\\", "/", $fullUrl.rtrim(str_replace(AJXP_INSTALL_PATH, "", $dlFolder), "/")); + } + + foreach ($files as $file) { + $publicletData = $this->loadPublicletData($file); + if (!is_a($publicletData["REPOSITORY"], "Repository")) { + continue; + } + AJXP_XMLWriter::renderNode(str_replace(".php", "", basename($file)), "".SystemTextEncoding::toUTF8($publicletData["REPOSITORY"]->getDisplay()).":/".SystemTextEncoding::toUTF8($publicletData["FILE_PATH"]), true, array( + "icon" => "html.png", + "password" => ($publicletData["PASSWORD"]!=""?$publicletData["PASSWORD"]:"-"), + "expiration" => ($publicletData["EXPIRE_TIME"]!=0?date($mess["date_format"], $publicletData["EXPIRE_TIME"]):"-"), + "expired" => ($publicletData["EXPIRE_TIME"]!=0?($publicletData["EXPIRE_TIME"] (!$publicletData["SECURITY_MODIFIED"]?$mess["ajxp_shared.15"]:$mess["ajxp_shared.16"]), + "download_url" => $downloadBase . "/".basename($file), + "owner" => (isset($publicletData["OWNER_ID"])?$publicletData["OWNER_ID"]:"-"), + "ajxp_mime" => "shared_file") + ); + } + } + + public function metaSourceOrderingFunction($key1, $key2) + { + $a1 = explode(".", $key1); + $t1 = array_shift($a1); + $a2 = explode(".", $key2); + $t2 = array_shift($a2); + if($t1 == "index") return 1; + if($t1 == "metastore") return -1; + if($t2 == "index") return -1; + if($t2 == "metastore") return 1; + if($key1 == "meta.git" || $key1 == "meta.svn") return 1; + if($key2 == "meta.git" || $key2 == "meta.svn") return -1; + return 0; + } + + public function clearExpiredFiles() + { + $files = glob(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")."/*.php"); + $loggedUser = AuthService::getLoggedUser(); + $userId = $loggedUser->getId(); + $deleted = array(); + foreach ($files as $file) { + $publicletData = $this->loadPublicletData($file); + if (isSet($publicletData["EXPIRATION_TIME"]) && is_numeric($publicletData["EXPIRATION_TIME"]) && $publicletData["EXPIRATION_TIME"] > 0 && $publicletData["EXPIRATION_TIME"] < time()) { + unlink($file); + $deleted[] = basename($file); + } + } + return $deleted; + } + + protected function loadPublicletData($file) + { + $inputData = null; + $lines = file($file); + $id = str_replace(".php", "", basename($file)); + $code = trim($lines[3] . $lines[4] . $lines[5]); + if(strpos($code, '$cypheredData =') !== 0) return null; + eval($code); + $dataModified = !ShareCenter::checkHash($inputData, $id); + $publicletData = unserialize($inputData); + if(!is_array($publicletData)) return null; + $publicletData["SECURITY_MODIFIED"] = $dataModified; + return $publicletData; + } + + public function updateUserRole($userId, $roleId, $addOrRemove, $updateSubUsers = false) + { + $confStorage = ConfService::getConfStorageImpl(); + $user = $confStorage->createUserObject($userId); + //if($user->hasParent()) return $user; + if ($addOrRemove == "add") { + $roleObject = AuthService::getRole($roleId); + $user->addRole($roleObject); + } else { + $user->removeRole($roleId); + } + $user->save("superuser"); + $loggedUser = AuthService::getLoggedUser(); + if ($loggedUser->getId() == $user->getId()) { + AuthService::updateUser($user); + } + return $user; + + } + + + public function parseParameters(&$repDef, &$options, $userId = null, $globalBinaries = false) + { + AJXP_Utils::parseStandardFormParameters($repDef, $options, $userId, "DRIVER_OPTION_", ($globalBinaries?array():null)); + + } + + public function flattenKeyValues(&$result, $values, $parent = "") + { + foreach ($values as $key => $value) { + if (is_array($value)) { + $this->flattenKeyValues($result, $value, $parent."/".$key); + } else { + if ($key == "group_switch_value" || $key == "instance_name") { + $result[$parent] = $value; + } else { + $result[$parent.'/'.$key] = $value; + } + } + } + } + +} diff --git a/core/src/plugins/access.ajxp_conf/i18n/de.php b/core/src/plugins/access.ajxp_conf/i18n/de.php index cc9cc250e2..d7962510ef 100644 --- a/core/src/plugins/access.ajxp_conf/i18n/de.php +++ b/core/src/plugins/access.ajxp_conf/i18n/de.php @@ -143,4 +143,4 @@ "group_access" => "G", "119" => "Set user group", -); \ No newline at end of file +); diff --git a/core/src/plugins/access.ajxp_conf/i18n/en.php b/core/src/plugins/access.ajxp_conf/i18n/en.php index e2fb9516f9..01f2ac3aeb 100644 --- a/core/src/plugins/access.ajxp_conf/i18n/en.php +++ b/core/src/plugins/access.ajxp_conf/i18n/en.php @@ -25,7 +25,7 @@ "4" => "Logs", "5" => "Diagnostic", "6" => "User Name", -"7" => "Is Admin", +"7" => "Is Admin", "8" => "Workspace Label", "9" => "Access Type", "10" => "Meta Sources", @@ -36,18 +36,18 @@ "15" => "False", "16" => "Fle Date", "17" => "Date", -"18" => "I.P.", +"18" => "I.P.", "19" => "Level", -"20" => "User", -"21" => "Action", +"20" => "User", +"21" => "Action", "22" => "Params", "23" => "Test Name", "24" => "Test Data", "25" => "Workspaces Access", "26" => "Modify Password", "27" => "Admin Right", -"28" => "User has admin rights?", -"29" => "Read", +"28" => "User has admin rights?", +"29" => "Read", "30" => "Write", "32" => "Access Driver", "33" => "Loading...", @@ -56,7 +56,7 @@ "36" => "Mandatory fields are missing!", "37" => "Warning, password and confirmation differ!", "38" => "Please fill the login field!", -"39" => "Please fill both password fields!", +"39" => "Please fill both password fields!", "40" => "Please check the box to confirm!", "41" => "Driver Options", "42" => "Please choose a driver!", @@ -72,8 +72,8 @@ "52" => "Successfully created workspace! You can now add some 'Metadata Sources' to enrich the data, add automatic indexation, etc", "53" => "Error while trying to edit worskpace", "54" => "Successfully edited workspace", -"55" => "Warning, at the moment, you can only add one instance of each meta plugin.", -"56" => "Successfully added meta source", +"55" => "Warning, at the moment, you can only add one instance of each meta plugin.", +"56" => "Successfully added meta source", "57" => "Successfully deleted meta source", "58" => "Successfully edited meta source", "59" => "Successfully deleted workspace", @@ -95,7 +95,7 @@ "75" => "New Role", "role_access" => "o", "76" => "Role Id", -"77" => "Access Control", +"77" => "Access Control", "78" => "Personal data", "79" => "Workspace", "80" => "Fine-tune access for this user (Click on a workspace label if you wish to make it the default workspace when user logs in)", @@ -140,4 +140,4 @@ "118" => "New group", "group_access" => "g", "119" => "Set user group", -); \ No newline at end of file +); diff --git a/core/src/plugins/access.ajxp_conf/i18n/es.php b/core/src/plugins/access.ajxp_conf/i18n/es.php index a4f055f8d0..84fbd02aac 100644 --- a/core/src/plugins/access.ajxp_conf/i18n/es.php +++ b/core/src/plugins/access.ajxp_conf/i18n/es.php @@ -25,7 +25,7 @@ "4" => "Logs", "5" => "Diagnósticos", "6" => "Nombre de Usuario", -"7" => "Es Administrador", +"7" => "Es Administrador", "8" => "Etiqueta de Carpeta", "9" => "Tipo de Acceso", "10" => "Orígenes Meta", @@ -36,18 +36,18 @@ "15" => "Falso", "16" => "Fecha de archivo", "17" => "Fecha", -"18" => "I.P.", +"18" => "I.P.", "19" => "Nivel", -"20" => "Usuario", -"21" => "Acción", +"20" => "Usuario", +"21" => "Acción", "22" => "Parámetros", "23" => "Nombre de prueba", "24" => "Datos de prueba", "25" => "Acceso a Carpetas", "26" => "Modificar contraseña", "27" => "Administrar privilegios", -"28" => "El usuario tiene privilegios de administrador?", -"29" => "Leer", +"28" => "El usuario tiene privilegios de administrador?", +"29" => "Leer", "30" => "Escribir", "32" => "Controlador de Acceso", "33" => "Cargando...", @@ -56,7 +56,7 @@ "36" => "Faltan campos obligatorios!", "37" => "Atención, las contraseñas no coinciden!", "38" => "Por favor rellene el campo de login!", -"39" => "Por favor rellene los dos campos de contraseña!", +"39" => "Por favor rellene los dos campos de contraseña!", "40" => "Por favor marque la casilla para confirmar!", "41" => "Opciones de Controlador", "42" => "Por favor elija un Controlador!", @@ -72,8 +72,8 @@ "52" => "Carpeta creada correctamente! Ahora puede añadir metadatos para completar la información, añadir índices automáticos, etc", "53" => "Error editando la carpeta", "54" => "Carpeta editada correctamente", -"55" => "Atención, en este momento solo puede añadir una instacia de cada plugin.", -"56" => "Origen de meta añadido satisfactoriamente", +"55" => "Atención, en este momento solo puede añadir una instacia de cada plugin.", +"56" => "Origen de meta añadido satisfactoriamente", "57" => "Origen de meta bottado correctamente", "58" => "Origen de meta editado correctamente", "59" => "Carpeta borrada correctamente", @@ -95,7 +95,7 @@ "75" => "Nuevo Rol", "role_access" => "o", "76" => "ID de rol", -"77" => "Control de Acceso", +"77" => "Control de Acceso", "78" => "Datos Personales", "79" => "Carpeta", "80" => "Ajustes detallado de este usuario (pulse en una carpeta si quiere configurarla para que ésta se abra por defecto cuanco el usuario inicie sesión)", diff --git a/core/src/plugins/access.ajxp_conf/i18n/fi.php b/core/src/plugins/access.ajxp_conf/i18n/fi.php index 053e573f79..0a57914dcd 100644 --- a/core/src/plugins/access.ajxp_conf/i18n/fi.php +++ b/core/src/plugins/access.ajxp_conf/i18n/fi.php @@ -144,4 +144,4 @@ "group_access" => "g", "119" => "Set user group", /* END SENTENCE */ -); \ No newline at end of file +); diff --git a/core/src/plugins/access.ajxp_conf/i18n/fr.php b/core/src/plugins/access.ajxp_conf/i18n/fr.php index 9c20a6b6ad..2f27dcc9dc 100644 --- a/core/src/plugins/access.ajxp_conf/i18n/fr.php +++ b/core/src/plugins/access.ajxp_conf/i18n/fr.php @@ -142,4 +142,3 @@ "119" => "Set user group", /* END SENTENCE */ ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.ajxp_conf/i18n/hu.php b/core/src/plugins/access.ajxp_conf/i18n/hu.php index 4e4bf98bbc..e09c76a818 100644 --- a/core/src/plugins/access.ajxp_conf/i18n/hu.php +++ b/core/src/plugins/access.ajxp_conf/i18n/hu.php @@ -144,4 +144,4 @@ "119" => "Set user group", /* END SENTENCE */ -); \ No newline at end of file +); diff --git a/core/src/plugins/access.ajxp_conf/i18n/pt.php b/core/src/plugins/access.ajxp_conf/i18n/pt.php index 00678ee4d2..213a47ad04 100644 --- a/core/src/plugins/access.ajxp_conf/i18n/pt.php +++ b/core/src/plugins/access.ajxp_conf/i18n/pt.php @@ -25,7 +25,7 @@ "4" => "Registos", "5" => "Diagnóstico", "6" => "Nome de Utilizador", -"7" => "É Administrador", +"7" => "É Administrador", "8" => "Etiqueta de Área de Trabalho", "9" => "Tipo de Acesso", "10" => "Fontes Meta", @@ -36,18 +36,18 @@ "15" => "Falso", "16" => "Data de Ficheiro", "17" => "Data", -"18" => "I.P.", +"18" => "I.P.", "19" => "Nível", -"20" => "Utilizador", -"21" => "Acção", +"20" => "Utilizador", +"21" => "Acção", "22" => "Parâmetros", "23" => "Nome de Teste", "24" => "Nome de Dados", "25" => "Acesso à Área de Trabalho", "26" => "Alterar Palavra-Chave", "27" => "Direitos de Administrador", -"28" => "O Utilizador tem permissões de administrador?", -"29" => "Ler", +"28" => "O Utilizador tem permissões de administrador?", +"29" => "Ler", "30" => "Escrever", "32" => "Controlador de Acesso", "33" => "A carregar...", @@ -56,7 +56,7 @@ "36" => "Campos obrigatórios não preenchidos!", "37" => "ATENÇÃO: A confirmação difere da palavra-chave introduzida!", "38" => "Por favor preencha o campo de login!", -"39" => "Por favor preencha ambos os campos da palavra-chave!", +"39" => "Por favor preencha ambos os campos da palavra-chave!", "40" => "Por favor marque a caixa para confirmar!", "41" => "Opções do Controlador", "42" => "Por favor escolha um controlador!", @@ -72,8 +72,8 @@ "52" => "Criada a Área de Trabalho com sucesso! Pode agora adicionar algumas 'Fontes de Metadata' para melhorar os conteúdos, adicionar Indexação automática, etc", "53" => "Erro ao tentar editar a Área de Trabalho", "54" => "Editada com sucesso a Área de Trabalho", -"55" => "ATENÇÃO: De momento apenas pode correr uma instância de cada plugin meta.", -"56" => "Adicionada fonte meta com sucesso", +"55" => "ATENÇÃO: De momento apenas pode correr uma instância de cada plugin meta.", +"56" => "Adicionada fonte meta com sucesso", "57" => "Apagada fonte meta com sucesso", "58" => "Editada a fonte meta com sucesso", "59" => "Apagada a Área de Trabalho com Sucesso", @@ -95,7 +95,7 @@ "75" => "Novo papel", "role_access" => "p", "76" => "ID de Papel", -"77" => "Controlo de Acesso", +"77" => "Controlo de Acesso", "78" => "Dados Pessoais", "79" => "Área de Trabalho", "80" => "Ajustar acesso para este utilizador (Clique na etiqueta de Área de Trabalho da qual deseja que seja a que é mostrada sempre que o utilizador iniciar sessão)", @@ -140,4 +140,4 @@ "118" => "Novo Grupo", "group_access" => "G", "119" => "Definir grupo do utilizador", -); \ No newline at end of file +); diff --git a/core/src/plugins/access.ajxp_conf/i18n/si.php b/core/src/plugins/access.ajxp_conf/i18n/si.php index de29734944..f2873cdc5d 100644 --- a/core/src/plugins/access.ajxp_conf/i18n/si.php +++ b/core/src/plugins/access.ajxp_conf/i18n/si.php @@ -141,4 +141,4 @@ "118" => "New group", "group_access" => "g", "119" => "Set user group", -); \ No newline at end of file +); diff --git a/core/src/plugins/access.ajxp_conf/manifest.xml b/core/src/plugins/access.ajxp_conf/manifest.xml index 5a8b7dbee5..e769488a2d 100644 --- a/core/src/plugins/access.ajxp_conf/manifest.xml +++ b/core/src/plugins/access.ajxp_conf/manifest.xml @@ -6,9 +6,9 @@ - + - + @@ -99,6 +99,6 @@ - + - \ No newline at end of file + diff --git a/core/src/plugins/access.ajxp_shared/class.ajxpSharedAccessDriver.php b/core/src/plugins/access.ajxp_shared/class.ajxpSharedAccessDriver.php index 81e4406f0d..1d05c0e4e1 100644 --- a/core/src/plugins/access.ajxp_shared/class.ajxpSharedAccessDriver.php +++ b/core/src/plugins/access.ajxp_shared/class.ajxpSharedAccessDriver.php @@ -1,316 +1,319 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); -/** - * @package AjaXplorer_Plugins - * @subpackage Access - * @class ajxpSharedAccessDriver - * AJXP_Plugin to access the shared elements of the current user - */ -class ajxpSharedAccessDriver extends AbstractAccessDriver -{ - - function initRepository(){ - require_once AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/action.share/class.ShareCenter.php"; - } - - function switchAction($action, $httpVars, $fileVars){ - if(!isSet($this->actions[$action])) return; - parent::accessPreprocess($action, $httpVars, $fileVars); - $loggedUser = AuthService::getLoggedUser(); - if(!AuthService::usersEnabled()) return ; - - if($action == "edit"){ - if(isSet($httpVars["sub_action"])){ - $action = $httpVars["sub_action"]; - } - } - $mess = ConfService::getMessages(); - - switch($action) - { - //------------------------------------ - // BASIC LISTING - //------------------------------------ - case "ls": - $rootNodes = array( - "files" => array("LABEL" => $mess["ajxp_shared.3"], "ICON" => "html.png", "DESCRIPTION" => $mess["ajxp_shared.28"]), - "repositories" => array("LABEL" => $mess["ajxp_shared.2"], "ICON" => "document_open_remote.png", "DESCRIPTION" => $mess["ajxp_shared.29"]), - "users" => array("LABEL" => $mess["ajxp_shared.1"], "ICON" => "user_shared.png", "DESCRIPTION" => $mess["ajxp_shared.30"]) - ); - $dir = (isset($httpVars["dir"])?$httpVars["dir"]:""); - $splits = explode("/", $dir); - if(count($splits)){ - if($splits[0] == "") array_shift($splits); - if(count($splits)) $strippedDir = strtolower(urldecode($splits[0])); - else $strippedDir = ""; - } - if(array_key_exists($strippedDir, $rootNodes)){ - AJXP_XMLWriter::header(); - if($strippedDir == "users"){ - $this->listUsers(); - }else if($strippedDir == "repositories"){ - $this->listRepositories(); - }else if($strippedDir == "files"){ - $this->listSharedFiles(); - } - AJXP_XMLWriter::close(); - exit(1); - }else{ - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendFilesListComponentConfig(''); - foreach ($rootNodes as $key => $data){ - print ''; - } - AJXP_XMLWriter::close(); - } - break; - - case "stat" : - - header("Content-type:application/json"); - print '{"mode":true}'; - - break; - - case "delete" : - $mime = $httpVars["ajxp_mime"]; - $selection = new UserSelection(); - $selection->initFromHttpVars(); - $files = $selection->getFiles(); - AJXP_XMLWriter::header(); - foreach ($files as $index => $element){ - $element = basename($element); - $ar = explode("shared_", $mime); - $mime = array_pop($ar); - ShareCenter::deleteSharedElement($mime, $element, $loggedUser); - if($mime == "repository") $out = $mess["ajxp_conf.59"]; - else if($mime == "user") $out = $mess["ajxp_conf.60"]; - else if($mime == "file") $out = $mess["ajxp_shared.13"]; - } - AJXP_XMLWriter::sendMessage($out, null); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - break; - - case "clear_expired" : - - $deleted = $this->clearExpiredFiles(); - AJXP_XMLWriter::header(); - if(count($deleted)){ - AJXP_XMLWriter::sendMessage(sprintf($mess["ajxp_shared.23"], count($deleted).""), null); - AJXP_XMLWriter::reloadDataNode(); - }else{ - AJXP_XMLWriter::sendMessage($mess["ajxp_shared.24"], null); - } - AJXP_XMLWriter::close(); - - break; - - case "reset_download_counter" : - - $selection = new UserSelection(); - $selection->initFromHttpVars(); - $elements = $selection->getFiles(); - foreach ($elements as $element){ - PublicletCounter::reset(str_replace(".php", "", basename($element))); - } - AJXP_XMLWriter::header(); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - - break; - - default: - break; - } - - return; - } - - function listSharedFiles(){ - AJXP_XMLWriter::sendFilesListComponentConfig(' - - - - - - - '); - $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); - if(!is_dir($dlFolder)) return ; - $files = glob($dlFolder."/*.php"); - if(!is_array($files))return; - $mess = ConfService::getMessages(); - $loggedUser = AuthService::getLoggedUser(); - $userId = $loggedUser->getId(); - $dlURL = ConfService::getCoreConf("PUBLIC_DOWNLOAD_URL"); - if($dlURL!= ""){ - $downloadBase = rtrim($dlURL, "/"); - }else{ - $fullUrl = AJXP_Utils::detectServerURL() . dirname($_SERVER['REQUEST_URI']); - $downloadBase = str_replace("\\", "/", $fullUrl.rtrim(str_replace(AJXP_INSTALL_PATH, "", $dlFolder), "/")); - } - - foreach ($files as $file){ - $ar = explode(".", basename($file)); - $id = array_shift($ar); - if($ar[0] != "php") continue; - //if(strlen($id) != 32) continue; - $publicletData = ShareCenter::loadPublicletData($id); - if(isset($publicletData["OWNER_ID"]) && $publicletData["OWNER_ID"] != $userId){ - continue; - } - $expired = ($publicletData["EXPIRE_TIME"]!=0?($publicletData["EXPIRE_TIME"]getDisplay()).":/".SystemTextEncoding::toUTF8($publicletData["FILE_PATH"]), true, array( - "icon" => "html.png", - "password" => ($publicletData["PASSWORD"]!=""?$publicletData["PASSWORD"]:"-"), - "expiration" => ($publicletData["EXPIRE_TIME"]!=0?($expired?"[!]":"").date($mess["date_format"], $publicletData["EXPIRE_TIME"]):"-"), - "download_count" => $publicletData["DOWNLOAD_COUNT"], - "download_limit" => ($publicletData["DOWNLOAD_LIMIT"] == 0 ? "-" : $publicletData["DOWNLOAD_LIMIT"] ), - "integrity" => (!$publicletData["SECURITY_MODIFIED"]?$mess["ajxp_shared.15"]:$mess["ajxp_shared.16"]), - "download_url" => $downloadBase . "/".basename($file), - "ajxp_mime" => "shared_file") - ); - } - } - - function clearExpiredFiles(){ - $files = glob(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")."/*.php"); - $loggedUser = AuthService::getLoggedUser(); - $userId = $loggedUser->getId(); - $deleted = array(); - foreach ($files as $file){ - $ar = explode(".", basename($file)); - $id = array_shift($ar); - if(strlen($id) != 32) continue; - $publicletData = ShareCenter::loadPublicletData($id); - if(!isSet($publicletData["OWNER_ID"]) || $publicletData["OWNER_ID"] != $userId){ - continue; - } - if( (isSet($publicletData["EXPIRE_TIME"]) && is_numeric($publicletData["EXPIRE_TIME"]) && $publicletData["EXPIRE_TIME"] > 0 && $publicletData["EXPIRE_TIME"] < time()) || - (isSet($publicletData["DOWNLOAD_LIMIT"]) && $publicletData["DOWNLOAD_LIMIT"] > 0 && $publicletData["DOWNLOAD_LIMIT"] <= $publicletData["DOWNLOAD_COUNT"]) ) { - unlink($file); - $deleted[] = basename($file); - PublicletCounter::delete(str_replace(".php", "", basename($file))); - } - } - return $deleted; - } - - function listUsers(){ - AJXP_XMLWriter::sendFilesListComponentConfig(''); - if(!AuthService::usersEnabled()) return ; - $users = AuthService::listUsers(); - $mess = ConfService::getMessages(); - $loggedUser = AuthService::getLoggedUser(); - $repoList = ConfService::getRepositoriesList("all"); - $userArray = array(); - foreach ($users as $userIndex => $userObject){ - $label = $userObject->getId(); - if(!$userObject->hasParent() || $userObject->getParent() != $loggedUser->getId()) continue; - if($userObject->hasParent()){ - $label = $userObject->getParent()."000".$label; - } - $userArray[$label] = $userObject; - } - ksort($userArray); - foreach($userArray as $userObject) { - $isAdmin = $userObject->isAdmin(); - $userId = AJXP_Utils::xmlEntities($userObject->getId()); - $repoAccesses = array(); - foreach ($repoList as $repoObject) { - if($repoObject->hasOwner() && $repoObject->getOwner() == $loggedUser->getId()){ - $acl = $userObject->mergedRole->getAcl($repoObject->getId()); - if(!empty($acl)) $repoAccesses[] = $repoObject->getDisplay()." ($acl)"; - } - } - print ''; - } - } - - function listRepositories(){ - $repos = ConfService::getRepositoriesList("all"); - AJXP_XMLWriter::sendFilesListComponentConfig(''); - $repoArray = array(); - $childRepos = array(); - $loggedUser = AuthService::getLoggedUser(); - $users = AuthService::listUsers(); - foreach ($repos as $repoIndex => $repoObject){ - if($repoObject->getAccessType() == "ajxp_conf") continue; - if(!$repoObject->hasOwner() || $repoObject->getOwner() != $loggedUser->getId()){ - continue; - } - if(is_numeric($repoIndex)) $repoIndex = "".$repoIndex; - $name = AJXP_Utils::xmlEntities(SystemTextEncoding::toUTF8($repoObject->getDisplay())); - $repoArray[$name] = $repoIndex; - } - // Sort the list now by name - ksort($repoArray); - // Append child repositories - $sortedArray = array(); - foreach ($repoArray as $name => $repoIndex) { - $sortedArray[$name] = $repoIndex; - if(isSet($childRepos[$repoIndex]) && is_array($childRepos[$repoIndex])){ - foreach ($childRepos[$repoIndex] as $childData){ - $sortedArray[$childData["name"]] = $childData["index"]; - } - } - } - foreach ($sortedArray as $name => $repoIndex) { - $repoObject =& $repos[$repoIndex]; - $repoAccesses = array(); - foreach ($users as $userId => $userObject) { - //if(!$userObject->hasParent()) continue; - if($userObject->getId() == $loggedUser->getId()) continue; - $label = $userObject->personalRole->filterParameterValue("core.conf", "USER_DISPLAY_NAME", AJXP_REPO_SCOPE_ALL, $userId); - $acl = $userObject->mergedRole->getAcl($repoObject->getId()); - if(!empty($acl)) $repoAccesses[] = $label. " (".$acl.")"; - } - - $metaData = array( - "repository_id" => $repoIndex, - "accessType" => $repoObject->getAccessType(), - "icon" => "document_open_remote.png", - "openicon" => "document_open_remote.png", - "parentname" => "/repositories", - "repo_accesses" => implode(", ", $repoAccesses), - "ajxp_mime" => "shared_repository" - ); - AJXP_XMLWriter::renderNode("/repositories/$repoIndex", $name, true, $metaData); - } - } - -} - -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); +/** + * @package AjaXplorer_Plugins + * @subpackage Access + * @class ajxpSharedAccessDriver + * AJXP_Plugin to access the shared elements of the current user + */ +class ajxpSharedAccessDriver extends AbstractAccessDriver +{ + + public function initRepository() + { + require_once AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/action.share/class.ShareCenter.php"; + } + + public function switchAction($action, $httpVars, $fileVars) + { + if(!isSet($this->actions[$action])) return; + parent::accessPreprocess($action, $httpVars, $fileVars); + $loggedUser = AuthService::getLoggedUser(); + if(!AuthService::usersEnabled()) return ; + + if ($action == "edit") { + if (isSet($httpVars["sub_action"])) { + $action = $httpVars["sub_action"]; + } + } + $mess = ConfService::getMessages(); + + switch ($action) { + //------------------------------------ + // BASIC LISTING + //------------------------------------ + case "ls": + $rootNodes = array( + "files" => array("LABEL" => $mess["ajxp_shared.3"], "ICON" => "html.png", "DESCRIPTION" => $mess["ajxp_shared.28"]), + "repositories" => array("LABEL" => $mess["ajxp_shared.2"], "ICON" => "document_open_remote.png", "DESCRIPTION" => $mess["ajxp_shared.29"]), + "users" => array("LABEL" => $mess["ajxp_shared.1"], "ICON" => "user_shared.png", "DESCRIPTION" => $mess["ajxp_shared.30"]) + ); + $dir = (isset($httpVars["dir"])?$httpVars["dir"]:""); + $splits = explode("/", $dir); + if (count($splits)) { + if($splits[0] == "") array_shift($splits); + if(count($splits)) $strippedDir = strtolower(urldecode($splits[0])); + else $strippedDir = ""; + } + if (array_key_exists($strippedDir, $rootNodes)) { + AJXP_XMLWriter::header(); + if ($strippedDir == "users") { + $this->listUsers(); + } else if ($strippedDir == "repositories") { + $this->listRepositories(); + } else if ($strippedDir == "files") { + $this->listSharedFiles(); + } + AJXP_XMLWriter::close(); + exit(1); + } else { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendFilesListComponentConfig(''); + foreach ($rootNodes as $key => $data) { + print ''; + } + AJXP_XMLWriter::close(); + } + break; + + case "stat" : + + header("Content-type:application/json"); + print '{"mode":true}'; + + break; + + case "delete" : + $mime = $httpVars["ajxp_mime"]; + $selection = new UserSelection(); + $selection->initFromHttpVars(); + $files = $selection->getFiles(); + AJXP_XMLWriter::header(); + foreach ($files as $index => $element) { + $element = basename($element); + $ar = explode("shared_", $mime); + $mime = array_pop($ar); + ShareCenter::deleteSharedElement($mime, $element, $loggedUser); + if($mime == "repository") $out = $mess["ajxp_conf.59"]; + else if($mime == "user") $out = $mess["ajxp_conf.60"]; + else if($mime == "file") $out = $mess["ajxp_shared.13"]; + } + AJXP_XMLWriter::sendMessage($out, null); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + break; + + case "clear_expired" : + + $deleted = $this->clearExpiredFiles(); + AJXP_XMLWriter::header(); + if (count($deleted)) { + AJXP_XMLWriter::sendMessage(sprintf($mess["ajxp_shared.23"], count($deleted).""), null); + AJXP_XMLWriter::reloadDataNode(); + } else { + AJXP_XMLWriter::sendMessage($mess["ajxp_shared.24"], null); + } + AJXP_XMLWriter::close(); + + break; + + case "reset_download_counter" : + + $selection = new UserSelection(); + $selection->initFromHttpVars(); + $elements = $selection->getFiles(); + foreach ($elements as $element) { + PublicletCounter::reset(str_replace(".php", "", basename($element))); + } + AJXP_XMLWriter::header(); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + + break; + + default: + break; + } + + return; + } + + public function listSharedFiles() + { + AJXP_XMLWriter::sendFilesListComponentConfig(' + + + + + + + '); + $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); + if(!is_dir($dlFolder)) return ; + $files = glob($dlFolder."/*.php"); + if(!is_array($files))return; + $mess = ConfService::getMessages(); + $loggedUser = AuthService::getLoggedUser(); + $userId = $loggedUser->getId(); + $dlURL = ConfService::getCoreConf("PUBLIC_DOWNLOAD_URL"); + if ($dlURL!= "") { + $downloadBase = rtrim($dlURL, "/"); + } else { + $fullUrl = AJXP_Utils::detectServerURL() . dirname($_SERVER['REQUEST_URI']); + $downloadBase = str_replace("\\", "/", $fullUrl.rtrim(str_replace(AJXP_INSTALL_PATH, "", $dlFolder), "/")); + } + + foreach ($files as $file) { + $ar = explode(".", basename($file)); + $id = array_shift($ar); + if($ar[0] != "php") continue; + //if(strlen($id) != 32) continue; + $publicletData = ShareCenter::loadPublicletData($id); + if (isset($publicletData["OWNER_ID"]) && $publicletData["OWNER_ID"] != $userId) { + continue; + } + $expired = ($publicletData["EXPIRE_TIME"]!=0?($publicletData["EXPIRE_TIME"]getDisplay()).":/".SystemTextEncoding::toUTF8($publicletData["FILE_PATH"]), true, array( + "icon" => "html.png", + "password" => ($publicletData["PASSWORD"]!=""?$publicletData["PASSWORD"]:"-"), + "expiration" => ($publicletData["EXPIRE_TIME"]!=0?($expired?"[!]":"").date($mess["date_format"], $publicletData["EXPIRE_TIME"]):"-"), + "download_count" => $publicletData["DOWNLOAD_COUNT"], + "download_limit" => ($publicletData["DOWNLOAD_LIMIT"] == 0 ? "-" : $publicletData["DOWNLOAD_LIMIT"] ), + "integrity" => (!$publicletData["SECURITY_MODIFIED"]?$mess["ajxp_shared.15"]:$mess["ajxp_shared.16"]), + "download_url" => $downloadBase . "/".basename($file), + "ajxp_mime" => "shared_file") + ); + } + } + + public function clearExpiredFiles() + { + $files = glob(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")."/*.php"); + $loggedUser = AuthService::getLoggedUser(); + $userId = $loggedUser->getId(); + $deleted = array(); + foreach ($files as $file) { + $ar = explode(".", basename($file)); + $id = array_shift($ar); + if(strlen($id) != 32) continue; + $publicletData = ShareCenter::loadPublicletData($id); + if (!isSet($publicletData["OWNER_ID"]) || $publicletData["OWNER_ID"] != $userId) { + continue; + } + if( (isSet($publicletData["EXPIRE_TIME"]) && is_numeric($publicletData["EXPIRE_TIME"]) && $publicletData["EXPIRE_TIME"] > 0 && $publicletData["EXPIRE_TIME"] < time()) || + (isSet($publicletData["DOWNLOAD_LIMIT"]) && $publicletData["DOWNLOAD_LIMIT"] > 0 && $publicletData["DOWNLOAD_LIMIT"] <= $publicletData["DOWNLOAD_COUNT"]) ) { + unlink($file); + $deleted[] = basename($file); + PublicletCounter::delete(str_replace(".php", "", basename($file))); + } + } + return $deleted; + } + + public function listUsers() + { + AJXP_XMLWriter::sendFilesListComponentConfig(''); + if(!AuthService::usersEnabled()) return ; + $users = AuthService::listUsers(); + $mess = ConfService::getMessages(); + $loggedUser = AuthService::getLoggedUser(); + $repoList = ConfService::getRepositoriesList("all"); + $userArray = array(); + foreach ($users as $userIndex => $userObject) { + $label = $userObject->getId(); + if(!$userObject->hasParent() || $userObject->getParent() != $loggedUser->getId()) continue; + if ($userObject->hasParent()) { + $label = $userObject->getParent()."000".$label; + } + $userArray[$label] = $userObject; + } + ksort($userArray); + foreach ($userArray as $userObject) { + $isAdmin = $userObject->isAdmin(); + $userId = AJXP_Utils::xmlEntities($userObject->getId()); + $repoAccesses = array(); + foreach ($repoList as $repoObject) { + if ($repoObject->hasOwner() && $repoObject->getOwner() == $loggedUser->getId()) { + $acl = $userObject->mergedRole->getAcl($repoObject->getId()); + if(!empty($acl)) $repoAccesses[] = $repoObject->getDisplay()." ($acl)"; + } + } + print ''; + } + } + + public function listRepositories() + { + $repos = ConfService::getRepositoriesList("all"); + AJXP_XMLWriter::sendFilesListComponentConfig(''); + $repoArray = array(); + $childRepos = array(); + $loggedUser = AuthService::getLoggedUser(); + $users = AuthService::listUsers(); + foreach ($repos as $repoIndex => $repoObject) { + if($repoObject->getAccessType() == "ajxp_conf") continue; + if (!$repoObject->hasOwner() || $repoObject->getOwner() != $loggedUser->getId()) { + continue; + } + if(is_numeric($repoIndex)) $repoIndex = "".$repoIndex; + $name = AJXP_Utils::xmlEntities(SystemTextEncoding::toUTF8($repoObject->getDisplay())); + $repoArray[$name] = $repoIndex; + } + // Sort the list now by name + ksort($repoArray); + // Append child repositories + $sortedArray = array(); + foreach ($repoArray as $name => $repoIndex) { + $sortedArray[$name] = $repoIndex; + if (isSet($childRepos[$repoIndex]) && is_array($childRepos[$repoIndex])) { + foreach ($childRepos[$repoIndex] as $childData) { + $sortedArray[$childData["name"]] = $childData["index"]; + } + } + } + foreach ($sortedArray as $name => $repoIndex) { + $repoObject =& $repos[$repoIndex]; + $repoAccesses = array(); + foreach ($users as $userId => $userObject) { + //if(!$userObject->hasParent()) continue; + if($userObject->getId() == $loggedUser->getId()) continue; + $label = $userObject->personalRole->filterParameterValue("core.conf", "USER_DISPLAY_NAME", AJXP_REPO_SCOPE_ALL, $userId); + $acl = $userObject->mergedRole->getAcl($repoObject->getId()); + if(!empty($acl)) $repoAccesses[] = $label. " (".$acl.")"; + } + + $metaData = array( + "repository_id" => $repoIndex, + "accessType" => $repoObject->getAccessType(), + "icon" => "document_open_remote.png", + "openicon" => "document_open_remote.png", + "parentname" => "/repositories", + "repo_accesses" => implode(", ", $repoAccesses), + "ajxp_mime" => "shared_repository" + ); + AJXP_XMLWriter::renderNode("/repositories/$repoIndex", $name, true, $metaData); + } + } + +} diff --git a/core/src/plugins/access.ajxp_shared/i18n/de.php b/core/src/plugins/access.ajxp_shared/i18n/de.php index ecd99a59cd..eae5d74af4 100644 --- a/core/src/plugins/access.ajxp_shared/i18n/de.php +++ b/core/src/plugins/access.ajxp_shared/i18n/de.php @@ -52,5 +52,4 @@ "31"=> "Beschreibung", "32"=> "Zurücksetzen", "33"=> "Download-Zähler zurücksetzen", -); -?> +); diff --git a/core/src/plugins/access.ajxp_shared/i18n/en.php b/core/src/plugins/access.ajxp_shared/i18n/en.php index e8144055bb..e9e563d5a3 100644 --- a/core/src/plugins/access.ajxp_shared/i18n/en.php +++ b/core/src/plugins/access.ajxp_shared/i18n/en.php @@ -52,5 +52,4 @@ "31"=> "Description", "32"=> "Reset", "33"=> "Reset download counter", -); -?> +); diff --git a/core/src/plugins/access.ajxp_shared/i18n/es.php b/core/src/plugins/access.ajxp_shared/i18n/es.php index 80a9e26f46..12761ad5c1 100644 --- a/core/src/plugins/access.ajxp_shared/i18n/es.php +++ b/core/src/plugins/access.ajxp_shared/i18n/es.php @@ -1,58 +1,57 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - // spanish translation: Ion Rey Bakaikoa , 2010 -// spanish corrections: Cristóbal Sabroe Yde , 2010 -$mess=array( -"1" => "Usuarios compartidos", -"2" => "Repositorios compartidos", -"3" => "Archivos públicos", -"4" => "Camino del archivo", -"5" => "Repositorio", -"6" => "Contraseña", -"7" => "Caduca", -"8" => "Elementos", -"9" => "Usuarios asociados", -"10"=> "Repositorios asociados", -"11"=> "¿Está seguro de que quiere borrar los elemento selecionado?", -"12"=> "No tienes permiso para borrar este elemento.", -"13"=> "Se ha borrado el archivo público.", -"14"=> "Integridad", -"15"=> "Ok", -"16"=> "Roto", -"17"=> "Descargar URL", -"18"=> "Copiar URL", -"19"=> "Copiar url para enviar email.", -"20"=> "Descargas", -"21"=> "Si", -"22"=> "No", -"23"=> "Se han borrado %s archivos.", -"24"=> "Nada para borrar.", -"25"=> "Limpiar caducados", -"26"=> "Borra archivos caducados.", -"27"=> "Dueño", -"28"=> "Archivos compartidos para descargas directas, con o sin contraseñaa.", -"29"=> "Repositorios delegados creados por usuarios.", -"30"=> "Usuarios creados para acceder a repositorios delegados.", -"31"=> "Descripción", -"32"=> "Resetear", -"33"=> "Resetear el contador de descargas", -); -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + // spanish translation: Ion Rey Bakaikoa , 2010 +// spanish corrections: Cristóbal Sabroe Yde , 2010 +$mess=array( +"1" => "Usuarios compartidos", +"2" => "Repositorios compartidos", +"3" => "Archivos públicos", +"4" => "Camino del archivo", +"5" => "Repositorio", +"6" => "Contraseña", +"7" => "Caduca", +"8" => "Elementos", +"9" => "Usuarios asociados", +"10"=> "Repositorios asociados", +"11"=> "¿Está seguro de que quiere borrar los elemento selecionado?", +"12"=> "No tienes permiso para borrar este elemento.", +"13"=> "Se ha borrado el archivo público.", +"14"=> "Integridad", +"15"=> "Ok", +"16"=> "Roto", +"17"=> "Descargar URL", +"18"=> "Copiar URL", +"19"=> "Copiar url para enviar email.", +"20"=> "Descargas", +"21"=> "Si", +"22"=> "No", +"23"=> "Se han borrado %s archivos.", +"24"=> "Nada para borrar.", +"25"=> "Limpiar caducados", +"26"=> "Borra archivos caducados.", +"27"=> "Dueño", +"28"=> "Archivos compartidos para descargas directas, con o sin contraseñaa.", +"29"=> "Repositorios delegados creados por usuarios.", +"30"=> "Usuarios creados para acceder a repositorios delegados.", +"31"=> "Descripción", +"32"=> "Resetear", +"33"=> "Resetear el contador de descargas", +); diff --git a/core/src/plugins/access.ajxp_shared/i18n/fr.php b/core/src/plugins/access.ajxp_shared/i18n/fr.php index 913f3804b3..2da4cf369c 100644 --- a/core/src/plugins/access.ajxp_shared/i18n/fr.php +++ b/core/src/plugins/access.ajxp_shared/i18n/fr.php @@ -52,5 +52,4 @@ "31"=> "Description", "32"=> "RàZ", "33"=> "Remise à zéro du compteur", -); -?> +); diff --git a/core/src/plugins/access.ajxp_shared/i18n/hu.php b/core/src/plugins/access.ajxp_shared/i18n/hu.php index 9ba6e17d51..927978ce73 100644 --- a/core/src/plugins/access.ajxp_shared/i18n/hu.php +++ b/core/src/plugins/access.ajxp_shared/i18n/hu.php @@ -55,5 +55,4 @@ "31"=> "Leírás", "32"=> "Nullázás", "33"=> "A letöltésszámláló nullázása", -); -?> +); diff --git a/core/src/plugins/access.ajxp_shared/i18n/pt.php b/core/src/plugins/access.ajxp_shared/i18n/pt.php index 65f5655470..92eaf9db3f 100644 --- a/core/src/plugins/access.ajxp_shared/i18n/pt.php +++ b/core/src/plugins/access.ajxp_shared/i18n/pt.php @@ -52,5 +52,4 @@ "31"=> "Descrição", "32"=> "Repor", "33"=> "Repor Contador de Transferências", -); -?> +); diff --git a/core/src/plugins/access.ajxp_shared/i18n/si.php b/core/src/plugins/access.ajxp_shared/i18n/si.php index 0d317346f4..ce7308c238 100644 --- a/core/src/plugins/access.ajxp_shared/i18n/si.php +++ b/core/src/plugins/access.ajxp_shared/i18n/si.php @@ -53,5 +53,4 @@ "31"=> "Opis", "32"=> "Ponastavi", "33"=> "Ponastavi števec prenosov", -); -?> +); diff --git a/core/src/plugins/access.ajxp_shared/manifest.xml b/core/src/plugins/access.ajxp_shared/manifest.xml index f86fcff7b9..e1b7f2dda6 100644 --- a/core/src/plugins/access.ajxp_shared/manifest.xml +++ b/core/src/plugins/access.ajxp_shared/manifest.xml @@ -2,7 +2,7 @@ - + @@ -17,7 +17,7 @@ ]]> - + 0){ path = window.actionArguments[0]; if(Object.isString(path)){path = new AjxpNode(path,false,getBaseName(path));} @@ -44,7 +44,7 @@ } if(path){ ajaxplorer.updateContextData(path); - } + } ]]> @@ -53,9 +53,9 @@ - - - + + + @@ -127,8 +127,8 @@ - - + + ]]> - + - + - \ No newline at end of file + diff --git a/core/src/plugins/access.demo/class.demoAccessDriver.php b/core/src/plugins/access.demo/class.demoAccessDriver.php index be026ae1c4..48467bf722 100644 --- a/core/src/plugins/access.demo/class.demoAccessDriver.php +++ b/core/src/plugins/access.demo/class.demoAccessDriver.php @@ -1,76 +1,74 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * @package AjaXplorer_Plugins - * @subpackage Access - * @class demoAccessDriver - * AJXP_Plugin to access a filesystem with all write actions disabled - */ -class demoAccessDriver extends fsAccessDriver -{ - /** - * @var Repository - */ - var $repository; - - function switchAction($action, $httpVars, $fileVars){ - if(!isSet($this->actions[$action])) return; - $errorMessage = "This is a demo, all 'write' actions are disabled!"; - switch($action) - { - //------------------------------------ - // WRITE ACTIONS - //------------------------------------ - case "put_content": - case "copy": - case "move": - case "rename": - case "delete": - case "mkdir": - case "mkfile": - case "chmod": - case "compress": - return AJXP_XMLWriter::sendMessage(null, $errorMessage, false); - break; - - //------------------------------------ - // UPLOAD - //------------------------------------ - case "upload": - - return array("ERROR" => array("CODE" => "", "MESSAGE" => $errorMessage)); - - break; - - default: - break; - } - - return parent::switchAction($action, $httpVars, $fileVars); - - } - -} - -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * @package AjaXplorer_Plugins + * @subpackage Access + * @class demoAccessDriver + * AJXP_Plugin to access a filesystem with all write actions disabled + */ +class demoAccessDriver extends fsAccessDriver +{ + /** + * @var Repository + */ + public $repository; + + public function switchAction($action, $httpVars, $fileVars) + { + if(!isSet($this->actions[$action])) return; + $errorMessage = "This is a demo, all 'write' actions are disabled!"; + switch ($action) { + //------------------------------------ + // WRITE ACTIONS + //------------------------------------ + case "put_content": + case "copy": + case "move": + case "rename": + case "delete": + case "mkdir": + case "mkfile": + case "chmod": + case "compress": + return AJXP_XMLWriter::sendMessage(null, $errorMessage, false); + break; + + //------------------------------------ + // UPLOAD + //------------------------------------ + case "upload": + + return array("ERROR" => array("CODE" => "", "MESSAGE" => $errorMessage)); + + break; + + default: + break; + } + + return parent::switchAction($action, $httpVars, $fileVars); + + } + +} diff --git a/core/src/plugins/access.demo/i18n/conf/de.php b/core/src/plugins/access.demo/i18n/conf/de.php index e649007939..2f25b97627 100644 --- a/core/src/plugins/access.demo/i18n/conf/de.php +++ b/core/src/plugins/access.demo/i18n/conf/de.php @@ -28,4 +28,3 @@ "Recycle Bin Folder" => "Papierkorb-Verzeichnis", "Leave empty if you do not want to use a recycle bin." => "Leerlassen um kein Papierkorb zu verwenden.", ); -?> diff --git a/core/src/plugins/access.demo/i18n/conf/en.php b/core/src/plugins/access.demo/i18n/conf/en.php index 1bc2aec8d1..b5b73bf89f 100644 --- a/core/src/plugins/access.demo/i18n/conf/en.php +++ b/core/src/plugins/access.demo/i18n/conf/en.php @@ -28,4 +28,3 @@ "Recycle Bin Folder" => "Recycle Bin Folder", "Leave empty if you do not want to use a recycle bin." => "Leave empty if you do not want to use a recycle bin.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.demo/i18n/conf/fr.php b/core/src/plugins/access.demo/i18n/conf/fr.php index a0f50471e1..00d9cc2fad 100644 --- a/core/src/plugins/access.demo/i18n/conf/fr.php +++ b/core/src/plugins/access.demo/i18n/conf/fr.php @@ -28,4 +28,3 @@ "Recycle Bin Folder" => "Corbeille", "Leave empty if you do not want to use a recycle bin." => "Laisser vide si pas de corbeille", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.demo/manifest.xml b/core/src/plugins/access.demo/manifest.xml index 689eba2081..3b2216fdcf 100644 --- a/core/src/plugins/access.demo/manifest.xml +++ b/core/src/plugins/access.demo/manifest.xml @@ -12,9 +12,9 @@ - + - + @@ -25,4 +25,4 @@ - \ No newline at end of file + diff --git a/core/src/plugins/access.dropbox/class.dropboxAccessDriver.php b/core/src/plugins/access.dropbox/class.dropboxAccessDriver.php index d03bd6a3fa..3281dca7ed 100644 --- a/core/src/plugins/access.dropbox/class.dropboxAccessDriver.php +++ b/core/src/plugins/access.dropbox/class.dropboxAccessDriver.php @@ -1,116 +1,119 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * AJXP_Plugin to access a dropbox account - * @package AjaXplorer_Plugins - * @subpackage Access - */ -class dropboxAccessDriver extends fsAccessDriver -{ - /** - * @var Repository - */ - public $repository; - public $driverConf; - protected $wrapperClassName; - protected $urlBase; - - function initRepository(){ - if(is_array($this->pluginConf)){ - $this->driverConf = $this->pluginConf; - }else{ - $this->driverConf = array(); - } - - $wrapperData = $this->detectStreamWrapper(true); - AJXP_Logger::debug("Detected wrapper data", $wrapperData); - $this->wrapperClassName = $wrapperData["classname"]; - $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); - - $consumerKey = $this->repository->getOption("CONSUMER_KEY"); - $consumerSecret = $this->repository->getOption("CONSUMER_SECRET"); - $oauth = new Dropbox_OAuth_PEAR($consumerKey, $consumerSecret); - - // TOKENS IN SESSION? - if(!empty($_SESSION["OAUTH_DROPBOX_TOKENS"])) return; - - // TOKENS IN FILE ? - $tokens = $this->getTokens($this->repository->getId()); - if(!empty($tokens)){ - $_SESSION["OAUTH_DROPBOX_TOKENS"] = $tokens; - return; - } - - // OAUTH NEGOCIATION - if (isset($_SESSION['DROPBOX_NEGOCIATION_STATE'])) { - $state = $_SESSION['DROPBOX_NEGOCIATION_STATE']; - } else { - $state = 1; - } - switch($state) { - - case 1 : - $tokens = $oauth->getRequestToken(); - //print_r($tokens); - - // Note that if you want the user to automatically redirect back, you can - // add the 'callback' argument to getAuthorizeUrl. - //echo "Step 2: You must now redirect the user to:\n"; - $_SESSION['DROPBOX_NEGOCIATION_STATE'] = 2; - $_SESSION['oauth_tokens'] = $tokens; - throw new Exception("Please go to getAuthorizeUrl()."\">".$oauth->getAuthorizeUrl()." to authorize the access to your dropbox. Then try again to switch to this repository."); - - case 2 : - $oauth->setToken($_SESSION['oauth_tokens']); - $tokens = $oauth->getAccessToken(); - $_SESSION['DROPBOX_NEGOCIATION_STATE'] = 3; - $_SESSION['OAUTH_DROPBOX_TOKENS'] = $tokens; - $this->setTokens($this->repository->getId(), $tokens); - return; - } - - throw new Exception("Impossible to find the tokens for accessing the dropbox repository"); - - } - - function performChecks(){ - if(!AJXP_Utils::searchIncludePath('HTTP/OAuth/Consumer.php')){ - throw new Exception("The PEAR HTTP_OAuth package must be installed!"); - } - } - - function isWriteable($dir, $type = "dir"){ - return true; - } - - function getTokens($repositoryId){ - return AJXP_Utils::loadSerialFile(AJXP_DATA_PATH."/plugins/access.dropbox/".$repositoryId."_tokens"); - } - function setTokens($repositoryId, $oauth_tokens){ - return AJXP_Utils::saveSerialFile(AJXP_DATA_PATH."/plugins/access.dropbox/".$repositoryId."_tokens", $oauth_tokens, true); - } - -} - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * AJXP_Plugin to access a dropbox account + * @package AjaXplorer_Plugins + * @subpackage Access + */ +class dropboxAccessDriver extends fsAccessDriver +{ + /** + * @var Repository + */ + public $repository; + public $driverConf; + protected $wrapperClassName; + protected $urlBase; + + public function initRepository() + { + if (is_array($this->pluginConf)) { + $this->driverConf = $this->pluginConf; + } else { + $this->driverConf = array(); + } + + $wrapperData = $this->detectStreamWrapper(true); + AJXP_Logger::debug("Detected wrapper data", $wrapperData); + $this->wrapperClassName = $wrapperData["classname"]; + $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); + + $consumerKey = $this->repository->getOption("CONSUMER_KEY"); + $consumerSecret = $this->repository->getOption("CONSUMER_SECRET"); + $oauth = new Dropbox_OAuth_PEAR($consumerKey, $consumerSecret); + + // TOKENS IN SESSION? + if(!empty($_SESSION["OAUTH_DROPBOX_TOKENS"])) return; + + // TOKENS IN FILE ? + $tokens = $this->getTokens($this->repository->getId()); + if (!empty($tokens)) { + $_SESSION["OAUTH_DROPBOX_TOKENS"] = $tokens; + return; + } + + // OAUTH NEGOCIATION + if (isset($_SESSION['DROPBOX_NEGOCIATION_STATE'])) { + $state = $_SESSION['DROPBOX_NEGOCIATION_STATE']; + } else { + $state = 1; + } + switch ($state) { + + case 1 : + $tokens = $oauth->getRequestToken(); + //print_r($tokens); + + // Note that if you want the user to automatically redirect back, you can + // add the 'callback' argument to getAuthorizeUrl. + //echo "Step 2: You must now redirect the user to:\n"; + $_SESSION['DROPBOX_NEGOCIATION_STATE'] = 2; + $_SESSION['oauth_tokens'] = $tokens; + throw new Exception("Please go to getAuthorizeUrl()."\">".$oauth->getAuthorizeUrl()." to authorize the access to your dropbox. Then try again to switch to this repository."); + + case 2 : + $oauth->setToken($_SESSION['oauth_tokens']); + $tokens = $oauth->getAccessToken(); + $_SESSION['DROPBOX_NEGOCIATION_STATE'] = 3; + $_SESSION['OAUTH_DROPBOX_TOKENS'] = $tokens; + $this->setTokens($this->repository->getId(), $tokens); + return; + } + + throw new Exception("Impossible to find the tokens for accessing the dropbox repository"); + + } + + public function performChecks() + { + if (!AJXP_Utils::searchIncludePath('HTTP/OAuth/Consumer.php')) { + throw new Exception("The PEAR HTTP_OAuth package must be installed!"); + } + } + + public function isWriteable($dir, $type = "dir") + { + return true; + } + + public function getTokens($repositoryId) + { + return AJXP_Utils::loadSerialFile(AJXP_DATA_PATH."/plugins/access.dropbox/".$repositoryId."_tokens"); + } + public function setTokens($repositoryId, $oauth_tokens) + { + return AJXP_Utils::saveSerialFile(AJXP_DATA_PATH."/plugins/access.dropbox/".$repositoryId."_tokens", $oauth_tokens, true); + } + +} diff --git a/core/src/plugins/access.dropbox/class.dropboxWrapper.php b/core/src/plugins/access.dropbox/class.dropboxWrapper.php index e3cb4dd04d..009e53b0f4 100644 --- a/core/src/plugins/access.dropbox/class.dropboxWrapper.php +++ b/core/src/plugins/access.dropbox/class.dropboxWrapper.php @@ -1,264 +1,289 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - - -require_once (AJXP_INSTALL_PATH.'/plugins/access.dropbox/dropbox-php/autoload.php'); -require_once (AJXP_BIN_FOLDER.'/interface.AjxpWrapper.php'); - -/** - * AjxpWrapper encapsulation the PHP Dropbox client - * @package AjaXplorer_Plugins - * @subpackage Access - */ -class dropboxWrapper implements AjxpWrapper { - - /** - * - * @var Dropbox_API - */ - private static $dropbox; - private static $oauth; - - private static $crtDirContent = array(); - private static $crtDirIndex = 0; - - private static $crtHandle; - private static $crtTmpFile; - private static $crtWritePath; - - function __construct() { - } - - public function initPath($ajxpPath){ - if(empty(self::$dropbox)){ - $repo = ConfService::getRepository(); - $consumerKey = $repo->getOption('CONSUMER_KEY'); - $consumerSecret = $repo->getOption('CONSUMER_SECRET'); - $email = $repo->getOption('USER'); - $pass = $repo->getOption("PASS"); - - self::$oauth = new Dropbox_OAuth_PEAR($consumerKey, $consumerSecret); - self::$oauth->setToken($_SESSION["OAUTH_DROPBOX_TOKENS"]); - self::$dropbox = new Dropbox_API(self::$oauth); - } - $path = parse_url($ajxpPath, PHP_URL_PATH); - if($path == "") return "/"; - return $path; - } - - static function staticInitPath($ajxpPath){ - $tmpObject = new dropboxWrapper(); - return $tmpObject->initPath($ajxpPath); - } - - protected function metadataToStat($metaEntry){ - AJXP_Logger::debug("Stating ", $metaEntry); - $mode = 0666; - if(intval($metaEntry["is_dir"]) == 1) $mode += 0040000; - else $mode += 0100000; - $time = strtotime($metaEntry["modified"]); - $size = intval($metaEntry["bytes"]); - $keys = array( - 'dev' => 0, - 'ino' => 0, - 'mode' => $mode, - 'nlink' => 0, - 'uid' => 0, - 'gid' => 0, - 'rdev' => 0, - 'size' => $size, - 'atime' => $time, - 'mtime' => $time, - 'ctime' => $time, - 'blksize' => 0, - 'blocks' => 0 - ); - AJXP_Logger::debug("Stat value", $keys); - return $keys; - } - - static public function copyFileInStream($path, $stream) { - $path = self::staticInitPath($path); - $data = self::$dropbox->getFile($path); - fwrite($stream, $data, strlen($data)); - } - - static public function isRemote(){ - return true; - } - - static public function getRealFSReference($path) { - $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".rand(); - $path = self::staticInitPath($path); - file_put_contents($tmpFile, self::$dropbox->getFile($path)); - return $tmpFile; - } - - static public function changeMode($path, $chmodValue) { - - } - - - public function rename($path_from, $path_to) { - $path1 = $this->initPath($path_from); - $path2 = $this->initPath($path_to); - self::$dropbox->copy($path1, $path2); - self::$dropbox->delete($path1); - } - - public function mkdir($path, $mode, $options) { - $path = $this->initPath($path); - try{ - self::$dropbox->createFolder($path); - }catch (Dropbox_Exception $e){ - return false; - } - return true; - } - - public function rmdir($path, $options) { - $path = $this->initPath($path); - try{ - self::$dropbox->delete($path); - }catch (Dropbox_Exception $e){ - return false; - } - return true; - } - - public function unlink($path) { - $path = $this->initPath($path); - try{ - self::$dropbox->delete($path); - }catch (Dropbox_Exception $e){ - return false; - } - return true; - } - - public function url_stat($path, $flags) { - AJXP_Logger::debug("STATING $path"); - $path = $this->initPath($path); - $meta = null; - if(self::$crtDirContent != null){ - foreach (self::$crtDirContent as $metaEntry){ - if($metaEntry["path"] == $path){ - $metaEntry = $meta; - break; - } - } - } - if(empty($meta)){ - try{ - $meta = self::$dropbox->getMetaData($path); - }catch(Dropbox_Exception_NotFound $nf){ - return false; - } - } - return $this->metadataToStat($meta); - } - - public function dir_opendir($path, $options) { - $path = $this->initPath($path); - $metadata = self::$dropbox->getMetaData($path); - AJXP_Logger::debug("CONTENT for $path", $metadata); - self::$crtDirContent = $metadata["contents"]; - if(!is_array(self::$crtDirContent)){ - return false; - } - return true; - } - - public function dir_readdir() { - //return false; - if(self::$crtDirIndex == count(self::$crtDirContent)-1) return false; - $meta = self::$crtDirContent[self::$crtDirIndex]; - self::$crtDirIndex ++; - return basename($meta["path"]); - } - - public function dir_rewinddir() { - self::$crtDirIndex = 0; - } - - public function dir_closedir() { - self::$crtDirContent = array(); - self::$crtDirIndex = 0; - } - - - public function stream_flush() { - return fflush(self::$crtHandle); - } - - public function stream_read($count) { - return fread(self::$crtHandle, $count); - } - - public function stream_seek($offset, $whence = SEEK_SET) { - return fseek(self::$crtHandle, $offset, $whence); - } - - public function stream_write($data) { - return fwrite(self::$crtHandle, $data); - } - - public function stream_close() { - $res = fclose(self::$crtHandle); - if(self::$crtWritePath != null){ - $path = $this->initPath(self::$crtWritePath); - try{ - $postRes = self::$dropbox->putFile($path, self::$crtTmpFile); - AJXP_Logger::debug("Post to $path succeeded:"); - }catch(Dropbox_Exception $dE){ - AJXP_Logger::debug("Post to $path failed :".$dE->getMessage()); - } - } - unlink(self::$crtTmpFile); - return $res; - } - - public function stream_tell() { - return ftell(self::$crtHandle); - } - - public function stream_eof() { - return feof(self::$crtHandle); - } - - public function stream_stat() { - return true; - } - - public function stream_open($path, $mode, $options, &$opened_path) { - if(strstr($mode, "r") !== false){ - self::$crtTmpFile = self::getRealFSReference($path); - self::$crtWritePath = null; - }else{ - self::$crtTmpFile = AJXP_Utils::getAjxpTmpDir()."/".rand(); - self::$crtWritePath = $path; - } - self::$crtHandle = fopen(self::$crtTmpFile, $mode); - return true; - } -} + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + + +require_once (AJXP_INSTALL_PATH.'/plugins/access.dropbox/dropbox-php/autoload.php'); +require_once (AJXP_BIN_FOLDER.'/interface.AjxpWrapper.php'); + +/** + * AjxpWrapper encapsulation the PHP Dropbox client + * @package AjaXplorer_Plugins + * @subpackage Access + */ +class dropboxWrapper implements AjxpWrapper +{ + /** + * + * @var Dropbox_API + */ + private static $dropbox; + private static $oauth; + + private static $crtDirContent = array(); + private static $crtDirIndex = 0; + + private static $crtHandle; + private static $crtTmpFile; + private static $crtWritePath; + + public function __construct() + { + } + + public function initPath($ajxpPath) + { + if (empty(self::$dropbox)) { + $repo = ConfService::getRepository(); + $consumerKey = $repo->getOption('CONSUMER_KEY'); + $consumerSecret = $repo->getOption('CONSUMER_SECRET'); + $email = $repo->getOption('USER'); + $pass = $repo->getOption("PASS"); + + self::$oauth = new Dropbox_OAuth_PEAR($consumerKey, $consumerSecret); + self::$oauth->setToken($_SESSION["OAUTH_DROPBOX_TOKENS"]); + self::$dropbox = new Dropbox_API(self::$oauth); + } + $path = parse_url($ajxpPath, PHP_URL_PATH); + if($path == "") return "/"; + return $path; + } + + public static function staticInitPath($ajxpPath) + { + $tmpObject = new dropboxWrapper(); + return $tmpObject->initPath($ajxpPath); + } + + protected function metadataToStat($metaEntry) + { + AJXP_Logger::debug("Stating ", $metaEntry); + $mode = 0666; + if(intval($metaEntry["is_dir"]) == 1) $mode += 0040000; + else $mode += 0100000; + $time = strtotime($metaEntry["modified"]); + $size = intval($metaEntry["bytes"]); + $keys = array( + 'dev' => 0, + 'ino' => 0, + 'mode' => $mode, + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => $size, + 'atime' => $time, + 'mtime' => $time, + 'ctime' => $time, + 'blksize' => 0, + 'blocks' => 0 + ); + AJXP_Logger::debug("Stat value", $keys); + return $keys; + } + + public static function copyFileInStream($path, $stream) + { + $path = self::staticInitPath($path); + $data = self::$dropbox->getFile($path); + fwrite($stream, $data, strlen($data)); + } + + public static function isRemote() + { + return true; + } + + public static function getRealFSReference($path) + { + $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".rand(); + $path = self::staticInitPath($path); + file_put_contents($tmpFile, self::$dropbox->getFile($path)); + return $tmpFile; + } + + public static function changeMode($path, $chmodValue) + { + } + + + public function rename($path_from, $path_to) + { + $path1 = $this->initPath($path_from); + $path2 = $this->initPath($path_to); + self::$dropbox->copy($path1, $path2); + self::$dropbox->delete($path1); + } + + public function mkdir($path, $mode, $options) + { + $path = $this->initPath($path); + try { + self::$dropbox->createFolder($path); + } catch (Dropbox_Exception $e) { + return false; + } + return true; + } + + public function rmdir($path, $options) + { + $path = $this->initPath($path); + try { + self::$dropbox->delete($path); + } catch (Dropbox_Exception $e) { + return false; + } + return true; + } + + public function unlink($path) + { + $path = $this->initPath($path); + try { + self::$dropbox->delete($path); + } catch (Dropbox_Exception $e) { + return false; + } + return true; + } + + public function url_stat($path, $flags) + { + AJXP_Logger::debug("STATING $path"); + $path = $this->initPath($path); + $meta = null; + if (self::$crtDirContent != null) { + foreach (self::$crtDirContent as $metaEntry) { + if ($metaEntry["path"] == $path) { + $metaEntry = $meta; + break; + } + } + } + if (empty($meta)) { + try { + $meta = self::$dropbox->getMetaData($path); + } catch (Dropbox_Exception_NotFound $nf) { + return false; + } + } + return $this->metadataToStat($meta); + } + + public function dir_opendir($path, $options) + { + $path = $this->initPath($path); + $metadata = self::$dropbox->getMetaData($path); + AJXP_Logger::debug("CONTENT for $path", $metadata); + self::$crtDirContent = $metadata["contents"]; + if (!is_array(self::$crtDirContent)) { + return false; + } + return true; + } + + public function dir_readdir() + { + //return false; + if(self::$crtDirIndex == count(self::$crtDirContent)-1) return false; + $meta = self::$crtDirContent[self::$crtDirIndex]; + self::$crtDirIndex ++; + return basename($meta["path"]); + } + + public function dir_rewinddir() + { + self::$crtDirIndex = 0; + } + + public function dir_closedir() + { + self::$crtDirContent = array(); + self::$crtDirIndex = 0; + } + + + public function stream_flush() + { + return fflush(self::$crtHandle); + } + + public function stream_read($count) + { + return fread(self::$crtHandle, $count); + } + + public function stream_seek($offset, $whence = SEEK_SET) + { + return fseek(self::$crtHandle, $offset, $whence); + } + + public function stream_write($data) + { + return fwrite(self::$crtHandle, $data); + } + + public function stream_close() + { + $res = fclose(self::$crtHandle); + if (self::$crtWritePath != null) { + $path = $this->initPath(self::$crtWritePath); + try { + $postRes = self::$dropbox->putFile($path, self::$crtTmpFile); + AJXP_Logger::debug("Post to $path succeeded:"); + } catch (Dropbox_Exception $dE) { + AJXP_Logger::debug("Post to $path failed :".$dE->getMessage()); + } + } + unlink(self::$crtTmpFile); + return $res; + } + + public function stream_tell() + { + return ftell(self::$crtHandle); + } + + public function stream_eof() + { + return feof(self::$crtHandle); + } + + public function stream_stat() + { + return true; + } + + public function stream_open($path, $mode, $options, &$opened_path) + { + if (strstr($mode, "r") !== false) { + self::$crtTmpFile = self::getRealFSReference($path); + self::$crtWritePath = null; + } else { + self::$crtTmpFile = AJXP_Utils::getAjxpTmpDir()."/".rand(); + self::$crtWritePath = $path; + } + self::$crtHandle = fopen(self::$crtTmpFile, $mode); + return true; + } +} diff --git a/core/src/plugins/access.dropbox/i18n/conf/de.php b/core/src/plugins/access.dropbox/i18n/conf/de.php index dfeb2b482d..248daf3f83 100644 --- a/core/src/plugins/access.dropbox/i18n/conf/de.php +++ b/core/src/plugins/access.dropbox/i18n/conf/de.php @@ -30,4 +30,3 @@ "Password" => "Passwort", "User Password" => "Benutzer Passwort", ); -?> diff --git a/core/src/plugins/access.dropbox/i18n/conf/en.php b/core/src/plugins/access.dropbox/i18n/conf/en.php index 0b4b3be855..d6617067ca 100644 --- a/core/src/plugins/access.dropbox/i18n/conf/en.php +++ b/core/src/plugins/access.dropbox/i18n/conf/en.php @@ -30,4 +30,3 @@ "Password" => "Password", "User Password" => "User Password", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.dropbox/i18n/conf/fr.php b/core/src/plugins/access.dropbox/i18n/conf/fr.php index 00ab021938..f23a3dd680 100644 --- a/core/src/plugins/access.dropbox/i18n/conf/fr.php +++ b/core/src/plugins/access.dropbox/i18n/conf/fr.php @@ -30,4 +30,3 @@ "Password" => "Mot de passe", "User Password" => "Mot de passe", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.dropbox/i18n/conf/pt.php b/core/src/plugins/access.dropbox/i18n/conf/pt.php index 7788c64743..c031e1070e 100644 --- a/core/src/plugins/access.dropbox/i18n/conf/pt.php +++ b/core/src/plugins/access.dropbox/i18n/conf/pt.php @@ -30,4 +30,3 @@ "Password" => "Palavra-Chave", "User Password" => "Palavra-Chave do Utilizador", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.dropbox/manifest.xml b/core/src/plugins/access.dropbox/manifest.xml index 1664513100..94fb661528 100644 --- a/core/src/plugins/access.dropbox/manifest.xml +++ b/core/src/plugins/access.dropbox/manifest.xml @@ -9,7 +9,7 @@ - + @@ -21,6 +21,6 @@ - + - \ No newline at end of file + diff --git a/core/src/plugins/access.fs/class.fsAccessDriver.php b/core/src/plugins/access.fs/class.fsAccessDriver.php index 23c7077ebe..49cb90c11c 100644 --- a/core/src/plugins/access.fs/class.fsAccessDriver.php +++ b/core/src/plugins/access.fs/class.fsAccessDriver.php @@ -1,1984 +1,1923 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - - -// This is used to catch exception while downloading -if(!function_exists('download_exception_handler')){ - function download_exception_handler($exception){} -} - -/** - * AJXP_Plugin to access a filesystem. Most "FS" like driver (even remote ones) - * extend this one. - * @package AjaXplorer_Plugins - * @subpackage Access - */ -class fsAccessDriver extends AbstractAccessDriver implements AjxpWrapperProvider -{ - /** - * @var Repository - */ - public $repository; - public $driverConf; - protected $wrapperClassName; - protected $urlBase; - private static $loadedUserBookmarks; - - function initRepository(){ - if(is_array($this->pluginConf)){ - $this->driverConf = $this->pluginConf; - }else{ - $this->driverConf = array(); - } - if( $this->getFilteredOption("PROBE_REAL_SIZE", $this->repository->getId()) == true ){ - // PASS IT TO THE WRAPPER - ConfService::setConf("PROBE_REAL_SIZE", $this->getFilteredOption("PROBE_REAL_SIZE", $this->repository->getId())); - } - $create = $this->repository->getOption("CREATE"); - $path = $this->repository->getOption("PATH"); - $recycle = $this->repository->getOption("RECYCLE_BIN"); - if($create == true){ - if(!is_dir($path)) @mkdir($path, 0755, true); - if(!is_dir($path)){ - throw new AJXP_Exception("Cannot create root path for repository (".$this->repository->getDisplay()."). Please check repository configuration or that your folder is writeable!"); - } - if($recycle!= "" && !is_dir($path."/".$recycle)){ - @mkdir($path."/".$recycle); - if(!is_dir($path."/".$recycle)){ - throw new AJXP_Exception("Cannot create recycle bin folder. Please check repository configuration or that your folder is writeable!"); - } - } - $dataTemplate = $this->repository->getOption("DATA_TEMPLATE"); - if(!empty($dataTemplate) && is_dir($dataTemplate) && !is_file($path."/.ajxp_template")){ - $errs = array();$succ = array(); - $this->dircopy($dataTemplate, $path, $succ, $errs, false, false); - touch($path."/.ajxp_template"); - } - }else{ - if(!is_dir($path)){ - throw new AJXP_Exception("Cannot find base path for your repository! Please check the configuration!"); - } - } - $wrapperData = $this->detectStreamWrapper(true); - $this->wrapperClassName = $wrapperData["classname"]; - $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); - if($recycle != ""){ - RecycleBinManager::init($this->urlBase, "/".$recycle); - } - } - - public function getResourceUrl($path){ - return $this->urlBase.$path; - } - - public function getWrapperClassName(){ - return $this->wrapperClassName; - } - - function redirectActionsToMethod(&$contribNode, $arrayActions, $targetMethod){ - $actionXpath=new DOMXPath($contribNode->ownerDocument); - foreach($arrayActions as $index => $value){ - $arrayActions[$index] = 'action[@name="'.$value.'"]/processing/serverCallback'; - } - $procList = $actionXpath->query(implode(" | ", $arrayActions), $contribNode); - foreach($procList as $node){ - $node->setAttribute("methodName", $targetMethod); - } - } - - function disableArchiveBrowsingContributions(&$contribNode){ - // Cannot use zip features on FTP ! - // Remove "compress" action - $actionXpath=new DOMXPath($contribNode->ownerDocument); - $compressNodeList = $actionXpath->query('action[@name="compress"]', $contribNode); - if(!$compressNodeList->length) return ; - unset($this->actions["compress"]); - $compressNode = $compressNodeList->item(0); - $contribNode->removeChild($compressNode); - // Disable "download" if selection is multiple - $nodeList = $actionXpath->query('action[@name="download"]/gui/selectionContext', $contribNode); - $selectionNode = $nodeList->item(0); - $values = array("dir" => "false", "unique" => "true"); - foreach ($selectionNode->attributes as $attribute){ - if(isSet($values[$attribute->name])){ - $attribute->value = $values[$attribute->name]; - } - } - $nodeList = $actionXpath->query('action[@name="download"]/processing/clientListener[@name="selectionChange"]', $contribNode); - $listener = $nodeList->item(0); - $listener->parentNode->removeChild($listener); - // Disable "Explore" action on files - $nodeList = $actionXpath->query('action[@name="ls"]/gui/selectionContext', $contribNode); - $selectionNode = $nodeList->item(0); - $values = array("file" => "false", "allowedMimes" => ""); - foreach ($selectionNode->attributes as $attribute){ - if(isSet($values[$attribute->name])){ - $attribute->value = $values[$attribute->name]; - } - } - } - - protected function getNodesDiffArray(){ - return array("REMOVE" => array(), "ADD" => array(), "UPDATE" => array()); - } - - public function addSlugToPath($selection) - { - if (is_array($selection)) - // As passed by Copy/Move - $orig_files = $selection; - elseif ((is_object($selection)) && (isset($selection->files)) && (is_array($selection->files))) - // As passed by Download - $orig_files = $selection->files; - elseif (is_string($selection)) - // As passed by destination parameter - return $this->repository->slug.$selection; - else - // Unrecognized - return $selection; - - $files = array(); - foreach ($orig_files as $file) - $files[] = $this->repository->slug.$file; - return $files; - } - - function switchAction($action, $httpVars, $fileVars){ - if(!isSet($this->actions[$action])) return; - parent::accessPreprocess($action, $httpVars, $fileVars); - $selection = new UserSelection(); - $dir = $httpVars["dir"] OR ""; - if($this->wrapperClassName == "fsAccessWrapper"){ - $dir = fsAccessWrapper::patchPathForBaseDir($dir); - } - $dir = AJXP_Utils::securePath($dir); - if($action != "upload"){ - $dir = AJXP_Utils::decodeSecureMagic($dir); - } - $selection->initFromHttpVars($httpVars); - if(!$selection->isEmpty()){ - $this->filterUserSelectionToHidden($selection->getFiles()); - } - $mess = ConfService::getMessages(); - - $newArgs = RecycleBinManager::filterActions($action, $selection, $dir, $httpVars); - if(isSet($newArgs["action"])) $action = $newArgs["action"]; - if(isSet($newArgs["dest"])) $httpVars["dest"] = SystemTextEncoding::toUTF8($newArgs["dest"]);//Re-encode! - // FILTER DIR PAGINATION ANCHOR - $page = null; - if(isSet($dir) && strstr($dir, "%23")!==false){ - $parts = explode("%23", $dir); - $dir = $parts[0]; - $page = $parts[1]; - } - - $pendingSelection = ""; - $logMessage = null; - $reloadContextNode = false; - - switch($action) - { - //------------------------------------ - // DOWNLOAD - //------------------------------------ - case "download": - AJXP_Logger::logAction("Download", array("files"=>$this->addSlugToPath($selection))); - @set_error_handler(array("HTMLWriter", "javascriptErrorHandler"), E_ALL & ~ E_NOTICE); - @register_shutdown_function("restore_error_handler"); - $zip = false; - if($selection->isUnique()){ - if(is_dir($this->urlBase.$selection->getUniqueFile())) { - $zip = true; - $base = basename($selection->getUniqueFile()); - $dir .= "/".dirname($selection->getUniqueFile()); - }else{ - if(!file_exists($this->urlBase.$selection->getUniqueFile())){ - throw new Exception("Cannot find file!"); - } - } - $node = $selection->getUniqueNode($this); - }else{ - $zip = true; - } - if($zip){ - // Make a temp zip and send it as download - $loggedUser = AuthService::getLoggedUser(); - $file = AJXP_Utils::getAjxpTmpDir()."/".($loggedUser?$loggedUser->getId():"shared")."_".time()."tmpDownload.zip"; - $zipFile = $this->makeZip($selection->getFiles(), $file, $dir); - if(!$zipFile) throw new AJXP_Exception("Error while compressing"); - register_shutdown_function("unlink", $file); - $localName = ($base==""?"Files":$base).".zip"; - $this->readFile($file, "force-download", $localName, false, false, true); - }else{ - $localName = ""; - AJXP_Controller::applyHook("dl.localname", array($this->urlBase.$selection->getUniqueFile(), &$localName, $this->wrapperClassName)); - $this->readFile($this->urlBase.$selection->getUniqueFile(), "force-download", $localName); - } - if(isSet($node)){ - AJXP_Controller::applyHook("node.read", array(&$node)); - } - - - break; - - case "prepare_chunk_dl" : - - $chunkCount = intval($httpVars["chunk_count"]); - $fileId = $this->urlBase.$selection->getUniqueFile(); - $sessionKey = "chunk_file_".md5($fileId.time()); - $totalSize = $this->filesystemFileSize($fileId); - $chunkSize = intval ( $totalSize / $chunkCount ); - $realFile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $fileId, true); - $chunkData = array( - "localname" => basename($fileId), - "chunk_count" => $chunkCount, - "chunk_size" => $chunkSize, - "total_size" => $totalSize, - "file_id" => $sessionKey - ); - - $_SESSION[$sessionKey] = array_merge($chunkData, array("file"=>$realFile)); - HTMLWriter::charsetHeader("application/json"); - print(json_encode($chunkData)); - - $node = $selection->getUniqueNode($this); - AJXP_Controller::applyHook("node.read", array(&$node)); - - break; - - case "download_chunk" : - - $chunkIndex = intval($httpVars["chunk_index"]); - $chunkKey = $httpVars["file_id"]; - $sessData = $_SESSION[$chunkKey]; - $realFile = $sessData["file"]; - $chunkSize = $sessData["chunk_size"]; - $offset = $chunkSize * $chunkIndex; - if($chunkIndex == $sessData["chunk_count"]-1){ - // Compute the last chunk real length - $chunkSize = $sessData["total_size"] - ($chunkSize * ($sessData["chunk_count"]-1)); - if(call_user_func(array($this->wrapperClassName, "isRemote"))){ - register_shutdown_function("unlink", $realFile); - } - } - $this->readFile($realFile, "force-download", $sessData["localname"].".".sprintf("%03d", $chunkIndex+1), false, false, true, $offset, $chunkSize); - - - break; - - case "compress" : - // Make a temp zip and send it as download - $loggedUser = AuthService::getLoggedUser(); - if(isSet($httpVars["archive_name"])){ - $localName = AJXP_Utils::decodeSecureMagic($httpVars["archive_name"]); - $this->filterUserSelectionToHidden(array($localName)); - }else{ - $localName = (basename($dir)==""?"Files":basename($dir)).".zip"; - } - $file = AJXP_Utils::getAjxpTmpDir()."/".($loggedUser?$loggedUser->getId():"shared")."_".time()."tmpCompression.zip"; - $zipFile = $this->makeZip($selection->getFiles(), $file, $dir); - if(!$zipFile) throw new AJXP_Exception("Error while compressing file $localName"); - register_shutdown_function("unlink", $file); - $tmpFNAME = $this->urlBase.$dir."/".str_replace(".zip", ".tmp", $localName); - copy($file, $tmpFNAME); - try{ - AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($tmpFNAME), filesize($tmpFNAME))); - }catch (Exception $e){ - @unlink($tmpFNAME); - throw $e; - } - @rename($tmpFNAME, $this->urlBase.$dir."/".$localName); - AJXP_Controller::applyHook("node.change", array(null, new AJXP_Node($this->urlBase.$dir."/".$localName), false)); - //$reloadContextNode = true; - //$pendingSelection = $localName; - $newNode = new AJXP_Node($this->urlBase.$dir."/".$localName); - if(!isset($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); - $nodesDiffs["ADD"][] = $newNode; - break; - - case "stat" : - - clearstatcache(); - $stat = @stat($this->urlBase.$selection->getUniqueFile()); - header("Content-type:application/json"); - if(!$stat){ - print '{}'; - }else{ - print json_encode($stat); - } - - break; - - - //------------------------------------ - // ONLINE EDIT - //------------------------------------ - case "get_content": - - $dlFile = $this->urlBase.$selection->getUniqueFile(); - AJXP_Logger::logAction("Get_content", array("files"=>$this->addSlugToPath($selection))); - if(AJXP_Utils::getStreamingMimeType(basename($dlFile))!==false){ - $this->readFile($this->urlBase.$selection->getUniqueFile(), "stream_content"); - }else{ - $this->readFile($this->urlBase.$selection->getUniqueFile(), "plain"); - } - $node = $selection->getUniqueNode($this); - AJXP_Controller::applyHook("node.read", array(&$node)); - - break; - - case "put_content": - if(!isset($httpVars["content"])) break; - // Load "code" variable directly from POST array, do not "securePath" or "sanitize"... - $code = $httpVars["content"]; - $file = $selection->getUniqueFile($httpVars["file"]); - AJXP_Logger::logAction("Online Edition", array("file"=>$this->addSlugToPath($file))); - if(isSet($httpVars["encode"]) && $httpVars["encode"] == "base64"){ - $code = base64_decode($code); - }else{ - $code = SystemTextEncoding::magicDequote($code); - $code=str_replace("<","<",$code); - } - $fileName = $this->urlBase.$file; - $currentNode = new AJXP_Node($fileName); - try{ - AJXP_Controller::applyHook("node.before_change", array(&$currentNode, strlen($code))); - }catch(Exception $e){ - header("Content-Type:text/plain"); - print $e->getMessage(); - return; - } - if(!is_file($fileName) || !$this->isWriteable($fileName, "file")){ - header("Content-Type:text/plain"); - print((!$this->isWriteable($fileName, "file")?"1001":"1002")); - return ; - } - $fp=fopen($fileName,"w"); - fputs ($fp,$code); - fclose($fp); - clearstatcache(true, $fileName); - AJXP_Controller::applyHook("node.change", array($currentNode, $currentNode, false)); - header("Content-Type:text/plain"); - print($mess[115]); - - break; - - //------------------------------------ - // COPY / MOVE - //------------------------------------ - case "copy"; - case "move"; - - //throw new AJXP_Exception("", 113); - if($selection->isEmpty()) - { - throw new AJXP_Exception("", 113); - } - $success = $error = array(); - $dest = AJXP_Utils::decodeSecureMagic($httpVars["dest"]); - $this->filterUserSelectionToHidden(array($httpVars["dest"])); - if($selection->inZip()){ - // Set action to copy anycase (cannot move from the zip). - $action = "copy"; - $this->extractArchive($dest, $selection, $error, $success); - }else{ - $move = ($action == "move" ? true : false); - if($move && isSet($httpVars["force_copy_delete"])){ - $move = false; - } - $this->copyOrMove($dest, $selection->getFiles(), $error, $success, $move); - - } - - if(count($error)){ - throw new AJXP_Exception(SystemTextEncoding::toUTF8(join("\n", $error))); - }else { - if(isSet($httpVars["force_copy_delete"])){ - $errorMessage = $this->delete($selection->getFiles(), $logMessages); - if($errorMessage) throw new AJXP_Exception(SystemTextEncoding::toUTF8($errorMessage)); - AJXP_Logger::logAction("Copy/Delete", array("files"=>$this->addSlugToPath($selection), "destination" => $this->addSlugToPath($dest))); - }else{ - AJXP_Logger::logAction(($action=="move"?"Move":"Copy"), array("files"=>$this->addSlugToPath($selection), "destination"=>$this->addSlugToPath($dest))); - } - $logMessage = join("\n", $success); - } - if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); - // Assume new nodes are correctly created - $selectedItems = $selection->getFiles(); - foreach($selectedItems as $selectedPath){ - $newPath = $this->urlBase.$dest ."/". basename($selectedPath); - $newNode = new AJXP_Node($newPath); - $nodesDiffs["ADD"][] = $newNode; - if($action == "move") $nodesDiffs["REMOVE"][] = $selectedPath; - } - if(!(RecycleBinManager::getRelativeRecycle() ==$dest && $this->getFilteredOption("HIDE_RECYCLE", $this->repository->getId()) == true)){ - //$reloadDataNode = $dest; - } - - break; - - //------------------------------------ - // DELETE - //------------------------------------ - case "delete"; - - if($selection->isEmpty()) - { - throw new AJXP_Exception("", 113); - } - $logMessages = array(); - $errorMessage = $this->delete($selection->getFiles(), $logMessages); - if(count($logMessages)) - { - $logMessage = join("\n", $logMessages); - } - if($errorMessage) throw new AJXP_Exception(SystemTextEncoding::toUTF8($errorMessage)); - AJXP_Logger::logAction("Delete", array("files"=>$this->addSlugToPath($selection))); - if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); - $nodesDiffs["REMOVE"] = array_merge($nodesDiffs["REMOVE"], $selection->getFiles()); - - break; - - - case "purge" : - - - $pTime = intval($this->repository->getOption("PURGE_AFTER")); - if($pTime > 0){ - $purgeTime = intval($pTime)*3600*24; - $this->recursivePurge($this->urlBase, $purgeTime); - } - - break; - - //------------------------------------ - // RENAME - //------------------------------------ - case "rename"; - - $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); - $filename_new = AJXP_Utils::decodeSecureMagic($httpVars["filename_new"]); - $dest = null; - if(isSet($httpVars["dest"])){ - $dest = AJXP_Utils::decodeSecureMagic($httpVars["dest"]); - $filename_new = ""; - } - $this->filterUserSelectionToHidden(array($filename_new)); - $this->rename($file, $filename_new, $dest); - $logMessage= SystemTextEncoding::toUTF8($file)." $mess[41] ".SystemTextEncoding::toUTF8($filename_new); - //$reloadContextNode = true; - //$pendingSelection = $filename_new; - if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); - if($dest == null) $dest = dirname($file); - $nodesDiffs["UPDATE"][$file] = new AJXP_Node($this->urlBase.$dest."/".$filename_new); - AJXP_Logger::logAction("Rename", array("original"=>$this->addSlugToPath($file), "new"=>$filename_new)); - - break; - - //------------------------------------ - // CREER UN REPERTOIRE / CREATE DIR - //------------------------------------ - case "mkdir"; - - $messtmp=""; - $dirname=AJXP_Utils::decodeSecureMagic($httpVars["dirname"], AJXP_SANITIZE_HTML_STRICT); - $dirname = substr($dirname, 0, ConfService::getCoreConf("NODENAME_MAX_LENGTH")); - $this->filterUserSelectionToHidden(array($dirname)); - AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($dir."/".$dirname), -2)); - $error = $this->mkDir($dir, $dirname, isSet($httpVars["ignore_exists"])?true:false); - if(isSet($error)){ - throw new AJXP_Exception($error); - } - $messtmp.="$mess[38] ".SystemTextEncoding::toUTF8($dirname)." $mess[39] "; - if($dir=="") {$messtmp.="/";} else {$messtmp.= SystemTextEncoding::toUTF8($dir);} - $logMessage = $messtmp; - //$pendingSelection = $dirname; - //$reloadContextNode = true; - $newNode = new AJXP_Node($this->urlBase.$dir."/".$dirname); - if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); - array_push($nodesDiffs["ADD"], $newNode); - AJXP_Logger::logAction("Create Dir", array("dir"=>$this->addSlugToPath($dir)."/".$dirname)); - - break; - - //------------------------------------ - // CREER UN FICHIER / CREATE FILE - //------------------------------------ - case "mkfile"; - - $messtmp=""; - $filename=AJXP_Utils::decodeSecureMagic($httpVars["filename"], AJXP_SANITIZE_HTML_STRICT); - $filename = substr($filename, 0, ConfService::getCoreConf("NODENAME_MAX_LENGTH")); - $this->filterUserSelectionToHidden(array($filename)); - $content = ""; - if(isSet($httpVars["content"])){ - $content = $httpVars["content"]; - } - $error = $this->createEmptyFile($dir, $filename, $content); - if(isSet($error)){ - throw new AJXP_Exception($error); - } - $messtmp.="$mess[34] ".SystemTextEncoding::toUTF8($filename)." $mess[39] "; - if($dir=="") {$messtmp.="/";} else {$messtmp.=SystemTextEncoding::toUTF8($dir);} - $logMessage = $messtmp; - //$reloadContextNode = true; - //$pendingSelection = $dir."/".$filename; - AJXP_Logger::logAction("Create File", array("file"=>$this->addSlugToPath($dir)."/".$filename)); - $newNode = new AJXP_Node($this->urlBase.$dir."/".$filename); - if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); - array_push($nodesDiffs["ADD"], $newNode); - - break; - - //------------------------------------ - // CHANGE FILE PERMISSION - //------------------------------------ - case "chmod"; - - $messtmp=""; - $files = $selection->getFiles(); - $changedFiles = array(); - $chmod_value = $httpVars["chmod_value"]; - $recursive = $httpVars["recursive"]; - $recur_apply_to = $httpVars["recur_apply_to"]; - foreach ($files as $fileName){ - $error = $this->chmod($fileName, $chmod_value, ($recursive=="on"), ($recursive=="on"?$recur_apply_to:"both"), $changedFiles); - } - if(isSet($error)){ - throw new AJXP_Exception($error); - } - //$messtmp.="$mess[34] ".SystemTextEncoding::toUTF8($filename)." $mess[39] "; - $logMessage="Successfully changed permission to ".$chmod_value." for ".count($changedFiles)." files or folders"; - AJXP_Logger::logAction("Chmod", array("dir"=>$this->addSlugToPath($dir), "filesCount"=>count($changedFiles))); - if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); - $nodesDiffs["UPDATE"] = array_merge($nodesDiffs["UPDATE"], $selection->buildNodes($this)); - - break; - - //------------------------------------ - // UPLOAD - //------------------------------------ - case "upload": - - AJXP_Logger::debug("Upload Files Data", $fileVars); - $destination=$this->urlBase.AJXP_Utils::decodeSecureMagic($dir); - AJXP_Logger::debug("Upload inside", array("destination"=>$this->addSlugToPath($destination))); - if(!$this->isWriteable($destination)) - { - $errorCode = 412; - $errorMessage = "$mess[38] ".SystemTextEncoding::toUTF8($dir)." $mess[99]."; - AJXP_Logger::debug("Upload error 412", array("destination"=>$this->addSlugToPath($destination))); - return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $errorMessage)); - } - foreach ($fileVars as $boxName => $boxData) - { - if(substr($boxName, 0, 9) != "userfile_") continue; - $err = AJXP_Utils::parseFileDataErrors($boxData); - if($err != null) - { - $errorCode = $err[0]; - $errorMessage = $err[1]; - break; - } - $userfile_name = $boxData["name"]; - try{ - $this->filterUserSelectionToHidden(array($userfile_name)); - }catch (Exception $e){ - return array("ERROR" => array("CODE" => 411, "MESSAGE" => "Forbidden")); - } - $userfile_name=AJXP_Utils::sanitize(SystemTextEncoding::fromPostedFileName($userfile_name), AJXP_SANITIZE_HTML_STRICT); - if(isSet($httpVars["urlencoded_filename"])){ - $userfile_name = AJXP_Utils::sanitize(SystemTextEncoding::fromUTF8(urldecode($httpVars["urlencoded_filename"])), AJXP_SANITIZE_HTML_STRICT); - } - AJXP_Logger::debug("User filename ".$userfile_name); - $userfile_name = substr($userfile_name, 0, ConfService::getCoreConf("NODENAME_MAX_LENGTH")); - if(isSet($httpVars["auto_rename"])){ - $userfile_name = self::autoRenameForDest($destination, $userfile_name); - } - try { - if(file_exists($destination."/".$userfile_name)){ - AJXP_Controller::applyHook("node.before_change", array(new AJXP_Node($destination."/".$userfile_name), $boxData["size"])); - }else{ - AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($destination."/".$userfile_name), $boxData["size"])); - } - AJXP_Controller::applyHook("node.before_change", array(new AJXP_Node($destination))); - }catch (Exception $e){ - $errorCode=507; - $errorMessage = $e->getMessage(); - break; - } - if(isSet($boxData["input_upload"])){ - try{ - AJXP_Logger::debug("Begining reading INPUT stream"); - $input = fopen("php://input", "r"); - $output = fopen("$destination/".$userfile_name, "w"); - $sizeRead = 0; - while($sizeRead < intval($boxData["size"])){ - $chunk = fread($input, 4096); - $sizeRead += strlen($chunk); - fwrite($output, $chunk, strlen($chunk)); - } - fclose($input); - fclose($output); - AJXP_Logger::debug("End reading INPUT stream"); - }catch (Exception $e){ - $errorCode=411; - $errorMessage = $e->getMessage(); - break; - } - }else{ - $result = @move_uploaded_file($boxData["tmp_name"], "$destination/".$userfile_name); - if(!$result){ - $realPath = call_user_func(array($this->wrapperClassName, "getRealFSReference"),"$destination/".$userfile_name); - $result = move_uploaded_file($boxData["tmp_name"], $realPath); - } - if (!$result) - { - $errorCode=411; - $errorMessage="$mess[33] ".$userfile_name; - break; - } - } - if(isSet($httpVars["appendto_urlencoded_part"])){ - $appendTo = AJXP_Utils::sanitize(SystemTextEncoding::fromUTF8(urldecode($httpVars["appendto_urlencoded_part"])), AJXP_SANITIZE_HTML_STRICT); - if(file_exists($destination ."/" . $appendTo)){ - AJXP_Logger::debug("Should copy stream from $userfile_name to $appendTo"); - $partO = fopen($destination."/".$userfile_name, "r"); - $appendF = fopen($destination ."/". $appendTo, "a+"); - while(!feof($partO)){ - $buf = fread($partO, 1024); - fwrite($appendF, $buf, strlen($buf)); - } - fclose($partO); - fclose($appendF); - AJXP_Logger::debug("Done, closing streams!"); - } - @unlink($destination."/".$userfile_name); - $userfile_name = $appendTo; - } - - $this->changeMode($destination."/".$userfile_name); - $createdNode = new AJXP_Node($destination."/".$userfile_name); - //AJXP_Controller::applyHook("node.change", array(null, $createdNode, false)); - $logMessage.="$mess[34] ".SystemTextEncoding::toUTF8($userfile_name)." $mess[35] $dir"; - AJXP_Logger::logAction("Upload File", array("file"=>$this->addSlugToPath(SystemTextEncoding::fromUTF8($dir))."/".$userfile_name)); - } - - if(isSet($errorMessage)){ - AJXP_Logger::debug("Return error $errorCode $errorMessage"); - return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $errorMessage)); - }else{ - AJXP_Logger::debug("Return success"); - return array("SUCCESS" => true, "CREATED_NODE" => $createdNode); - } - return ; - - break; - - case "lsync" : - - if(!ConfService::currentContextIsCommandLine()){ - die("This command must be accessed via CLI only."); - } - $fromNode = null; - $toNode = null; - $copyOrMove = false; - if(isSet($httpVars["from"])) { - $fromNode = new AJXP_Node($this->urlBase.AJXP_Utils::decodeSecureMagic($httpVars["from"])); - } - if(isSet($httpVars["to"])) { - $toNode = new AJXP_Node($this->urlBase.AJXP_Utils::decodeSecureMagic($httpVars["to"])); - } - if(isSet($httpVars["copy"]) && $httpVars["copy"] == "true"){ - $copyOrMove = true; - } - AJXP_Controller::applyHook("node.change", array($fromNode, $toNode, $copyOrMove)); - - break; - - //------------------------------------ - // XML LISTING - //------------------------------------ - case "ls": - - if(!isSet($dir) || $dir == "/") $dir = ""; - $lsOptions = $this->parseLsOptions((isSet($httpVars["options"])?$httpVars["options"]:"a")); - - $startTime = microtime(); - if(isSet($httpVars["file"])){ - $uniqueFile = AJXP_Utils::decodeSecureMagic($httpVars["file"]); - } - $dir = AJXP_Utils::securePath(SystemTextEncoding::magicDequote($dir)); - $path = $this->urlBase.($dir!= ""?($dir[0]=="/"?"":"/").$dir:""); - $nonPatchedPath = $path; - if($this->wrapperClassName == "fsAccessWrapper") { - $nonPatchedPath = fsAccessWrapper::unPatchPathForBaseDir($path); - } - $threshold = $this->repository->getOption("PAGINATION_THRESHOLD"); - if(!isSet($threshold) || intval($threshold) == 0) $threshold = 500; - $limitPerPage = $this->repository->getOption("PAGINATION_NUMBER"); - if(!isset($limitPerPage) || intval($limitPerPage) == 0) $limitPerPage = 200; - - $countFiles = $this->countFiles($path, !$lsOptions["f"]); - if($countFiles > $threshold){ - if(isSet($uniqueFile)){ - $originalLimitPerPage = $limitPerPage; - $offset = $limitPerPage = 0; - }else{ - $offset = 0; - $crtPage = 1; - if(isSet($page)){ - $offset = (intval($page)-1)*$limitPerPage; - $crtPage = $page; - } - $totalPages = floor($countFiles / $limitPerPage) + 1; - } - }else{ - $offset = $limitPerPage = 0; - } - - $metaData = array(); - if(RecycleBinManager::recycleEnabled() && $dir == ""){ - $metaData["repo_has_recycle"] = "true"; - } - $parentAjxpNode = new AJXP_Node($nonPatchedPath, $metaData); - $parentAjxpNode->loadNodeInfo(false, true, ($lsOptions["l"]?"all":"minimal")); - AJXP_Controller::applyHook("node.read", array(&$parentAjxpNode)); - if(AJXP_XMLWriter::$headerSent == "tree"){ - AJXP_XMLWriter::renderAjxpNode($parentAjxpNode, false); - }else{ - AJXP_XMLWriter::renderAjxpHeaderNode($parentAjxpNode); - } - if(isSet($totalPages) && isSet($crtPage)){ - AJXP_XMLWriter::renderPaginationData( - $countFiles, - $crtPage, - $totalPages, - $this->countFiles($path, TRUE) - ); - if(!$lsOptions["f"]){ - AJXP_XMLWriter::close(); - exit(1); - } - } - - $cursor = 0; - $handle = opendir($path); - if(!$handle) { - throw new AJXP_Exception("Cannot open dir ".$nonPatchedPath); - } - closedir($handle); - $fullList = array("d" => array(), "z" => array(), "f" => array()); - $nodes = scandir($path); - if(!empty($this->driverConf["SCANDIR_RESULT_SORTFONC"])){ - usort($nodes, $this->driverConf["SCANDIR_RESULT_SORTFONC"]); - } - //while(strlen($nodeName = readdir($handle)) > 0){ - foreach ($nodes as $nodeName){ - if($nodeName == "." || $nodeName == "..") continue; - if(isSet($uniqueFile) && $nodeName != $uniqueFile){ - $cursor ++; - continue; - } - if($offset > 0 && $cursor < $offset){ - $cursor ++; - continue; - } - $isLeaf = ""; - if(!$this->filterNodeName($path, $nodeName, $isLeaf, $lsOptions)){ - continue; - } - if(RecycleBinManager::recycleEnabled() && $dir == "" && "/".$nodeName == RecycleBinManager::getRecyclePath()){ - continue; - } - - if($limitPerPage > 0 && ($cursor - $offset) >= $limitPerPage) { - break; - } - - $currentFile = $nonPatchedPath."/".$nodeName; - $meta = array(); - if($isLeaf != "") $meta = array("is_file" => ($isLeaf?"1":"0")); - $node = new AJXP_Node($currentFile, $meta); - $node->setLabel($nodeName); - $node->loadNodeInfo(false, false, ($lsOptions["l"]?"all":"minimal")); - if(!empty($node->metaData["nodeName"]) && $node->metaData["nodeName"] != $nodeName){ - $node->setUrl($nonPatchedPath."/".$node->metaData["nodeName"]); - } - if(!empty($node->metaData["hidden"]) && $node->metaData["hidden"] === true){ - continue; - } - if(!empty($node->metaData["mimestring_id"]) && array_key_exists($node->metaData["mimestring_id"], $mess)){ - $node->mergeMetadata(array("mimestring" => $mess[$node->metaData["mimestring_id"]])); - } - if(isSet($originalLimitPerPage) && $cursor > $originalLimitPerPage){ - $node->mergeMetadata(array("page_position" => floor($cursor / $originalLimitPerPage) +1)); - } - - $nodeType = "d"; - if($node->isLeaf()){ - if(AJXP_Utils::isBrowsableArchive($nodeName)) { - if($lsOptions["f"] && $lsOptions["z"]){ - $nodeType = "f"; - }else{ - $nodeType = "z"; - } - } - else $nodeType = "f"; - } - - $fullList[$nodeType][$nodeName] = $node; - $cursor ++; - if(isSet($uniqueFile) && $nodeName != $uniqueFile){ - break; - } - } - if(isSet($httpVars["recursive"]) && $httpVars["recursive"] == "true"){ - foreach($fullList["d"] as $nodeDir){ - $this->switchAction("ls", array( - "dir" => SystemTextEncoding::toUTF8($nodeDir->getPath()), - "options"=> $httpVars["options"], - "recursive" => "true" - ), array()); - } - }else{ - array_map(array("AJXP_XMLWriter", "renderAjxpNode"), $fullList["d"]); - } - array_map(array("AJXP_XMLWriter", "renderAjxpNode"), $fullList["z"]); - array_map(array("AJXP_XMLWriter", "renderAjxpNode"), $fullList["f"]); - - // ADD RECYCLE BIN TO THE LIST - if($dir == "" && !$uniqueFile && RecycleBinManager::recycleEnabled() && $this->getFilteredOption("HIDE_RECYCLE", $this->repository->getId()) !== true) - { - $recycleBinOption = RecycleBinManager::getRelativeRecycle(); - if(file_exists($this->urlBase.$recycleBinOption)){ - $recycleNode = new AJXP_Node($this->urlBase.$recycleBinOption); - $recycleNode->loadNodeInfo(); - AJXP_XMLWriter::renderAjxpNode($recycleNode); - } - } - - AJXP_Logger::debug("LS Time : ".intval((microtime()-$startTime)*1000)."ms"); - - AJXP_XMLWriter::close(); - return ; - - break; - } - - - $xmlBuffer = ""; - if(isset($logMessage) || isset($errorMessage)) - { - $xmlBuffer .= AJXP_XMLWriter::sendMessage((isSet($logMessage)?$logMessage:null), (isSet($errorMessage)?$errorMessage:null), false); - } - if($reloadContextNode){ - if(!isSet($pendingSelection)) $pendingSelection = ""; - $xmlBuffer .= AJXP_XMLWriter::reloadDataNode("", $pendingSelection, false); - } - if(isSet($reloadDataNode)){ - $xmlBuffer .= AJXP_XMLWriter::reloadDataNode($reloadDataNode, "", false); - } - if(isSet($nodesDiffs)){ - $xmlBuffer .= AJXP_XMLWriter::writeNodesDiff($nodesDiffs, false); - } - - return $xmlBuffer; - } - - function parseLsOptions($optionString){ - // LS OPTIONS : dz , a, d, z, all of these with or without l - // d : directories - // z : archives - // f : files - // => a : all, alias to dzf - // l : list metadata - $allowed = array("a", "d", "z", "f", "l"); - $lsOptions = array(); - foreach ($allowed as $key){ - if(strchr($optionString, $key)!==false){ - $lsOptions[$key] = true; - }else{ - $lsOptions[$key] = false; - } - } - if($lsOptions["a"]){ - $lsOptions["d"] = $lsOptions["z"] = $lsOptions["f"] = true; - } - return $lsOptions; - } - - /** - * @param AJXP_Node $ajxpNode - * @param bool $parentNode - * @param bool $details - * @return void - */ - function loadNodeInfo(&$ajxpNode, $parentNode = false, $details = false){ - - $nodeName = basename($ajxpNode->getPath()); - $metaData = $ajxpNode->metadata; - if(!isSet($metaData["is_file"])){ - $isLeaf = is_file($ajxpNode->getUrl()) || AJXP_Utils::isBrowsableArchive($nodeName); - $metaData["is_file"] = ($isLeaf?"1":"0"); - }else{ - $isLeaf = $metaData["is_file"] == "1" ? true : false; - } - $metaData["filename"] = $ajxpNode->getPath(); - - if(RecycleBinManager::recycleEnabled() && $ajxpNode->getPath() == RecycleBinManager::getRelativeRecycle()){ - $mess = ConfService::getMessages(); - $recycleIcon = ($this->countFiles($ajxpNode->getUrl(), false, true)>0?"trashcan_full.png":"trashcan.png"); - $metaData["icon"] = $recycleIcon; - $metaData["mimestring"] = $mess[122]; - $ajxpNode->setLabel($mess[122]); - $metaData["ajxp_mime"] = "ajxp_recycle"; - }else{ - $mimeData = AJXP_Utils::mimeData($ajxpNode->getUrl(), !$isLeaf); - $metaData["mimestring_id"] = $mimeData[0]; //AJXP_Utils::mimetype($ajxpNode->getUrl(), "type", !$isLeaf); - $metaData["icon"] = $mimeData[1]; //AJXP_Utils::mimetype($nodeName, "image", !$isLeaf); - if($metaData["icon"] == "folder.png"){ - $metaData["openicon"] = "folder_open.png"; - } - if(!$isLeaf){ - $metaData["ajxp_mime"] = "ajxp_folder"; - } - } - //if($lsOptions["l"]){ - - $metaData["file_group"] = @filegroup($ajxpNode->getUrl()) || "unknown"; - $metaData["file_owner"] = @fileowner($ajxpNode->getUrl()) || "unknown"; - $crtPath = $ajxpNode->getPath(); - $vRoots = $this->repository->listVirtualRoots(); - if(!empty($crtPath)){ - if(!@$this->isWriteable($ajxpNode->getUrl())){ - $metaData["ajxp_readonly"] = "true"; - } - if(isSet($vRoots[ltrim($crtPath, "/")])){ - $metaData["ajxp_readonly"] = $vRoots[ltrim($crtPath, "/")]["right"] == "r" ? "true" : "false"; - } - }else{ - if(count($vRoots)) { - $metaData["ajxp_readonly"] = "true"; - } - } - $fPerms = @fileperms($ajxpNode->getUrl()); - if($fPerms !== false){ - $fPerms = substr(decoct( $fPerms ), ($isLeaf?2:1)); - }else{ - $fPerms = '0000'; - } - $metaData["file_perms"] = $fPerms; - $datemodif = $this->date_modif($ajxpNode->getUrl()); - $metaData["ajxp_modiftime"] = ($datemodif ? $datemodif : "0"); - $metaData["bytesize"] = 0; - if($isLeaf){ - $metaData["bytesize"] = $this->filesystemFileSize($ajxpNode->getUrl()); - } - $metaData["filesize"] = AJXP_Utils::roundSize($metaData["bytesize"]); - if(AJXP_Utils::isBrowsableArchive($nodeName)){ - $metaData["ajxp_mime"] = "ajxp_browsable_archive"; - } - - if($details == "minimal"){ - $miniMeta = array( - "is_file" => $metaData["is_file"], - "filename" => $metaData["filename"], - "bytesize" => $metaData["bytesize"], - "ajxp_modiftime" => $metaData["ajxp_modiftime"], - ); - $ajxpNode->mergeMetadata($miniMeta); - }else{ - $ajxpNode->mergeMetadata($metaData); - } - - } - - /** - * Test if userSelection is containing a hidden file, which should not be the case! - * @param UserSelection $files - */ - function filterUserSelectionToHidden($files){ - $showHiddenFiles = $this->getFilteredOption("SHOW_HIDDEN_FILES", $this->repository->getId()); - foreach ($files as $file){ - $file = basename($file); - if(AJXP_Utils::isHidden($file) && !$showHiddenFiles){ - throw new Exception("Forbidden"); - } - if($this->filterFile($file) || $this->filterFolder($file)){ - throw new Exception("Forbidden"); - } - } - } - - function filterNodeName($nodePath, $nodeName, &$isLeaf, $lsOptions){ - $showHiddenFiles = $this->getFilteredOption("SHOW_HIDDEN_FILES", $this->repository->getId()); - $isLeaf = (is_file($nodePath."/".$nodeName) || AJXP_Utils::isBrowsableArchive($nodeName)); - if(AJXP_Utils::isHidden($nodeName) && !$showHiddenFiles){ - return false; - } - $nodeType = "d"; - if($isLeaf){ - if(AJXP_Utils::isBrowsableArchive($nodeName)) $nodeType = "z"; - else $nodeType = "f"; - } - if(!$lsOptions[$nodeType]) return false; - if($nodeType == "d"){ - if(RecycleBinManager::recycleEnabled() - && $nodePath."/".$nodeName == RecycleBinManager::getRecyclePath()){ - return false; - } - return !$this->filterFolder($nodeName); - }else{ - if($nodeName == "." || $nodeName == "..") return false; - if(RecycleBinManager::recycleEnabled() - && $nodePath == RecycleBinManager::getRecyclePath() - && $nodeName == RecycleBinManager::getCacheFileName()){ - return false; - } - return !$this->filterFile($nodeName); - } - } - - function filterFile($fileName){ - $pathParts = pathinfo($fileName); - $hiddenFileNames = $this->getFilteredOption("HIDE_FILENAMES", $this->repository->getId()); - $hiddenExtensions = $this->getFilteredOption("HIDE_EXTENSIONS", $this->repository->getId()); - if(!empty($hiddenFileNames)){ - if(!is_array($hiddenFileNames)) { - $hiddenFileNames = explode(",",$hiddenFileNames); - } - foreach ($hiddenFileNames as $search){ - if(strcasecmp($search, $pathParts["basename"]) == 0) return true; - } - } - if(!empty($hiddenExtensions)){ - if(!is_array($hiddenExtensions)) { - $hiddenExtensions = explode(",",$hiddenExtensions); - } - foreach ($hiddenExtensions as $search){ - if(strcasecmp($search, $pathParts["extension"]) == 0) return true; - } - } - return false; - } - - function filterFolder($folderName, $compare = "equals"){ - $hiddenFolders = $this->getFilteredOption("HIDE_FOLDERS", $this->repository->getId()); - if(!empty($hiddenFolders)){ - if(!is_array($hiddenFolders)) { - $hiddenFolders = explode(",",$hiddenFolders); - } - foreach ($hiddenFolders as $search){ - if($compare == "equals" && strcasecmp($search, $folderName) == 0) return true; - if($compare == "contains" && strpos($folderName, "/".$search) !== false) return true; - } - } - return false; - } - - function readFile($filePathOrData, $headerType="plain", $localName="", $data=false, $gzip=null, $realfileSystem=false, $byteOffset=-1, $byteLength=-1) - { - if($gzip === null){ - $gzip = ConfService::getCoreConf("GZIP_COMPRESSION"); - } - if(!$realfileSystem && $this->wrapperClassName == "fsAccessWrapper"){ - $originalFilePath = $filePathOrData; - $filePathOrData = fsAccessWrapper::patchPathForBaseDir($filePathOrData); - } - session_write_close(); - - restore_error_handler(); - restore_exception_handler(); - - set_exception_handler('download_exception_handler'); - set_error_handler('download_exception_handler'); - // required for IE, otherwise Content-disposition is ignored - if(ini_get('zlib.output_compression')) { - AJXP_Utils::safeIniSet('zlib.output_compression', 'Off'); - } - - $isFile = !$data && !$gzip; - if($byteLength == -1){ - if($data){ - $size = strlen($filePathOrData); - }else if ($realfileSystem){ - $size = sprintf("%u", filesize($filePathOrData)); - }else{ - $size = $this->filesystemFileSize($filePathOrData); - } - }else{ - $size = $byteLength; - } - if($gzip && ($size > ConfService::getCoreConf("GZIP_LIMIT") || !function_exists("gzencode") || @strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === FALSE)){ - $gzip = false; // disable gzip - } - - $localName = ($localName=="" ? basename((isSet($originalFilePath)?$originalFilePath:$filePathOrData)) : $localName); - if($headerType == "plain") - { - header("Content-type:text/plain"); - } - else if($headerType == "image") - { - header("Content-Type: ".AJXP_Utils::getImageMimeType(basename($filePathOrData))."; name=\"".$localName."\""); - header("Content-Length: ".$size); - header('Cache-Control: public'); - } - else - { - /* - if(preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']) || preg_match('/ WebKit /',$_SERVER['HTTP_USER_AGENT'])){ - $localName = str_replace("+", " ", urlencode(SystemTextEncoding::toUTF8($localName))); - } - */ - if ($isFile) { - header("Accept-Ranges: 0-$size"); - AJXP_Logger::debug("Sending accept range 0-$size"); - } - - // Check if we have a range header (we are resuming a transfer) - if ( isset($_SERVER['HTTP_RANGE']) && $isFile && $size != 0 ) - { - if($headerType == "stream_content"){ - if(extension_loaded('fileinfo') && $this->wrapperClassName == "fsAccessWrapper"){ - $fInfo = new fInfo( FILEINFO_MIME ); - $realfile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $filePathOrData); - $mimeType = $fInfo->file( $realfile); - $splitChar = explode(";", $mimeType); - $mimeType = trim($splitChar[0]); - AJXP_Logger::debug("Detected mime $mimeType for $realfile"); - }else{ - $mimeType = AJXP_Utils::getStreamingMimeType(basename($filePathOrData)); - } - header('Content-type: '.$mimeType); - } - // multiple ranges, which can become pretty complex, so ignore it for now - $ranges = explode('=', $_SERVER['HTTP_RANGE']); - $offsets = explode('-', $ranges[1]); - $offset = floatval($offsets[0]); - - $length = floatval($offsets[1]) - $offset; - if (!$length) $length = $size - $offset; - if ($length + $offset > $size || $length < 0) $length = $size - $offset; - AJXP_Logger::debug('Content-Range: bytes ' . $offset . '-' . $length . '/' . $size); - header('HTTP/1.1 206 Partial Content'); - header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $size); - - header("Content-Length: ". $length); - $file = fopen($filePathOrData, 'rb'); - fseek($file, 0); - $relOffset = $offset; - while ($relOffset > 2.0E9) - { - // seek to the requested offset, this is 0 if it's not a partial content request - fseek($file, 2000000000, SEEK_CUR); - $relOffset -= 2000000000; - // This works because we never overcome the PHP 32 bit limit - } - fseek($file, $relOffset, SEEK_CUR); - - while(ob_get_level()) ob_end_flush(); - $readSize = 0.0; - $bufferSize = 1024 * 8; - while (!feof($file) && $readSize < $length && connection_status() == 0) - { - AJXP_Logger::debug("dl reading $readSize to $length", $_SERVER["HTTP_RANGE"]); - echo fread($file, $bufferSize); - $readSize += $bufferSize; - flush(); - } - - fclose($file); - return; - } else - { - if($gzip){ - $gzippedData = ($data?gzencode($filePathOrData,9):gzencode(file_get_contents($filePathOrData), 9)); - $size = strlen($gzippedData); - } - HTMLWriter::generateAttachmentsHeader($localName, $size, $isFile, $gzip); - if($gzip){ - print $gzippedData; - return; - } - } - } - - if($data){ - print($filePathOrData); - }else{ - if($this->getFilteredOption("USE_XSENDFILE", $this->repository->getId()) && $this->wrapperClassName == "fsAccessWrapper"){ - if(!$realfileSystem) $filePathOrData = fsAccessWrapper::getRealFSReference($filePathOrData); - $filePathOrData = str_replace("\\", "/", $filePathOrData); - $server_name = $_SERVER["SERVER_SOFTWARE"]; - $regex = '/^(lighttpd\/1.4).([0-9]{2}$|[0-9]{3}$|[0-9]{4}$)+/'; - if(preg_match($regex, $server_name)) - $header_sendfile = "X-LIGHTTPD-send-file"; - else - $header_sendfile = "X-Sendfile"; - header($header_sendfile.": ".SystemTextEncoding::toUTF8($filePathOrData)); - header("Content-type: application/octet-stream"); - header('Content-Disposition: attachment; filename="' . basename($filePathOrData) . '"'); - return; - } - if($this->getFilteredOption("USE_XACCELREDIRECT", $this->repository->getId()) && $this->wrapperClassName == "fsAccessWrapper" && array_key_exists("X-Accel-Mapping",$_SERVER)){ - if(!$realfileSystem) $filePathOrData = fsAccessWrapper::getRealFSReference($filePathOrData); - $filePathOrData = str_replace("\\", "/", $filePathOrData); - $filePathOrData = SystemTextEncoding::toUTF8($filePathOrData); - $mapping = explode('=',$_SERVER['X-Accel-Mapping']); - $replacecount = 0; - $accelfile = str_replace($mapping[0],$mapping[1],$filePathOrData,$replacecount); - if($replacecount == 1){ - header("X-Accel-Redirect: $accelfile"); - header("Content-type: application/octet-stream"); - header('Content-Disposition: attachment; filename="' . basename($accelfile) . '"'); - return; - } else { - AJXP_Logger::logAction("error","Problem with X-Accel-Mapping for file $filePathOrData"); - } - } - $stream = fopen("php://output", "a"); - if($realfileSystem){ - AJXP_Logger::debug("realFS!", array("file"=>$filePathOrData)); - $fp = fopen($filePathOrData, "rb"); - if($byteOffset != -1){ - fseek($fp, $byteOffset); - } - $sentSize = 0; - $readChunk = 4096; - while (!feof($fp)) { - if( $byteLength != -1 && ($sentSize + $readChunk) >= $byteLength){ - // compute last chunk and break after - $readChunk = $byteLength - $sentSize; - $break = true; - } - $data = fread($fp, $readChunk); - $dataSize = strlen($data); - fwrite($stream, $data, $dataSize); - $sentSize += $dataSize; - if(isSet($break)){ - break; - } - } - fclose($fp); - }else{ - call_user_func(array($this->wrapperClassName, "copyFileInStream"), $filePathOrData, $stream); - } - fflush($stream); - fclose($stream); - } - } - - function countFiles($dirName, $foldersOnly = false, $nonEmptyCheckOnly = false){ - $handle=@opendir($dirName); - if($handle === false){ - throw new Exception("Error while trying to open directory ".$dirName); - } - if($foldersOnly && !call_user_func(array($this->wrapperClassName, "isRemote"))){ - closedir($handle); - $path = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $dirName); - $dirs = glob($path."/*", GLOB_ONLYDIR|GLOB_NOSORT); - if($dirs === false) return 0; - return count($dirs); - } - $count = 0; - $showHiddenFiles = $this->getFilteredOption("SHOW_HIDDEN_FILES", $this->repository->getId()); - while (strlen($file = readdir($handle)) > 0) - { - if($file != "." && $file !=".." - && !(AJXP_Utils::isHidden($file) && !$showHiddenFiles)){ - if($foldersOnly && is_file($dirName."/".$file)) continue; - $count++; - if($nonEmptyCheckOnly) break; - } - } - closedir($handle); - return $count; - } - - function date_modif($file) - { - $tmp = @filemtime($file) or 0; - return $tmp;// date("d,m L Y H:i:s",$tmp); - } - - function changeMode($filePath) - { - $chmodValue = $this->repository->getOption("CHMOD_VALUE"); - if(isSet($chmodValue) && $chmodValue != "") - { - $chmodValue = octdec(ltrim($chmodValue, "0")); - call_user_func(array($this->wrapperClassName, "changeMode"), $filePath, $chmodValue); - } - } - - function filesystemFileSize($filePath){ - $bytesize = "-"; - $bytesize = @filesize($filePath); - if(method_exists($this->wrapperClassName, "getLastRealSize")){ - $last = call_user_func(array($this->wrapperClassName, "getLastRealSize")); - if($last !== false){ - $bytesize = $last; - } - } - if($bytesize < 0){ - $bytesize = sprintf("%u", $bytesize); - } - - return $bytesize; - } - - /** - * Extract an archive directly inside the dest directory. - * - * @param string $destDir - * @param UserSelection $selection - * @param array $error - * @param array $success - */ - function extractArchive($destDir, $selection, &$error, &$success){ - require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); - $zipPath = $selection->getZipPath(true); - $zipLocalPath = $selection->getZipLocalPath(true); - if(strlen($zipLocalPath)>1 && $zipLocalPath[0] == "/") $zipLocalPath = substr($zipLocalPath, 1)."/"; - $files = $selection->getFiles(); - - $realZipFile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $this->urlBase.$zipPath); - $archive = new PclZip($realZipFile); - $content = $archive->listContent(); - foreach ($files as $key => $item){// Remove path - $item = substr($item, strlen($zipPath)); - if($item[0] == "/") $item = substr($item, 1); - foreach ($content as $zipItem){ - if($zipItem["stored_filename"] == $item || $zipItem["stored_filename"] == $item."/"){ - $files[$key] = $zipItem["stored_filename"]; - break; - }else{ - unset($files[$key]); - } - } - } - AJXP_Logger::debug("Archive", $this->addSlugToPath($files)); - $realDestination = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $this->urlBase.$destDir); - AJXP_Logger::debug("Extract", array($realDestination, $realZipFile, $this->addSlugToPath($files), $zipLocalPath)); - $result = $archive->extract(PCLZIP_OPT_BY_NAME, $files, - PCLZIP_OPT_PATH, $realDestination, - PCLZIP_OPT_REMOVE_PATH, $zipLocalPath); - if($result <= 0){ - $error[] = $archive->errorInfo(true); - }else{ - $mess = ConfService::getMessages(); - $success[] = sprintf($mess[368], basename($zipPath), $destDir); - } - } - - function copyOrMove($destDir, $selectedFiles, &$error, &$success, $move = false) - { - AJXP_Logger::debug("CopyMove", array("dest"=>$this->addSlugToPath($destDir), "selection" => $this->addSlugToPath($selectedFiles))); - $mess = ConfService::getMessages(); - if(!$this->isWriteable($this->urlBase.$destDir)) - { - $error[] = $mess[38]." ".$destDir." ".$mess[99]; - return ; - } - - foreach ($selectedFiles as $selectedFile) - { - if($move && !$this->isWriteable(dirname($this->urlBase.$selectedFile))) - { - $error[] = "\n".$mess[38]." ".dirname($selectedFile)." ".$mess[99]; - continue; - } - $this->copyOrMoveFile($destDir, $selectedFile, $error, $success, $move); - } - } - - function renameAction($actionName, $httpVars) - { - $filePath = SystemTextEncoding::fromUTF8($httpVars["file"]); - $newFilename = SystemTextEncoding::fromUTF8($httpVars["filename_new"]); - return $this->rename($filePath, $newFilename); - } - - function rename($filePath, $filename_new, $dest = null) - { - $nom_fic=basename($filePath); - $mess = ConfService::getMessages(); - $filename_new=AJXP_Utils::sanitize(SystemTextEncoding::magicDequote($filename_new), AJXP_SANITIZE_HTML_STRICT); - $filename_new = substr($filename_new, 0, ConfService::getCoreConf("NODENAME_MAX_LENGTH")); - $old=$this->urlBase."/$filePath"; - if(!$this->isWriteable($old)) - { - throw new AJXP_Exception($mess[34]." ".$nom_fic." ".$mess[99]); - } - if($dest == null) $new=dirname($old)."/".$filename_new; - else $new = $this->urlBase.$dest; - if($filename_new=="" && $dest == null) - { - throw new AJXP_Exception("$mess[37]"); - } - if(file_exists($new)) - { - throw new AJXP_Exception("$filename_new $mess[43]"); - } - if(!file_exists($old)) - { - throw new AJXP_Exception($mess[100]." $nom_fic"); - } - $oldNode = new AJXP_Node($old); - AJXP_Controller::applyHook("node.before_path_change", array(&$oldNode)); - rename($old,$new); - AJXP_Controller::applyHook("node.change", array($oldNode, new AJXP_Node($new), false)); - } - - public static function autoRenameForDest($destination, $fileName){ - if(!is_file($destination."/".$fileName)) return $fileName; - $i = 1; - $ext = ""; - $name = ""; - $split = explode(".", $fileName); - if(count($split) > 1){ - $ext = ".".$split[count($split)-1]; - array_pop($split); - $name = join(".", $split); - }else{ - $name = $fileName; - } - while (is_file($destination."/".$name."-$i".$ext)) { - $i++; // increment i until finding a non existing file. - } - return $name."-$i".$ext; - } - - function mkDir($crtDir, $newDirName, $ignoreExists = false) - { - $currentNodeDir = new AJXP_Node($this->urlBase.$crtDir); - AJXP_Controller::applyHook("node.before_change", array(&$currentNodeDir)); - - $mess = ConfService::getMessages(); - if($newDirName=="") - { - return "$mess[37]"; - } - if(file_exists($this->urlBase."$crtDir/$newDirName")) - { - if($ignoreExists) return null; - return "$mess[40]"; - } - if(!$this->isWriteable($this->urlBase."$crtDir")) - { - return $mess[38]." $crtDir ".$mess[99]; - } - - $dirMode = 0775; - $chmodValue = $this->repository->getOption("CHMOD_VALUE"); - if(isSet($chmodValue) && $chmodValue != "") - { - $dirMode = octdec(ltrim($chmodValue, "0")); - if ($dirMode & 0400) $dirMode |= 0100; // User is allowed to read, allow to list the directory - if ($dirMode & 0040) $dirMode |= 0010; // Group is allowed to read, allow to list the directory - if ($dirMode & 0004) $dirMode |= 0001; // Other are allowed to read, allow to list the directory - } - $old = umask(0); - mkdir($this->urlBase."$crtDir/$newDirName", $dirMode); - umask($old); - $newNode = new AJXP_Node($this->urlBase.$crtDir."/".$newDirName); - AJXP_Controller::applyHook("node.change", array(null, $newNode, false)); - return null; - } - - function createEmptyFile($crtDir, $newFileName, $content = "") - { - if(($content == "") && preg_match("/\.html$/",$newFileName)||preg_match("/\.htm$/",$newFileName)){ - $content = "\n\nNew Document - Created By AjaXplorer\n\n\n\n\n\n\n"; - AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($this->urlBase.$crtDir."/".$newFileName), strlen($content))); - } - AJXP_Controller::applyHook("node.before_change", array(new AJXP_Node($this->urlBase.$crtDir))); - $mess = ConfService::getMessages(); - if($newFileName=="") - { - return "$mess[37]"; - } - if(file_exists($this->urlBase."$crtDir/$newFileName")) - { - return "$mess[71]"; - } - if(!$this->isWriteable($this->urlBase."$crtDir")) - { - return "$mess[38] $crtDir $mess[99]"; - } - $fp=fopen($this->urlBase."$crtDir/$newFileName","w"); - if($fp) - { - if($content != ""){ - fputs($fp, $content); - } - $this->changeMode($this->urlBase."$crtDir/$newFileName"); - fclose($fp); - $newNode = new AJXP_Node($this->urlBase."$crtDir/$newFileName"); - AJXP_Controller::applyHook("node.change", array(null, $newNode, false)); - return null; - } - else - { - return "$mess[102] $crtDir/$newFileName (".$fp.")"; - } - } - - - function delete($selectedFiles, &$logMessages) - { - $mess = ConfService::getMessages(); - foreach ($selectedFiles as $selectedFile) - { - if($selectedFile == "" || $selectedFile == DIRECTORY_SEPARATOR) - { - return $mess[120]; - } - $fileToDelete=$this->urlBase.$selectedFile; - if(!file_exists($fileToDelete)) - { - $logMessages[]=$mess[100]." ".SystemTextEncoding::toUTF8($selectedFile); - continue; - } - $this->deldir($fileToDelete); - if(is_dir($fileToDelete)) - { - $logMessages[]="$mess[38] ".SystemTextEncoding::toUTF8($selectedFile)." $mess[44]."; - } - else - { - $logMessages[]="$mess[34] ".SystemTextEncoding::toUTF8($selectedFile)." $mess[44]."; - } - AJXP_Controller::applyHook("node.change", array(new AJXP_Node($fileToDelete))); - } - return null; - } - - - - function copyOrMoveFile($destDir, $srcFile, &$error, &$success, $move = false) - { - $mess = ConfService::getMessages(); - $destFile = $this->urlBase.$destDir."/".basename($srcFile); - $realSrcFile = $this->urlBase.$srcFile; - - if (is_dir(dirname($realSrcFile)) && (strpos($destFile, rtrim($realSrcFile, "/") . "/") === 0)) - { - $error[] = $mess[101]; - return; - } - - if(!file_exists($realSrcFile)) - { - $error[] = $mess[100].$srcFile; - return ; - } - if(!$move){ - AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($destFile), filesize($realSrcFile))); - } - if(dirname($realSrcFile)==dirname($destFile)) - { - if($move){ - $error[] = $mess[101]; - return ; - }else{ - $base = basename($srcFile); - $i = 1; - if(is_file($realSrcFile)){ - $dotPos = strrpos($base, "."); - if($dotPos>-1){ - $radic = substr($base, 0, $dotPos); - $ext = substr($base, $dotPos); - } - } - // auto rename file - $i = 1; - $newName = $base; - while (file_exists($this->urlBase.$destDir."/".$newName)) { - $suffix = "-$i"; - if(isSet($radic)) $newName = $radic . $suffix . $ext; - else $newName = $base.$suffix; - $i++; - } - $destFile = $this->urlBase.$destDir."/".$newName; - } - } - if(!is_file($realSrcFile)) - { - $errors = array(); - $succFiles = array(); - if($move){ - AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($realSrcFile))); - if(file_exists($destFile)) $this->deldir($destFile); - $res = rename($realSrcFile, $destFile); - }else{ - $dirRes = $this->dircopy($realSrcFile, $destFile, $errors, $succFiles); - } - if(count($errors) || (isSet($res) && $res!==true)) - { - $error[] = $mess[114]; - return ; - }else{ - AJXP_Controller::applyHook("node.change", array(new AJXP_Node($realSrcFile), new AJXP_Node($destFile), !$move)); - } - } - else - { - if($move){ - AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($realSrcFile))); - if(file_exists($destFile)) unlink($destFile); - $res = rename($realSrcFile, $destFile); - AJXP_Controller::applyHook("node.change", array(new AJXP_Node($realSrcFile), new AJXP_Node($destFile), false)); - }else{ - try{ - if(call_user_func(array($this->wrapperClassName, "isRemote"))){ - $src = fopen($realSrcFile, "r"); - $dest = fopen($destFile, "w"); - if($dest !== false){ - while (!feof($src)) { - stream_copy_to_stream($src, $dest, 4096); - } - fclose($dest); - } - fclose($src); - }else{ - copy($realSrcFile, $destFile); - } - $this->changeMode($destFile); - AJXP_Controller::applyHook("node.change", array(new AJXP_Node($realSrcFile), new AJXP_Node($destFile), true)); - }catch (Exception $e){ - $error[] = $e->getMessage(); - return ; - } - } - } - - if($move) - { - // Now delete original - // $this->deldir($realSrcFile); // both file and dir - $messagePart = $mess[74]." ".SystemTextEncoding::toUTF8($destDir); - if(RecycleBinManager::recycleEnabled() && $destDir == RecycleBinManager::getRelativeRecycle()) - { - RecycleBinManager::fileToRecycle($srcFile); - $messagePart = $mess[123]." ".$mess[122]; - } - if(isset($dirRes)) - { - $success[] = $mess[117]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$messagePart." (".SystemTextEncoding::toUTF8($dirRes)." ".$mess[116].") "; - } - else - { - $success[] = $mess[34]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$messagePart; - } - } - else - { - if(RecycleBinManager::recycleEnabled() && $destDir == "/".$this->repository->getOption("RECYCLE_BIN")) - { - RecycleBinManager::fileToRecycle($srcFile); - } - if(isSet($dirRes)) - { - $success[] = $mess[117]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$mess[73]." ".SystemTextEncoding::toUTF8($destDir)." (".SystemTextEncoding::toUTF8($dirRes)." ".$mess[116].")"; - } - else - { - $success[] = $mess[34]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$mess[73]." ".SystemTextEncoding::toUTF8($destDir); - } - } - - } - - // A function to copy files from one directory to another one, including subdirectories and - // nonexisting or newer files. Function returns number of files copied. - // This function is PHP implementation of Windows xcopy A:\dir1\* B:\dir2 /D /E /F /H /R /Y - // Syntaxis: [$number =] dircopy($sourcedirectory, $destinationdirectory [, $verbose]); - // Example: $num = dircopy('A:\dir1', 'B:\dir2', 1); - - function dircopy($srcdir, $dstdir, &$errors, &$success, $verbose = false, $convertSrcFile = true) - { - $num = 0; - //$verbose = true; - $recurse = array(); - if(!is_dir($dstdir)) mkdir($dstdir); - if($curdir = opendir($srcdir)) - { - while($file = readdir($curdir)) - { - if($file != '.' && $file != '..') - { - $srcfile = $srcdir . "/" . $file; - $dstfile = $dstdir . "/" . $file; - if(is_file($srcfile)) - { - if(is_file($dstfile)) $ow = filemtime($srcfile) - filemtime($dstfile); else $ow = 1; - if($ow > 0) - { - try { - if($convertSrcFile) $tmpPath = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $srcfile); - else $tmpPath = $srcfile; - if($verbose) echo "Copying '$tmpPath' to '$dstfile'..."; - copy($tmpPath, $dstfile); - $success[] = $srcfile; - $num ++; - $this->changeMode($dstfile); - }catch (Exception $e){ - $errors[] = $srcfile; - } - } - } - else{ - $recurse[] = array("src" => $srcfile, "dest"=> $dstfile); - } - } - } - closedir($curdir); - foreach($recurse as $rec){ - if($verbose) echo "Dircopy $srcfile"; - $num += $this->dircopy($rec["src"], $rec["dest"], $errors, $success, $verbose, $convertSrcFile); - } - } - return $num; - } - - function simpleCopy($origFile, $destFile) - { - return copy($origFile, $destFile); - } - - public function isWriteable($dir, $type="dir") - { - if( $this->getFilteredOption("USE_POSIX", $this->repository->getId()) == true && extension_loaded('posix')){ - $real = call_user_func(array( $this->wrapperClassName, "getRealFSReference"), $dir); - return posix_access($real, POSIX_W_OK); - } - return is_writable($dir); - } - - function deldir($location) - { - if(is_dir($location)) - { - AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($location))); - $all=opendir($location); - while ($file=readdir($all)) - { - if (is_dir("$location/$file") && $file !=".." && $file!=".") - { - $this->deldir("$location/$file"); - if(file_exists("$location/$file")){ - rmdir("$location/$file"); - } - unset($file); - } - elseif (!is_dir("$location/$file")) - { - if(file_exists("$location/$file")){ - unlink("$location/$file"); - } - unset($file); - } - } - closedir($all); - rmdir($location); - } - else - { - if(file_exists("$location")) { - AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($location))); - $test = @unlink("$location"); - if(!$test) throw new Exception("Cannot delete file ".$location); - } - } - if(basename(dirname($location)) == $this->repository->getOption("RECYCLE_BIN")) - { - // DELETING FROM RECYCLE - RecycleBinManager::deleteFromRecycle($location); - } - } - - /** - * Change file permissions - * - * @param String $path - * @param String $chmodValue - * @param Boolean $recursive - * @param String $nodeType "both", "file", "dir" - */ - function chmod($path, $chmodValue, $recursive=false, $nodeType="both", &$changedFiles) - { - $realValue = octdec(ltrim($chmodValue, "0")); - if(is_file($this->urlBase.$path)){ - if($nodeType=="both" || $nodeType=="file"){ - call_user_func(array($this->wrapperClassName, "changeMode"), $this->urlBase.$path, $realValue); - $changedFiles[] = $path; - } - }else{ - if($nodeType=="both" || $nodeType=="dir"){ - call_user_func(array($this->wrapperClassName, "changeMode"), $this->urlBase.$path, $realValue); - $changedFiles[] = $path; - } - if($recursive){ - $handler = opendir($this->urlBase.$path); - while ($child=readdir($handler)) { - if($child == "." || $child == "..") continue; - // do not pass realValue or it will be re-decoded. - $this->chmod($path."/".$child, $chmodValue, $recursive, $nodeType, $changedFiles); - } - closedir($handler); - } - } - } - - /** - * @param String $from - * @param String $to - * @param Boolean $copy - */ - function nodeChanged(&$from, &$to, $copy = false){ - $fromNode = $toNode = null; - if($from != null) $fromNode = new AJXP_Node($this->urlBase.$from); - if($to != null) $toNode = new AJXP_Node($this->urlBase.$to); - AJXP_Controller::applyHook("node.change", array($fromNode, $toNode, $copy)); - } - - /** - * @param String $node - */ - function nodeWillChange($node, $newSize = null){ - if($newSize != null){ - AJXP_Controller::applyHook("node.before_change", array(new AJXP_Node($this->urlBase.$node), $newSize)); - }else{ - AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($this->urlBase.$node))); - } - } - - - /** - * @var fsAccessDriver - */ - public static $filteringDriverInstance; - /** - * @return zipfile - */ - function makeZip ($src, $dest, $basedir) - { - @set_time_limit(0); - require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); - $filePaths = array(); - foreach ($src as $item){ - $realFile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $this->urlBase."/".$item); - $realFile = AJXP_Utils::securePath($realFile); - $basedir = trim(dirname($realFile)); - if(basename($item) == ""){ - $filePaths[] = array(PCLZIP_ATT_FILE_NAME => $realFile); - }else{ - $filePaths[] = array(PCLZIP_ATT_FILE_NAME => $realFile, - PCLZIP_ATT_FILE_NEW_SHORT_NAME => basename($item)); - } - } - AJXP_Logger::debug("Pathes", $filePaths); - AJXP_Logger::debug("Basedir", array($basedir)); - self::$filteringDriverInstance = $this; - $archive = new PclZip($dest); - $vList = $archive->create($filePaths, PCLZIP_OPT_REMOVE_PATH, $basedir, PCLZIP_OPT_NO_COMPRESSION, PCLZIP_OPT_ADD_TEMP_FILE_ON, PCLZIP_CB_PRE_ADD, 'zipPreAddCallback'); - if(!$vList){ - throw new Exception("Zip creation error : ($dest) ".$archive->errorInfo(true)); - } - self::$filteringDriverInstance = null; - return $vList; - } - - - function recursivePurge($dirName, $purgeTime){ - - $handle=opendir($dirName); - $count = 0; - while (strlen($file = readdir($handle)) > 0) - { - if($file == "" || $file == ".." || AJXP_Utils::isHidden($file) ){ - continue; - } - if(is_file($dirName."/".$file)){ - $time = filemtime($dirName."/".$file); - $docAge = time() - $time; - if( $docAge > $purgeTime){ - $node = new AJXP_Node($dirName."/".$file); - AJXP_Controller::applyHook("node.before_path_change", array($node)); - unlink($dirName."/".$file); - AJXP_Controller::applyHook("node.change", array($node)); - AJXP_Logger::logAction("Purge", array("file" => $dirName."/".$file)); - print(" - Purging document : ".$dirName."/".$file."\n"); - } - }else{ - $this->recursivePurge($dirName."/".$file, $purgeTime); - } - } - closedir($handle); - - - } - - - /** The publiclet URL making */ - function makePublicletOptions($filePath, $password, $expire, $downloadlimit, $repository) - { - $data = array( - "DRIVER"=>$repository->getAccessType(), - "OPTIONS"=>NULL, - "FILE_PATH"=>$filePath, - "ACTION"=>"download", - "EXPIRE_TIME"=>$expire ? (time() + $expire * 86400) : 0, - "DOWNLOAD_LIMIT"=>$downloadlimit ? $downloadlimit : 0, - "PASSWORD"=>$password - ); - return $data; - } - - function makeSharedRepositoryOptions($httpVars, $repository){ - $newOptions = array( - "PATH" => $repository->getOption("PATH").AJXP_Utils::decodeSecureMagic($httpVars["file"]), - "CREATE" => false, - "RECYCLE_BIN" => "", - "DEFAULT_RIGHTS" => ""); - if($repository->getOption("USE_SESSION_CREDENTIALS")===true){ - $newOptions["ENCODED_CREDENTIALS"] = AJXP_Safe::getEncodedCredentialString(); - } - return $newOptions; - } - - -} - - function zipPreAddCallback($value, $header){ - if(fsAccessDriver::$filteringDriverInstance == null) return true; - $search = $header["filename"]; - return !(fsAccessDriver::$filteringDriverInstance->filterFile($search) - || fsAccessDriver::$filteringDriverInstance->filterFolder($search, "contains")); - } - - -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + + +// This is used to catch exception while downloading +if (!function_exists('download_exception_handler')) { + function download_exception_handler($exception){} +} + +/** + * AJXP_Plugin to access a filesystem. Most "FS" like driver (even remote ones) + * extend this one. + * @package AjaXplorer_Plugins + * @subpackage Access + */ +class fsAccessDriver extends AbstractAccessDriver implements AjxpWrapperProvider +{ + /** + * @var Repository + */ + public $repository; + public $driverConf; + protected $wrapperClassName; + protected $urlBase; + private static $loadedUserBookmarks; + + public function initRepository() + { + if (is_array($this->pluginConf)) { + $this->driverConf = $this->pluginConf; + } else { + $this->driverConf = array(); + } + if ( $this->getFilteredOption("PROBE_REAL_SIZE", $this->repository->getId()) == true ) { + // PASS IT TO THE WRAPPER + ConfService::setConf("PROBE_REAL_SIZE", $this->getFilteredOption("PROBE_REAL_SIZE", $this->repository->getId())); + } + $create = $this->repository->getOption("CREATE"); + $path = $this->repository->getOption("PATH"); + $recycle = $this->repository->getOption("RECYCLE_BIN"); + if ($create == true) { + if(!is_dir($path)) @mkdir($path, 0755, true); + if (!is_dir($path)) { + throw new AJXP_Exception("Cannot create root path for repository (".$this->repository->getDisplay()."). Please check repository configuration or that your folder is writeable!"); + } + if ($recycle!= "" && !is_dir($path."/".$recycle)) { + @mkdir($path."/".$recycle); + if (!is_dir($path."/".$recycle)) { + throw new AJXP_Exception("Cannot create recycle bin folder. Please check repository configuration or that your folder is writeable!"); + } + } + $dataTemplate = $this->repository->getOption("DATA_TEMPLATE"); + if (!empty($dataTemplate) && is_dir($dataTemplate) && !is_file($path."/.ajxp_template")) { + $errs = array();$succ = array(); + $this->dircopy($dataTemplate, $path, $succ, $errs, false, false); + touch($path."/.ajxp_template"); + } + } else { + if (!is_dir($path)) { + throw new AJXP_Exception("Cannot find base path for your repository! Please check the configuration!"); + } + } + $wrapperData = $this->detectStreamWrapper(true); + $this->wrapperClassName = $wrapperData["classname"]; + $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); + if ($recycle != "") { + RecycleBinManager::init($this->urlBase, "/".$recycle); + } + } + + public function getResourceUrl($path) + { + return $this->urlBase.$path; + } + + public function getWrapperClassName() + { + return $this->wrapperClassName; + } + + public function redirectActionsToMethod(&$contribNode, $arrayActions, $targetMethod) + { + $actionXpath=new DOMXPath($contribNode->ownerDocument); + foreach ($arrayActions as $index => $value) { + $arrayActions[$index] = 'action[@name="'.$value.'"]/processing/serverCallback'; + } + $procList = $actionXpath->query(implode(" | ", $arrayActions), $contribNode); + foreach ($procList as $node) { + $node->setAttribute("methodName", $targetMethod); + } + } + + public function disableArchiveBrowsingContributions(&$contribNode) + { + // Cannot use zip features on FTP ! + // Remove "compress" action + $actionXpath=new DOMXPath($contribNode->ownerDocument); + $compressNodeList = $actionXpath->query('action[@name="compress"]', $contribNode); + if(!$compressNodeList->length) return ; + unset($this->actions["compress"]); + $compressNode = $compressNodeList->item(0); + $contribNode->removeChild($compressNode); + // Disable "download" if selection is multiple + $nodeList = $actionXpath->query('action[@name="download"]/gui/selectionContext', $contribNode); + $selectionNode = $nodeList->item(0); + $values = array("dir" => "false", "unique" => "true"); + foreach ($selectionNode->attributes as $attribute) { + if (isSet($values[$attribute->name])) { + $attribute->value = $values[$attribute->name]; + } + } + $nodeList = $actionXpath->query('action[@name="download"]/processing/clientListener[@name="selectionChange"]', $contribNode); + $listener = $nodeList->item(0); + $listener->parentNode->removeChild($listener); + // Disable "Explore" action on files + $nodeList = $actionXpath->query('action[@name="ls"]/gui/selectionContext', $contribNode); + $selectionNode = $nodeList->item(0); + $values = array("file" => "false", "allowedMimes" => ""); + foreach ($selectionNode->attributes as $attribute) { + if (isSet($values[$attribute->name])) { + $attribute->value = $values[$attribute->name]; + } + } + } + + protected function getNodesDiffArray() + { + return array("REMOVE" => array(), "ADD" => array(), "UPDATE" => array()); + } + + public function addSlugToPath($selection) + { + if (is_array($selection)) + // As passed by Copy/Move + $orig_files = $selection; + elseif ((is_object($selection)) && (isset($selection->files)) && (is_array($selection->files))) + // As passed by Download + $orig_files = $selection->files; + elseif (is_string($selection)) + // As passed by destination parameter + return $this->repository->slug.$selection; + else + // Unrecognized + return $selection; + + $files = array(); + foreach ($orig_files as $file) + $files[] = $this->repository->slug.$file; + return $files; + } + + public function switchAction($action, $httpVars, $fileVars) + { + if(!isSet($this->actions[$action])) return; + parent::accessPreprocess($action, $httpVars, $fileVars); + $selection = new UserSelection(); + $dir = $httpVars["dir"] OR ""; + if ($this->wrapperClassName == "fsAccessWrapper") { + $dir = fsAccessWrapper::patchPathForBaseDir($dir); + } + $dir = AJXP_Utils::securePath($dir); + if ($action != "upload") { + $dir = AJXP_Utils::decodeSecureMagic($dir); + } + $selection->initFromHttpVars($httpVars); + if (!$selection->isEmpty()) { + $this->filterUserSelectionToHidden($selection->getFiles()); + } + $mess = ConfService::getMessages(); + + $newArgs = RecycleBinManager::filterActions($action, $selection, $dir, $httpVars); + if(isSet($newArgs["action"])) $action = $newArgs["action"]; + if(isSet($newArgs["dest"])) $httpVars["dest"] = SystemTextEncoding::toUTF8($newArgs["dest"]);//Re-encode! + // FILTER DIR PAGINATION ANCHOR + $page = null; + if (isSet($dir) && strstr($dir, "%23")!==false) { + $parts = explode("%23", $dir); + $dir = $parts[0]; + $page = $parts[1]; + } + + $pendingSelection = ""; + $logMessage = null; + $reloadContextNode = false; + + switch ($action) { + //------------------------------------ + // DOWNLOAD + //------------------------------------ + case "download": + AJXP_Logger::logAction("Download", array("files"=>$this->addSlugToPath($selection))); + @set_error_handler(array("HTMLWriter", "javascriptErrorHandler"), E_ALL & ~ E_NOTICE); + @register_shutdown_function("restore_error_handler"); + $zip = false; + if ($selection->isUnique()) { + if (is_dir($this->urlBase.$selection->getUniqueFile())) { + $zip = true; + $base = basename($selection->getUniqueFile()); + $dir .= "/".dirname($selection->getUniqueFile()); + } else { + if (!file_exists($this->urlBase.$selection->getUniqueFile())) { + throw new Exception("Cannot find file!"); + } + } + $node = $selection->getUniqueNode($this); + } else { + $zip = true; + } + if ($zip) { + // Make a temp zip and send it as download + $loggedUser = AuthService::getLoggedUser(); + $file = AJXP_Utils::getAjxpTmpDir()."/".($loggedUser?$loggedUser->getId():"shared")."_".time()."tmpDownload.zip"; + $zipFile = $this->makeZip($selection->getFiles(), $file, $dir); + if(!$zipFile) throw new AJXP_Exception("Error while compressing"); + register_shutdown_function("unlink", $file); + $localName = ($base==""?"Files":$base).".zip"; + $this->readFile($file, "force-download", $localName, false, false, true); + } else { + $localName = ""; + AJXP_Controller::applyHook("dl.localname", array($this->urlBase.$selection->getUniqueFile(), &$localName, $this->wrapperClassName)); + $this->readFile($this->urlBase.$selection->getUniqueFile(), "force-download", $localName); + } + if (isSet($node)) { + AJXP_Controller::applyHook("node.read", array(&$node)); + } + + + break; + + case "prepare_chunk_dl" : + + $chunkCount = intval($httpVars["chunk_count"]); + $fileId = $this->urlBase.$selection->getUniqueFile(); + $sessionKey = "chunk_file_".md5($fileId.time()); + $totalSize = $this->filesystemFileSize($fileId); + $chunkSize = intval ( $totalSize / $chunkCount ); + $realFile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $fileId, true); + $chunkData = array( + "localname" => basename($fileId), + "chunk_count" => $chunkCount, + "chunk_size" => $chunkSize, + "total_size" => $totalSize, + "file_id" => $sessionKey + ); + + $_SESSION[$sessionKey] = array_merge($chunkData, array("file"=>$realFile)); + HTMLWriter::charsetHeader("application/json"); + print(json_encode($chunkData)); + + $node = $selection->getUniqueNode($this); + AJXP_Controller::applyHook("node.read", array(&$node)); + + break; + + case "download_chunk" : + + $chunkIndex = intval($httpVars["chunk_index"]); + $chunkKey = $httpVars["file_id"]; + $sessData = $_SESSION[$chunkKey]; + $realFile = $sessData["file"]; + $chunkSize = $sessData["chunk_size"]; + $offset = $chunkSize * $chunkIndex; + if ($chunkIndex == $sessData["chunk_count"]-1) { + // Compute the last chunk real length + $chunkSize = $sessData["total_size"] - ($chunkSize * ($sessData["chunk_count"]-1)); + if (call_user_func(array($this->wrapperClassName, "isRemote"))) { + register_shutdown_function("unlink", $realFile); + } + } + $this->readFile($realFile, "force-download", $sessData["localname"].".".sprintf("%03d", $chunkIndex+1), false, false, true, $offset, $chunkSize); + + + break; + + case "compress" : + // Make a temp zip and send it as download + $loggedUser = AuthService::getLoggedUser(); + if (isSet($httpVars["archive_name"])) { + $localName = AJXP_Utils::decodeSecureMagic($httpVars["archive_name"]); + $this->filterUserSelectionToHidden(array($localName)); + } else { + $localName = (basename($dir)==""?"Files":basename($dir)).".zip"; + } + $file = AJXP_Utils::getAjxpTmpDir()."/".($loggedUser?$loggedUser->getId():"shared")."_".time()."tmpCompression.zip"; + $zipFile = $this->makeZip($selection->getFiles(), $file, $dir); + if(!$zipFile) throw new AJXP_Exception("Error while compressing file $localName"); + register_shutdown_function("unlink", $file); + $tmpFNAME = $this->urlBase.$dir."/".str_replace(".zip", ".tmp", $localName); + copy($file, $tmpFNAME); + try { + AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($tmpFNAME), filesize($tmpFNAME))); + } catch (Exception $e) { + @unlink($tmpFNAME); + throw $e; + } + @rename($tmpFNAME, $this->urlBase.$dir."/".$localName); + AJXP_Controller::applyHook("node.change", array(null, new AJXP_Node($this->urlBase.$dir."/".$localName), false)); + //$reloadContextNode = true; + //$pendingSelection = $localName; + $newNode = new AJXP_Node($this->urlBase.$dir."/".$localName); + if(!isset($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); + $nodesDiffs["ADD"][] = $newNode; + break; + + case "stat" : + + clearstatcache(); + $stat = @stat($this->urlBase.$selection->getUniqueFile()); + header("Content-type:application/json"); + if (!$stat) { + print '{}'; + } else { + print json_encode($stat); + } + + break; + + + //------------------------------------ + // ONLINE EDIT + //------------------------------------ + case "get_content": + + $dlFile = $this->urlBase.$selection->getUniqueFile(); + AJXP_Logger::logAction("Get_content", array("files"=>$this->addSlugToPath($selection))); + if (AJXP_Utils::getStreamingMimeType(basename($dlFile))!==false) { + $this->readFile($this->urlBase.$selection->getUniqueFile(), "stream_content"); + } else { + $this->readFile($this->urlBase.$selection->getUniqueFile(), "plain"); + } + $node = $selection->getUniqueNode($this); + AJXP_Controller::applyHook("node.read", array(&$node)); + + break; + + case "put_content": + if(!isset($httpVars["content"])) break; + // Load "code" variable directly from POST array, do not "securePath" or "sanitize"... + $code = $httpVars["content"]; + $file = $selection->getUniqueFile($httpVars["file"]); + AJXP_Logger::logAction("Online Edition", array("file"=>$this->addSlugToPath($file))); + if (isSet($httpVars["encode"]) && $httpVars["encode"] == "base64") { + $code = base64_decode($code); + } else { + $code = SystemTextEncoding::magicDequote($code); + $code=str_replace("<","<",$code); + } + $fileName = $this->urlBase.$file; + $currentNode = new AJXP_Node($fileName); + try { + AJXP_Controller::applyHook("node.before_change", array(&$currentNode, strlen($code))); + } catch (Exception $e) { + header("Content-Type:text/plain"); + print $e->getMessage(); + return; + } + if (!is_file($fileName) || !$this->isWriteable($fileName, "file")) { + header("Content-Type:text/plain"); + print((!$this->isWriteable($fileName, "file")?"1001":"1002")); + return ; + } + $fp=fopen($fileName,"w"); + fputs ($fp,$code); + fclose($fp); + clearstatcache(true, $fileName); + AJXP_Controller::applyHook("node.change", array($currentNode, $currentNode, false)); + header("Content-Type:text/plain"); + print($mess[115]); + + break; + + //------------------------------------ + // COPY / MOVE + //------------------------------------ + case "copy"; + case "move"; + + //throw new AJXP_Exception("", 113); + if ($selection->isEmpty()) { + throw new AJXP_Exception("", 113); + } + $success = $error = array(); + $dest = AJXP_Utils::decodeSecureMagic($httpVars["dest"]); + $this->filterUserSelectionToHidden(array($httpVars["dest"])); + if ($selection->inZip()) { + // Set action to copy anycase (cannot move from the zip). + $action = "copy"; + $this->extractArchive($dest, $selection, $error, $success); + } else { + $move = ($action == "move" ? true : false); + if ($move && isSet($httpVars["force_copy_delete"])) { + $move = false; + } + $this->copyOrMove($dest, $selection->getFiles(), $error, $success, $move); + + } + + if (count($error)) { + throw new AJXP_Exception(SystemTextEncoding::toUTF8(join("\n", $error))); + } else { + if (isSet($httpVars["force_copy_delete"])) { + $errorMessage = $this->delete($selection->getFiles(), $logMessages); + if($errorMessage) throw new AJXP_Exception(SystemTextEncoding::toUTF8($errorMessage)); + AJXP_Logger::logAction("Copy/Delete", array("files"=>$this->addSlugToPath($selection), "destination" => $this->addSlugToPath($dest))); + } else { + AJXP_Logger::logAction(($action=="move"?"Move":"Copy"), array("files"=>$this->addSlugToPath($selection), "destination"=>$this->addSlugToPath($dest))); + } + $logMessage = join("\n", $success); + } + if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); + // Assume new nodes are correctly created + $selectedItems = $selection->getFiles(); + foreach ($selectedItems as $selectedPath) { + $newPath = $this->urlBase.$dest ."/". basename($selectedPath); + $newNode = new AJXP_Node($newPath); + $nodesDiffs["ADD"][] = $newNode; + if($action == "move") $nodesDiffs["REMOVE"][] = $selectedPath; + } + if (!(RecycleBinManager::getRelativeRecycle() ==$dest && $this->getFilteredOption("HIDE_RECYCLE", $this->repository->getId()) == true)) { + //$reloadDataNode = $dest; + } + + break; + + //------------------------------------ + // DELETE + //------------------------------------ + case "delete"; + + if ($selection->isEmpty()) { + throw new AJXP_Exception("", 113); + } + $logMessages = array(); + $errorMessage = $this->delete($selection->getFiles(), $logMessages); + if (count($logMessages)) { + $logMessage = join("\n", $logMessages); + } + if($errorMessage) throw new AJXP_Exception(SystemTextEncoding::toUTF8($errorMessage)); + AJXP_Logger::logAction("Delete", array("files"=>$this->addSlugToPath($selection))); + if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); + $nodesDiffs["REMOVE"] = array_merge($nodesDiffs["REMOVE"], $selection->getFiles()); + + break; + + + case "purge" : + + + $pTime = intval($this->repository->getOption("PURGE_AFTER")); + if ($pTime > 0) { + $purgeTime = intval($pTime)*3600*24; + $this->recursivePurge($this->urlBase, $purgeTime); + } + + break; + + //------------------------------------ + // RENAME + //------------------------------------ + case "rename"; + + $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + $filename_new = AJXP_Utils::decodeSecureMagic($httpVars["filename_new"]); + $dest = null; + if (isSet($httpVars["dest"])) { + $dest = AJXP_Utils::decodeSecureMagic($httpVars["dest"]); + $filename_new = ""; + } + $this->filterUserSelectionToHidden(array($filename_new)); + $this->rename($file, $filename_new, $dest); + $logMessage= SystemTextEncoding::toUTF8($file)." $mess[41] ".SystemTextEncoding::toUTF8($filename_new); + //$reloadContextNode = true; + //$pendingSelection = $filename_new; + if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); + if($dest == null) $dest = dirname($file); + $nodesDiffs["UPDATE"][$file] = new AJXP_Node($this->urlBase.$dest."/".$filename_new); + AJXP_Logger::logAction("Rename", array("original"=>$this->addSlugToPath($file), "new"=>$filename_new)); + + break; + + //------------------------------------ + // CREER UN REPERTOIRE / CREATE DIR + //------------------------------------ + case "mkdir"; + + $messtmp=""; + $dirname=AJXP_Utils::decodeSecureMagic($httpVars["dirname"], AJXP_SANITIZE_HTML_STRICT); + $dirname = substr($dirname, 0, ConfService::getCoreConf("NODENAME_MAX_LENGTH")); + $this->filterUserSelectionToHidden(array($dirname)); + AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($dir."/".$dirname), -2)); + $error = $this->mkDir($dir, $dirname, isSet($httpVars["ignore_exists"])?true:false); + if (isSet($error)) { + throw new AJXP_Exception($error); + } + $messtmp.="$mess[38] ".SystemTextEncoding::toUTF8($dirname)." $mess[39] "; + if ($dir=="") {$messtmp.="/";} else {$messtmp.= SystemTextEncoding::toUTF8($dir);} + $logMessage = $messtmp; + //$pendingSelection = $dirname; + //$reloadContextNode = true; + $newNode = new AJXP_Node($this->urlBase.$dir."/".$dirname); + if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); + array_push($nodesDiffs["ADD"], $newNode); + AJXP_Logger::logAction("Create Dir", array("dir"=>$this->addSlugToPath($dir)."/".$dirname)); + + break; + + //------------------------------------ + // CREER UN FICHIER / CREATE FILE + //------------------------------------ + case "mkfile"; + + $messtmp=""; + $filename=AJXP_Utils::decodeSecureMagic($httpVars["filename"], AJXP_SANITIZE_HTML_STRICT); + $filename = substr($filename, 0, ConfService::getCoreConf("NODENAME_MAX_LENGTH")); + $this->filterUserSelectionToHidden(array($filename)); + $content = ""; + if (isSet($httpVars["content"])) { + $content = $httpVars["content"]; + } + $error = $this->createEmptyFile($dir, $filename, $content); + if (isSet($error)) { + throw new AJXP_Exception($error); + } + $messtmp.="$mess[34] ".SystemTextEncoding::toUTF8($filename)." $mess[39] "; + if ($dir=="") {$messtmp.="/";} else {$messtmp.=SystemTextEncoding::toUTF8($dir);} + $logMessage = $messtmp; + //$reloadContextNode = true; + //$pendingSelection = $dir."/".$filename; + AJXP_Logger::logAction("Create File", array("file"=>$this->addSlugToPath($dir)."/".$filename)); + $newNode = new AJXP_Node($this->urlBase.$dir."/".$filename); + if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); + array_push($nodesDiffs["ADD"], $newNode); + + break; + + //------------------------------------ + // CHANGE FILE PERMISSION + //------------------------------------ + case "chmod"; + + $messtmp=""; + $files = $selection->getFiles(); + $changedFiles = array(); + $chmod_value = $httpVars["chmod_value"]; + $recursive = $httpVars["recursive"]; + $recur_apply_to = $httpVars["recur_apply_to"]; + foreach ($files as $fileName) { + $error = $this->chmod($fileName, $chmod_value, ($recursive=="on"), ($recursive=="on"?$recur_apply_to:"both"), $changedFiles); + } + if (isSet($error)) { + throw new AJXP_Exception($error); + } + //$messtmp.="$mess[34] ".SystemTextEncoding::toUTF8($filename)." $mess[39] "; + $logMessage="Successfully changed permission to ".$chmod_value." for ".count($changedFiles)." files or folders"; + AJXP_Logger::logAction("Chmod", array("dir"=>$this->addSlugToPath($dir), "filesCount"=>count($changedFiles))); + if(!isSet($nodesDiffs)) $nodesDiffs = $this->getNodesDiffArray(); + $nodesDiffs["UPDATE"] = array_merge($nodesDiffs["UPDATE"], $selection->buildNodes($this)); + + break; + + //------------------------------------ + // UPLOAD + //------------------------------------ + case "upload": + + AJXP_Logger::debug("Upload Files Data", $fileVars); + $destination=$this->urlBase.AJXP_Utils::decodeSecureMagic($dir); + AJXP_Logger::debug("Upload inside", array("destination"=>$this->addSlugToPath($destination))); + if (!$this->isWriteable($destination)) { + $errorCode = 412; + $errorMessage = "$mess[38] ".SystemTextEncoding::toUTF8($dir)." $mess[99]."; + AJXP_Logger::debug("Upload error 412", array("destination"=>$this->addSlugToPath($destination))); + return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $errorMessage)); + } + foreach ($fileVars as $boxName => $boxData) { + if(substr($boxName, 0, 9) != "userfile_") continue; + $err = AJXP_Utils::parseFileDataErrors($boxData); + if ($err != null) { + $errorCode = $err[0]; + $errorMessage = $err[1]; + break; + } + $userfile_name = $boxData["name"]; + try { + $this->filterUserSelectionToHidden(array($userfile_name)); + } catch (Exception $e) { + return array("ERROR" => array("CODE" => 411, "MESSAGE" => "Forbidden")); + } + $userfile_name=AJXP_Utils::sanitize(SystemTextEncoding::fromPostedFileName($userfile_name), AJXP_SANITIZE_HTML_STRICT); + if (isSet($httpVars["urlencoded_filename"])) { + $userfile_name = AJXP_Utils::sanitize(SystemTextEncoding::fromUTF8(urldecode($httpVars["urlencoded_filename"])), AJXP_SANITIZE_HTML_STRICT); + } + AJXP_Logger::debug("User filename ".$userfile_name); + $userfile_name = substr($userfile_name, 0, ConfService::getCoreConf("NODENAME_MAX_LENGTH")); + if (isSet($httpVars["auto_rename"])) { + $userfile_name = self::autoRenameForDest($destination, $userfile_name); + } + try { + if (file_exists($destination."/".$userfile_name)) { + AJXP_Controller::applyHook("node.before_change", array(new AJXP_Node($destination."/".$userfile_name), $boxData["size"])); + } else { + AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($destination."/".$userfile_name), $boxData["size"])); + } + AJXP_Controller::applyHook("node.before_change", array(new AJXP_Node($destination))); + } catch (Exception $e) { + $errorCode=507; + $errorMessage = $e->getMessage(); + break; + } + if (isSet($boxData["input_upload"])) { + try { + AJXP_Logger::debug("Begining reading INPUT stream"); + $input = fopen("php://input", "r"); + $output = fopen("$destination/".$userfile_name, "w"); + $sizeRead = 0; + while ($sizeRead < intval($boxData["size"])) { + $chunk = fread($input, 4096); + $sizeRead += strlen($chunk); + fwrite($output, $chunk, strlen($chunk)); + } + fclose($input); + fclose($output); + AJXP_Logger::debug("End reading INPUT stream"); + } catch (Exception $e) { + $errorCode=411; + $errorMessage = $e->getMessage(); + break; + } + } else { + $result = @move_uploaded_file($boxData["tmp_name"], "$destination/".$userfile_name); + if (!$result) { + $realPath = call_user_func(array($this->wrapperClassName, "getRealFSReference"),"$destination/".$userfile_name); + $result = move_uploaded_file($boxData["tmp_name"], $realPath); + } + if (!$result) { + $errorCode=411; + $errorMessage="$mess[33] ".$userfile_name; + break; + } + } + if (isSet($httpVars["appendto_urlencoded_part"])) { + $appendTo = AJXP_Utils::sanitize(SystemTextEncoding::fromUTF8(urldecode($httpVars["appendto_urlencoded_part"])), AJXP_SANITIZE_HTML_STRICT); + if (file_exists($destination ."/" . $appendTo)) { + AJXP_Logger::debug("Should copy stream from $userfile_name to $appendTo"); + $partO = fopen($destination."/".$userfile_name, "r"); + $appendF = fopen($destination ."/". $appendTo, "a+"); + while (!feof($partO)) { + $buf = fread($partO, 1024); + fwrite($appendF, $buf, strlen($buf)); + } + fclose($partO); + fclose($appendF); + AJXP_Logger::debug("Done, closing streams!"); + } + @unlink($destination."/".$userfile_name); + $userfile_name = $appendTo; + } + + $this->changeMode($destination."/".$userfile_name); + $createdNode = new AJXP_Node($destination."/".$userfile_name); + //AJXP_Controller::applyHook("node.change", array(null, $createdNode, false)); + $logMessage.="$mess[34] ".SystemTextEncoding::toUTF8($userfile_name)." $mess[35] $dir"; + AJXP_Logger::logAction("Upload File", array("file"=>$this->addSlugToPath(SystemTextEncoding::fromUTF8($dir))."/".$userfile_name)); + } + + if (isSet($errorMessage)) { + AJXP_Logger::debug("Return error $errorCode $errorMessage"); + return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $errorMessage)); + } else { + AJXP_Logger::debug("Return success"); + return array("SUCCESS" => true, "CREATED_NODE" => $createdNode); + } + return ; + + break; + + case "lsync" : + + if (!ConfService::currentContextIsCommandLine()) { + die("This command must be accessed via CLI only."); + } + $fromNode = null; + $toNode = null; + $copyOrMove = false; + if (isSet($httpVars["from"])) { + $fromNode = new AJXP_Node($this->urlBase.AJXP_Utils::decodeSecureMagic($httpVars["from"])); + } + if (isSet($httpVars["to"])) { + $toNode = new AJXP_Node($this->urlBase.AJXP_Utils::decodeSecureMagic($httpVars["to"])); + } + if (isSet($httpVars["copy"]) && $httpVars["copy"] == "true") { + $copyOrMove = true; + } + AJXP_Controller::applyHook("node.change", array($fromNode, $toNode, $copyOrMove)); + + break; + + //------------------------------------ + // XML LISTING + //------------------------------------ + case "ls": + + if(!isSet($dir) || $dir == "/") $dir = ""; + $lsOptions = $this->parseLsOptions((isSet($httpVars["options"])?$httpVars["options"]:"a")); + + $startTime = microtime(); + if (isSet($httpVars["file"])) { + $uniqueFile = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + } + $dir = AJXP_Utils::securePath(SystemTextEncoding::magicDequote($dir)); + $path = $this->urlBase.($dir!= ""?($dir[0]=="/"?"":"/").$dir:""); + $nonPatchedPath = $path; + if ($this->wrapperClassName == "fsAccessWrapper") { + $nonPatchedPath = fsAccessWrapper::unPatchPathForBaseDir($path); + } + $threshold = $this->repository->getOption("PAGINATION_THRESHOLD"); + if(!isSet($threshold) || intval($threshold) == 0) $threshold = 500; + $limitPerPage = $this->repository->getOption("PAGINATION_NUMBER"); + if(!isset($limitPerPage) || intval($limitPerPage) == 0) $limitPerPage = 200; + + $countFiles = $this->countFiles($path, !$lsOptions["f"]); + if ($countFiles > $threshold) { + if (isSet($uniqueFile)) { + $originalLimitPerPage = $limitPerPage; + $offset = $limitPerPage = 0; + } else { + $offset = 0; + $crtPage = 1; + if (isSet($page)) { + $offset = (intval($page)-1)*$limitPerPage; + $crtPage = $page; + } + $totalPages = floor($countFiles / $limitPerPage) + 1; + } + } else { + $offset = $limitPerPage = 0; + } + + $metaData = array(); + if (RecycleBinManager::recycleEnabled() && $dir == "") { + $metaData["repo_has_recycle"] = "true"; + } + $parentAjxpNode = new AJXP_Node($nonPatchedPath, $metaData); + $parentAjxpNode->loadNodeInfo(false, true, ($lsOptions["l"]?"all":"minimal")); + AJXP_Controller::applyHook("node.read", array(&$parentAjxpNode)); + if (AJXP_XMLWriter::$headerSent == "tree") { + AJXP_XMLWriter::renderAjxpNode($parentAjxpNode, false); + } else { + AJXP_XMLWriter::renderAjxpHeaderNode($parentAjxpNode); + } + if (isSet($totalPages) && isSet($crtPage)) { + AJXP_XMLWriter::renderPaginationData( + $countFiles, + $crtPage, + $totalPages, + $this->countFiles($path, TRUE) + ); + if (!$lsOptions["f"]) { + AJXP_XMLWriter::close(); + exit(1); + } + } + + $cursor = 0; + $handle = opendir($path); + if (!$handle) { + throw new AJXP_Exception("Cannot open dir ".$nonPatchedPath); + } + closedir($handle); + $fullList = array("d" => array(), "z" => array(), "f" => array()); + $nodes = scandir($path); + if (!empty($this->driverConf["SCANDIR_RESULT_SORTFONC"])) { + usort($nodes, $this->driverConf["SCANDIR_RESULT_SORTFONC"]); + } + //while (strlen($nodeName = readdir($handle)) > 0) { + foreach ($nodes as $nodeName) { + if($nodeName == "." || $nodeName == "..") continue; + if (isSet($uniqueFile) && $nodeName != $uniqueFile) { + $cursor ++; + continue; + } + if ($offset > 0 && $cursor < $offset) { + $cursor ++; + continue; + } + $isLeaf = ""; + if (!$this->filterNodeName($path, $nodeName, $isLeaf, $lsOptions)) { + continue; + } + if (RecycleBinManager::recycleEnabled() && $dir == "" && "/".$nodeName == RecycleBinManager::getRecyclePath()) { + continue; + } + + if ($limitPerPage > 0 && ($cursor - $offset) >= $limitPerPage) { + break; + } + + $currentFile = $nonPatchedPath."/".$nodeName; + $meta = array(); + if($isLeaf != "") $meta = array("is_file" => ($isLeaf?"1":"0")); + $node = new AJXP_Node($currentFile, $meta); + $node->setLabel($nodeName); + $node->loadNodeInfo(false, false, ($lsOptions["l"]?"all":"minimal")); + if (!empty($node->metaData["nodeName"]) && $node->metaData["nodeName"] != $nodeName) { + $node->setUrl($nonPatchedPath."/".$node->metaData["nodeName"]); + } + if (!empty($node->metaData["hidden"]) && $node->metaData["hidden"] === true) { + continue; + } + if (!empty($node->metaData["mimestring_id"]) && array_key_exists($node->metaData["mimestring_id"], $mess)) { + $node->mergeMetadata(array("mimestring" => $mess[$node->metaData["mimestring_id"]])); + } + if (isSet($originalLimitPerPage) && $cursor > $originalLimitPerPage) { + $node->mergeMetadata(array("page_position" => floor($cursor / $originalLimitPerPage) +1)); + } + + $nodeType = "d"; + if ($node->isLeaf()) { + if (AJXP_Utils::isBrowsableArchive($nodeName)) { + if ($lsOptions["f"] && $lsOptions["z"]) { + $nodeType = "f"; + } else { + $nodeType = "z"; + } + } else $nodeType = "f"; + } + + $fullList[$nodeType][$nodeName] = $node; + $cursor ++; + if (isSet($uniqueFile) && $nodeName != $uniqueFile) { + break; + } + } + if (isSet($httpVars["recursive"]) && $httpVars["recursive"] == "true") { + foreach ($fullList["d"] as $nodeDir) { + $this->switchAction("ls", array( + "dir" => SystemTextEncoding::toUTF8($nodeDir->getPath()), + "options"=> $httpVars["options"], + "recursive" => "true" + ), array()); + } + } else { + array_map(array("AJXP_XMLWriter", "renderAjxpNode"), $fullList["d"]); + } + array_map(array("AJXP_XMLWriter", "renderAjxpNode"), $fullList["z"]); + array_map(array("AJXP_XMLWriter", "renderAjxpNode"), $fullList["f"]); + + // ADD RECYCLE BIN TO THE LIST + if ($dir == "" && !$uniqueFile && RecycleBinManager::recycleEnabled() && $this->getFilteredOption("HIDE_RECYCLE", $this->repository->getId()) !== true) { + $recycleBinOption = RecycleBinManager::getRelativeRecycle(); + if (file_exists($this->urlBase.$recycleBinOption)) { + $recycleNode = new AJXP_Node($this->urlBase.$recycleBinOption); + $recycleNode->loadNodeInfo(); + AJXP_XMLWriter::renderAjxpNode($recycleNode); + } + } + + AJXP_Logger::debug("LS Time : ".intval((microtime()-$startTime)*1000)."ms"); + + AJXP_XMLWriter::close(); + return ; + + break; + } + + + $xmlBuffer = ""; + if (isset($logMessage) || isset($errorMessage)) { + $xmlBuffer .= AJXP_XMLWriter::sendMessage((isSet($logMessage)?$logMessage:null), (isSet($errorMessage)?$errorMessage:null), false); + } + if ($reloadContextNode) { + if(!isSet($pendingSelection)) $pendingSelection = ""; + $xmlBuffer .= AJXP_XMLWriter::reloadDataNode("", $pendingSelection, false); + } + if (isSet($reloadDataNode)) { + $xmlBuffer .= AJXP_XMLWriter::reloadDataNode($reloadDataNode, "", false); + } + if (isSet($nodesDiffs)) { + $xmlBuffer .= AJXP_XMLWriter::writeNodesDiff($nodesDiffs, false); + } + + return $xmlBuffer; + } + + public function parseLsOptions($optionString) + { + // LS OPTIONS : dz , a, d, z, all of these with or without l + // d : directories + // z : archives + // f : files + // => a : all, alias to dzf + // l : list metadata + $allowed = array("a", "d", "z", "f", "l"); + $lsOptions = array(); + foreach ($allowed as $key) { + if (strchr($optionString, $key)!==false) { + $lsOptions[$key] = true; + } else { + $lsOptions[$key] = false; + } + } + if ($lsOptions["a"]) { + $lsOptions["d"] = $lsOptions["z"] = $lsOptions["f"] = true; + } + return $lsOptions; + } + + /** + * @param AJXP_Node $ajxpNode + * @param bool $parentNode + * @param bool $details + * @return void + */ + public function loadNodeInfo(&$ajxpNode, $parentNode = false, $details = false) + { + $nodeName = basename($ajxpNode->getPath()); + $metaData = $ajxpNode->metadata; + if (!isSet($metaData["is_file"])) { + $isLeaf = is_file($ajxpNode->getUrl()) || AJXP_Utils::isBrowsableArchive($nodeName); + $metaData["is_file"] = ($isLeaf?"1":"0"); + } else { + $isLeaf = $metaData["is_file"] == "1" ? true : false; + } + $metaData["filename"] = $ajxpNode->getPath(); + + if (RecycleBinManager::recycleEnabled() && $ajxpNode->getPath() == RecycleBinManager::getRelativeRecycle()) { + $mess = ConfService::getMessages(); + $recycleIcon = ($this->countFiles($ajxpNode->getUrl(), false, true)>0?"trashcan_full.png":"trashcan.png"); + $metaData["icon"] = $recycleIcon; + $metaData["mimestring"] = $mess[122]; + $ajxpNode->setLabel($mess[122]); + $metaData["ajxp_mime"] = "ajxp_recycle"; + } else { + $mimeData = AJXP_Utils::mimeData($ajxpNode->getUrl(), !$isLeaf); + $metaData["mimestring_id"] = $mimeData[0]; //AJXP_Utils::mimetype($ajxpNode->getUrl(), "type", !$isLeaf); + $metaData["icon"] = $mimeData[1]; //AJXP_Utils::mimetype($nodeName, "image", !$isLeaf); + if ($metaData["icon"] == "folder.png") { + $metaData["openicon"] = "folder_open.png"; + } + if (!$isLeaf) { + $metaData["ajxp_mime"] = "ajxp_folder"; + } + } + //if ($lsOptions["l"]) { + + $metaData["file_group"] = @filegroup($ajxpNode->getUrl()) || "unknown"; + $metaData["file_owner"] = @fileowner($ajxpNode->getUrl()) || "unknown"; + $crtPath = $ajxpNode->getPath(); + $vRoots = $this->repository->listVirtualRoots(); + if (!empty($crtPath)) { + if (!@$this->isWriteable($ajxpNode->getUrl())) { + $metaData["ajxp_readonly"] = "true"; + } + if (isSet($vRoots[ltrim($crtPath, "/")])) { + $metaData["ajxp_readonly"] = $vRoots[ltrim($crtPath, "/")]["right"] == "r" ? "true" : "false"; + } + } else { + if (count($vRoots)) { + $metaData["ajxp_readonly"] = "true"; + } + } + $fPerms = @fileperms($ajxpNode->getUrl()); + if ($fPerms !== false) { + $fPerms = substr(decoct( $fPerms ), ($isLeaf?2:1)); + } else { + $fPerms = '0000'; + } + $metaData["file_perms"] = $fPerms; + $datemodif = $this->date_modif($ajxpNode->getUrl()); + $metaData["ajxp_modiftime"] = ($datemodif ? $datemodif : "0"); + $metaData["bytesize"] = 0; + if ($isLeaf) { + $metaData["bytesize"] = $this->filesystemFileSize($ajxpNode->getUrl()); + } + $metaData["filesize"] = AJXP_Utils::roundSize($metaData["bytesize"]); + if (AJXP_Utils::isBrowsableArchive($nodeName)) { + $metaData["ajxp_mime"] = "ajxp_browsable_archive"; + } + + if ($details == "minimal") { + $miniMeta = array( + "is_file" => $metaData["is_file"], + "filename" => $metaData["filename"], + "bytesize" => $metaData["bytesize"], + "ajxp_modiftime" => $metaData["ajxp_modiftime"], + ); + $ajxpNode->mergeMetadata($miniMeta); + } else { + $ajxpNode->mergeMetadata($metaData); + } + + } + + /** + * Test if userSelection is containing a hidden file, which should not be the case! + * @param UserSelection $files + */ + public function filterUserSelectionToHidden($files) + { + $showHiddenFiles = $this->getFilteredOption("SHOW_HIDDEN_FILES", $this->repository->getId()); + foreach ($files as $file) { + $file = basename($file); + if (AJXP_Utils::isHidden($file) && !$showHiddenFiles) { + throw new Exception("Forbidden"); + } + if ($this->filterFile($file) || $this->filterFolder($file)) { + throw new Exception("Forbidden"); + } + } + } + + public function filterNodeName($nodePath, $nodeName, &$isLeaf, $lsOptions) + { + $showHiddenFiles = $this->getFilteredOption("SHOW_HIDDEN_FILES", $this->repository->getId()); + $isLeaf = (is_file($nodePath."/".$nodeName) || AJXP_Utils::isBrowsableArchive($nodeName)); + if (AJXP_Utils::isHidden($nodeName) && !$showHiddenFiles) { + return false; + } + $nodeType = "d"; + if ($isLeaf) { + if(AJXP_Utils::isBrowsableArchive($nodeName)) $nodeType = "z"; + else $nodeType = "f"; + } + if(!$lsOptions[$nodeType]) return false; + if ($nodeType == "d") { + if(RecycleBinManager::recycleEnabled() + && $nodePath."/".$nodeName == RecycleBinManager::getRecyclePath()){ + return false; + } + return !$this->filterFolder($nodeName); + } else { + if($nodeName == "." || $nodeName == "..") return false; + if(RecycleBinManager::recycleEnabled() + && $nodePath == RecycleBinManager::getRecyclePath() + && $nodeName == RecycleBinManager::getCacheFileName()){ + return false; + } + return !$this->filterFile($nodeName); + } + } + + public function filterFile($fileName) + { + $pathParts = pathinfo($fileName); + $hiddenFileNames = $this->getFilteredOption("HIDE_FILENAMES", $this->repository->getId()); + $hiddenExtensions = $this->getFilteredOption("HIDE_EXTENSIONS", $this->repository->getId()); + if (!empty($hiddenFileNames)) { + if (!is_array($hiddenFileNames)) { + $hiddenFileNames = explode(",",$hiddenFileNames); + } + foreach ($hiddenFileNames as $search) { + if(strcasecmp($search, $pathParts["basename"]) == 0) return true; + } + } + if (!empty($hiddenExtensions)) { + if (!is_array($hiddenExtensions)) { + $hiddenExtensions = explode(",",$hiddenExtensions); + } + foreach ($hiddenExtensions as $search) { + if(strcasecmp($search, $pathParts["extension"]) == 0) return true; + } + } + return false; + } + + public function filterFolder($folderName, $compare = "equals") + { + $hiddenFolders = $this->getFilteredOption("HIDE_FOLDERS", $this->repository->getId()); + if (!empty($hiddenFolders)) { + if (!is_array($hiddenFolders)) { + $hiddenFolders = explode(",",$hiddenFolders); + } + foreach ($hiddenFolders as $search) { + if($compare == "equals" && strcasecmp($search, $folderName) == 0) return true; + if($compare == "contains" && strpos($folderName, "/".$search) !== false) return true; + } + } + return false; + } + + public function readFile($filePathOrData, $headerType="plain", $localName="", $data=false, $gzip=null, $realfileSystem=false, $byteOffset=-1, $byteLength=-1) + { + if ($gzip === null) { + $gzip = ConfService::getCoreConf("GZIP_COMPRESSION"); + } + if (!$realfileSystem && $this->wrapperClassName == "fsAccessWrapper") { + $originalFilePath = $filePathOrData; + $filePathOrData = fsAccessWrapper::patchPathForBaseDir($filePathOrData); + } + session_write_close(); + + restore_error_handler(); + restore_exception_handler(); + + set_exception_handler('download_exception_handler'); + set_error_handler('download_exception_handler'); + // required for IE, otherwise Content-disposition is ignored + if (ini_get('zlib.output_compression')) { + AJXP_Utils::safeIniSet('zlib.output_compression', 'Off'); + } + + $isFile = !$data && !$gzip; + if ($byteLength == -1) { + if ($data) { + $size = strlen($filePathOrData); + } else if ($realfileSystem) { + $size = sprintf("%u", filesize($filePathOrData)); + } else { + $size = $this->filesystemFileSize($filePathOrData); + } + } else { + $size = $byteLength; + } + if ($gzip && ($size > ConfService::getCoreConf("GZIP_LIMIT") || !function_exists("gzencode") || @strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') === FALSE)) { + $gzip = false; // disable gzip + } + + $localName = ($localName=="" ? basename((isSet($originalFilePath)?$originalFilePath:$filePathOrData)) : $localName); + if ($headerType == "plain") { + header("Content-type:text/plain"); + } else if ($headerType == "image") { + header("Content-Type: ".AJXP_Utils::getImageMimeType(basename($filePathOrData))."; name=\"".$localName."\""); + header("Content-Length: ".$size); + header('Cache-Control: public'); + } else { + /* + if (preg_match('/ MSIE /',$_SERVER['HTTP_USER_AGENT']) || preg_match('/ WebKit /',$_SERVER['HTTP_USER_AGENT'])) { + $localName = str_replace("+", " ", urlencode(SystemTextEncoding::toUTF8($localName))); + } + */ + if ($isFile) { + header("Accept-Ranges: 0-$size"); + AJXP_Logger::debug("Sending accept range 0-$size"); + } + + // Check if we have a range header (we are resuming a transfer) + if ( isset($_SERVER['HTTP_RANGE']) && $isFile && $size != 0 ) { + if ($headerType == "stream_content") { + if (extension_loaded('fileinfo') && $this->wrapperClassName == "fsAccessWrapper") { + $fInfo = new fInfo( FILEINFO_MIME ); + $realfile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $filePathOrData); + $mimeType = $fInfo->file( $realfile); + $splitChar = explode(";", $mimeType); + $mimeType = trim($splitChar[0]); + AJXP_Logger::debug("Detected mime $mimeType for $realfile"); + } else { + $mimeType = AJXP_Utils::getStreamingMimeType(basename($filePathOrData)); + } + header('Content-type: '.$mimeType); + } + // multiple ranges, which can become pretty complex, so ignore it for now + $ranges = explode('=', $_SERVER['HTTP_RANGE']); + $offsets = explode('-', $ranges[1]); + $offset = floatval($offsets[0]); + + $length = floatval($offsets[1]) - $offset; + if (!$length) $length = $size - $offset; + if ($length + $offset > $size || $length < 0) $length = $size - $offset; + AJXP_Logger::debug('Content-Range: bytes ' . $offset . '-' . $length . '/' . $size); + header('HTTP/1.1 206 Partial Content'); + header('Content-Range: bytes ' . $offset . '-' . ($offset + $length) . '/' . $size); + + header("Content-Length: ". $length); + $file = fopen($filePathOrData, 'rb'); + fseek($file, 0); + $relOffset = $offset; + while ($relOffset > 2.0E9) { + // seek to the requested offset, this is 0 if it's not a partial content request + fseek($file, 2000000000, SEEK_CUR); + $relOffset -= 2000000000; + // This works because we never overcome the PHP 32 bit limit + } + fseek($file, $relOffset, SEEK_CUR); + + while(ob_get_level()) ob_end_flush(); + $readSize = 0.0; + $bufferSize = 1024 * 8; + while (!feof($file) && $readSize < $length && connection_status() == 0) { + AJXP_Logger::debug("dl reading $readSize to $length", $_SERVER["HTTP_RANGE"]); + echo fread($file, $bufferSize); + $readSize += $bufferSize; + flush(); + } + + fclose($file); + return; + } else { + if ($gzip) { + $gzippedData = ($data?gzencode($filePathOrData,9):gzencode(file_get_contents($filePathOrData), 9)); + $size = strlen($gzippedData); + } + HTMLWriter::generateAttachmentsHeader($localName, $size, $isFile, $gzip); + if ($gzip) { + print $gzippedData; + return; + } + } + } + + if ($data) { + print($filePathOrData); + } else { + if ($this->getFilteredOption("USE_XSENDFILE", $this->repository->getId()) && $this->wrapperClassName == "fsAccessWrapper") { + if(!$realfileSystem) $filePathOrData = fsAccessWrapper::getRealFSReference($filePathOrData); + $filePathOrData = str_replace("\\", "/", $filePathOrData); + $server_name = $_SERVER["SERVER_SOFTWARE"]; + $regex = '/^(lighttpd\/1.4).([0-9]{2}$|[0-9]{3}$|[0-9]{4}$)+/'; + if(preg_match($regex, $server_name)) + $header_sendfile = "X-LIGHTTPD-send-file"; + else + $header_sendfile = "X-Sendfile"; + header($header_sendfile.": ".SystemTextEncoding::toUTF8($filePathOrData)); + header("Content-type: application/octet-stream"); + header('Content-Disposition: attachment; filename="' . basename($filePathOrData) . '"'); + return; + } + if ($this->getFilteredOption("USE_XACCELREDIRECT", $this->repository->getId()) && $this->wrapperClassName == "fsAccessWrapper" && array_key_exists("X-Accel-Mapping",$_SERVER)) { + if(!$realfileSystem) $filePathOrData = fsAccessWrapper::getRealFSReference($filePathOrData); + $filePathOrData = str_replace("\\", "/", $filePathOrData); + $filePathOrData = SystemTextEncoding::toUTF8($filePathOrData); + $mapping = explode('=',$_SERVER['X-Accel-Mapping']); + $replacecount = 0; + $accelfile = str_replace($mapping[0],$mapping[1],$filePathOrData,$replacecount); + if ($replacecount == 1) { + header("X-Accel-Redirect: $accelfile"); + header("Content-type: application/octet-stream"); + header('Content-Disposition: attachment; filename="' . basename($accelfile) . '"'); + return; + } else { + AJXP_Logger::logAction("error","Problem with X-Accel-Mapping for file $filePathOrData"); + } + } + $stream = fopen("php://output", "a"); + if ($realfileSystem) { + AJXP_Logger::debug("realFS!", array("file"=>$filePathOrData)); + $fp = fopen($filePathOrData, "rb"); + if ($byteOffset != -1) { + fseek($fp, $byteOffset); + } + $sentSize = 0; + $readChunk = 4096; + while (!feof($fp)) { + if ( $byteLength != -1 && ($sentSize + $readChunk) >= $byteLength) { + // compute last chunk and break after + $readChunk = $byteLength - $sentSize; + $break = true; + } + $data = fread($fp, $readChunk); + $dataSize = strlen($data); + fwrite($stream, $data, $dataSize); + $sentSize += $dataSize; + if (isSet($break)) { + break; + } + } + fclose($fp); + } else { + call_user_func(array($this->wrapperClassName, "copyFileInStream"), $filePathOrData, $stream); + } + fflush($stream); + fclose($stream); + } + } + + public function countFiles($dirName, $foldersOnly = false, $nonEmptyCheckOnly = false) + { + $handle=@opendir($dirName); + if ($handle === false) { + throw new Exception("Error while trying to open directory ".$dirName); + } + if ($foldersOnly && !call_user_func(array($this->wrapperClassName, "isRemote"))) { + closedir($handle); + $path = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $dirName); + $dirs = glob($path."/*", GLOB_ONLYDIR|GLOB_NOSORT); + if($dirs === false) return 0; + return count($dirs); + } + $count = 0; + $showHiddenFiles = $this->getFilteredOption("SHOW_HIDDEN_FILES", $this->repository->getId()); + while (strlen($file = readdir($handle)) > 0) { + if($file != "." && $file !=".." + && !(AJXP_Utils::isHidden($file) && !$showHiddenFiles)){ + if($foldersOnly && is_file($dirName."/".$file)) continue; + $count++; + if($nonEmptyCheckOnly) break; + } + } + closedir($handle); + return $count; + } + + public function date_modif($file) + { + $tmp = @filemtime($file) or 0; + return $tmp;// date("d,m L Y H:i:s",$tmp); + } + + public function changeMode($filePath) + { + $chmodValue = $this->repository->getOption("CHMOD_VALUE"); + if (isSet($chmodValue) && $chmodValue != "") { + $chmodValue = octdec(ltrim($chmodValue, "0")); + call_user_func(array($this->wrapperClassName, "changeMode"), $filePath, $chmodValue); + } + } + + public function filesystemFileSize($filePath) + { + $bytesize = "-"; + $bytesize = @filesize($filePath); + if (method_exists($this->wrapperClassName, "getLastRealSize")) { + $last = call_user_func(array($this->wrapperClassName, "getLastRealSize")); + if ($last !== false) { + $bytesize = $last; + } + } + if ($bytesize < 0) { + $bytesize = sprintf("%u", $bytesize); + } + + return $bytesize; + } + + /** + * Extract an archive directly inside the dest directory. + * + * @param string $destDir + * @param UserSelection $selection + * @param array $error + * @param array $success + */ + public function extractArchive($destDir, $selection, &$error, &$success) + { + require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); + $zipPath = $selection->getZipPath(true); + $zipLocalPath = $selection->getZipLocalPath(true); + if(strlen($zipLocalPath)>1 && $zipLocalPath[0] == "/") $zipLocalPath = substr($zipLocalPath, 1)."/"; + $files = $selection->getFiles(); + + $realZipFile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $this->urlBase.$zipPath); + $archive = new PclZip($realZipFile); + $content = $archive->listContent(); + foreach ($files as $key => $item) {// Remove path + $item = substr($item, strlen($zipPath)); + if($item[0] == "/") $item = substr($item, 1); + foreach ($content as $zipItem) { + if ($zipItem["stored_filename"] == $item || $zipItem["stored_filename"] == $item."/") { + $files[$key] = $zipItem["stored_filename"]; + break; + } else { + unset($files[$key]); + } + } + } + AJXP_Logger::debug("Archive", $this->addSlugToPath($files)); + $realDestination = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $this->urlBase.$destDir); + AJXP_Logger::debug("Extract", array($realDestination, $realZipFile, $this->addSlugToPath($files), $zipLocalPath)); + $result = $archive->extract(PCLZIP_OPT_BY_NAME, $files, + PCLZIP_OPT_PATH, $realDestination, + PCLZIP_OPT_REMOVE_PATH, $zipLocalPath); + if ($result <= 0) { + $error[] = $archive->errorInfo(true); + } else { + $mess = ConfService::getMessages(); + $success[] = sprintf($mess[368], basename($zipPath), $destDir); + } + } + + public function copyOrMove($destDir, $selectedFiles, &$error, &$success, $move = false) + { + AJXP_Logger::debug("CopyMove", array("dest"=>$this->addSlugToPath($destDir), "selection" => $this->addSlugToPath($selectedFiles))); + $mess = ConfService::getMessages(); + if (!$this->isWriteable($this->urlBase.$destDir)) { + $error[] = $mess[38]." ".$destDir." ".$mess[99]; + return ; + } + + foreach ($selectedFiles as $selectedFile) { + if ($move && !$this->isWriteable(dirname($this->urlBase.$selectedFile))) { + $error[] = "\n".$mess[38]." ".dirname($selectedFile)." ".$mess[99]; + continue; + } + $this->copyOrMoveFile($destDir, $selectedFile, $error, $success, $move); + } + } + + public function renameAction($actionName, $httpVars) + { + $filePath = SystemTextEncoding::fromUTF8($httpVars["file"]); + $newFilename = SystemTextEncoding::fromUTF8($httpVars["filename_new"]); + return $this->rename($filePath, $newFilename); + } + + public function rename($filePath, $filename_new, $dest = null) + { + $nom_fic=basename($filePath); + $mess = ConfService::getMessages(); + $filename_new=AJXP_Utils::sanitize(SystemTextEncoding::magicDequote($filename_new), AJXP_SANITIZE_HTML_STRICT); + $filename_new = substr($filename_new, 0, ConfService::getCoreConf("NODENAME_MAX_LENGTH")); + $old=$this->urlBase."/$filePath"; + if (!$this->isWriteable($old)) { + throw new AJXP_Exception($mess[34]." ".$nom_fic." ".$mess[99]); + } + if($dest == null) $new=dirname($old)."/".$filename_new; + else $new = $this->urlBase.$dest; + if ($filename_new=="" && $dest == null) { + throw new AJXP_Exception("$mess[37]"); + } + if (file_exists($new)) { + throw new AJXP_Exception("$filename_new $mess[43]"); + } + if (!file_exists($old)) { + throw new AJXP_Exception($mess[100]." $nom_fic"); + } + $oldNode = new AJXP_Node($old); + AJXP_Controller::applyHook("node.before_path_change", array(&$oldNode)); + rename($old,$new); + AJXP_Controller::applyHook("node.change", array($oldNode, new AJXP_Node($new), false)); + } + + public static function autoRenameForDest($destination, $fileName) + { + if(!is_file($destination."/".$fileName)) return $fileName; + $i = 1; + $ext = ""; + $name = ""; + $split = explode(".", $fileName); + if (count($split) > 1) { + $ext = ".".$split[count($split)-1]; + array_pop($split); + $name = join(".", $split); + } else { + $name = $fileName; + } + while (is_file($destination."/".$name."-$i".$ext)) { + $i++; // increment i until finding a non existing file. + } + return $name."-$i".$ext; + } + + public function mkDir($crtDir, $newDirName, $ignoreExists = false) + { + $currentNodeDir = new AJXP_Node($this->urlBase.$crtDir); + AJXP_Controller::applyHook("node.before_change", array(&$currentNodeDir)); + + $mess = ConfService::getMessages(); + if ($newDirName=="") { + return "$mess[37]"; + } + if (file_exists($this->urlBase."$crtDir/$newDirName")) { + if($ignoreExists) return null; + return "$mess[40]"; + } + if (!$this->isWriteable($this->urlBase."$crtDir")) { + return $mess[38]." $crtDir ".$mess[99]; + } + + $dirMode = 0775; + $chmodValue = $this->repository->getOption("CHMOD_VALUE"); + if (isSet($chmodValue) && $chmodValue != "") { + $dirMode = octdec(ltrim($chmodValue, "0")); + if ($dirMode & 0400) $dirMode |= 0100; // User is allowed to read, allow to list the directory + if ($dirMode & 0040) $dirMode |= 0010; // Group is allowed to read, allow to list the directory + if ($dirMode & 0004) $dirMode |= 0001; // Other are allowed to read, allow to list the directory + } + $old = umask(0); + mkdir($this->urlBase."$crtDir/$newDirName", $dirMode); + umask($old); + $newNode = new AJXP_Node($this->urlBase.$crtDir."/".$newDirName); + AJXP_Controller::applyHook("node.change", array(null, $newNode, false)); + return null; + } + + public function createEmptyFile($crtDir, $newFileName, $content = "") + { + if (($content == "") && preg_match("/\.html$/",$newFileName)||preg_match("/\.htm$/",$newFileName)) { + $content = "\n\nNew Document - Created By AjaXplorer\n\n\n\n\n\n\n"; + AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($this->urlBase.$crtDir."/".$newFileName), strlen($content))); + } + AJXP_Controller::applyHook("node.before_change", array(new AJXP_Node($this->urlBase.$crtDir))); + $mess = ConfService::getMessages(); + if ($newFileName=="") { + return "$mess[37]"; + } + if (file_exists($this->urlBase."$crtDir/$newFileName")) { + return "$mess[71]"; + } + if (!$this->isWriteable($this->urlBase."$crtDir")) { + return "$mess[38] $crtDir $mess[99]"; + } + $fp=fopen($this->urlBase."$crtDir/$newFileName","w"); + if ($fp) { + if ($content != "") { + fputs($fp, $content); + } + $this->changeMode($this->urlBase."$crtDir/$newFileName"); + fclose($fp); + $newNode = new AJXP_Node($this->urlBase."$crtDir/$newFileName"); + AJXP_Controller::applyHook("node.change", array(null, $newNode, false)); + return null; + } else { + return "$mess[102] $crtDir/$newFileName (".$fp.")"; + } + } + + + public function delete($selectedFiles, &$logMessages) + { + $mess = ConfService::getMessages(); + foreach ($selectedFiles as $selectedFile) { + if ($selectedFile == "" || $selectedFile == DIRECTORY_SEPARATOR) { + return $mess[120]; + } + $fileToDelete=$this->urlBase.$selectedFile; + if (!file_exists($fileToDelete)) { + $logMessages[]=$mess[100]." ".SystemTextEncoding::toUTF8($selectedFile); + continue; + } + $this->deldir($fileToDelete); + if (is_dir($fileToDelete)) { + $logMessages[]="$mess[38] ".SystemTextEncoding::toUTF8($selectedFile)." $mess[44]."; + } else { + $logMessages[]="$mess[34] ".SystemTextEncoding::toUTF8($selectedFile)." $mess[44]."; + } + AJXP_Controller::applyHook("node.change", array(new AJXP_Node($fileToDelete))); + } + return null; + } + + + + public function copyOrMoveFile($destDir, $srcFile, &$error, &$success, $move = false) + { + $mess = ConfService::getMessages(); + $destFile = $this->urlBase.$destDir."/".basename($srcFile); + $realSrcFile = $this->urlBase.$srcFile; + + if (is_dir(dirname($realSrcFile)) && (strpos($destFile, rtrim($realSrcFile, "/") . "/") === 0)) { + $error[] = $mess[101]; + return; + } + + if (!file_exists($realSrcFile)) { + $error[] = $mess[100].$srcFile; + return ; + } + if (!$move) { + AJXP_Controller::applyHook("node.before_create", array(new AJXP_Node($destFile), filesize($realSrcFile))); + } + if (dirname($realSrcFile)==dirname($destFile)) { + if ($move) { + $error[] = $mess[101]; + return ; + } else { + $base = basename($srcFile); + $i = 1; + if (is_file($realSrcFile)) { + $dotPos = strrpos($base, "."); + if ($dotPos>-1) { + $radic = substr($base, 0, $dotPos); + $ext = substr($base, $dotPos); + } + } + // auto rename file + $i = 1; + $newName = $base; + while (file_exists($this->urlBase.$destDir."/".$newName)) { + $suffix = "-$i"; + if(isSet($radic)) $newName = $radic . $suffix . $ext; + else $newName = $base.$suffix; + $i++; + } + $destFile = $this->urlBase.$destDir."/".$newName; + } + } + if (!is_file($realSrcFile)) { + $errors = array(); + $succFiles = array(); + if ($move) { + AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($realSrcFile))); + if(file_exists($destFile)) $this->deldir($destFile); + $res = rename($realSrcFile, $destFile); + } else { + $dirRes = $this->dircopy($realSrcFile, $destFile, $errors, $succFiles); + } + if (count($errors) || (isSet($res) && $res!==true)) { + $error[] = $mess[114]; + return ; + } else { + AJXP_Controller::applyHook("node.change", array(new AJXP_Node($realSrcFile), new AJXP_Node($destFile), !$move)); + } + } else { + if ($move) { + AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($realSrcFile))); + if(file_exists($destFile)) unlink($destFile); + $res = rename($realSrcFile, $destFile); + AJXP_Controller::applyHook("node.change", array(new AJXP_Node($realSrcFile), new AJXP_Node($destFile), false)); + } else { + try { + if (call_user_func(array($this->wrapperClassName, "isRemote"))) { + $src = fopen($realSrcFile, "r"); + $dest = fopen($destFile, "w"); + if ($dest !== false) { + while (!feof($src)) { + stream_copy_to_stream($src, $dest, 4096); + } + fclose($dest); + } + fclose($src); + } else { + copy($realSrcFile, $destFile); + } + $this->changeMode($destFile); + AJXP_Controller::applyHook("node.change", array(new AJXP_Node($realSrcFile), new AJXP_Node($destFile), true)); + } catch (Exception $e) { + $error[] = $e->getMessage(); + return ; + } + } + } + + if ($move) { + // Now delete original + // $this->deldir($realSrcFile); // both file and dir + $messagePart = $mess[74]." ".SystemTextEncoding::toUTF8($destDir); + if (RecycleBinManager::recycleEnabled() && $destDir == RecycleBinManager::getRelativeRecycle()) { + RecycleBinManager::fileToRecycle($srcFile); + $messagePart = $mess[123]." ".$mess[122]; + } + if (isset($dirRes)) { + $success[] = $mess[117]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$messagePart." (".SystemTextEncoding::toUTF8($dirRes)." ".$mess[116].") "; + } else { + $success[] = $mess[34]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$messagePart; + } + } else { + if (RecycleBinManager::recycleEnabled() && $destDir == "/".$this->repository->getOption("RECYCLE_BIN")) { + RecycleBinManager::fileToRecycle($srcFile); + } + if (isSet($dirRes)) { + $success[] = $mess[117]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$mess[73]." ".SystemTextEncoding::toUTF8($destDir)." (".SystemTextEncoding::toUTF8($dirRes)." ".$mess[116].")"; + } else { + $success[] = $mess[34]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$mess[73]." ".SystemTextEncoding::toUTF8($destDir); + } + } + + } + + // A function to copy files from one directory to another one, including subdirectories and + // nonexisting or newer files. Function returns number of files copied. + // This function is PHP implementation of Windows xcopy A:\dir1\* B:\dir2 /D /E /F /H /R /Y + // Syntaxis: [$number =] dircopy($sourcedirectory, $destinationdirectory [, $verbose]); + // Example: $num = dircopy('A:\dir1', 'B:\dir2', 1); + + public function dircopy($srcdir, $dstdir, &$errors, &$success, $verbose = false, $convertSrcFile = true) + { + $num = 0; + //$verbose = true; + $recurse = array(); + if(!is_dir($dstdir)) mkdir($dstdir); + if ($curdir = opendir($srcdir)) { + while ($file = readdir($curdir)) { + if ($file != '.' && $file != '..') { + $srcfile = $srcdir . "/" . $file; + $dstfile = $dstdir . "/" . $file; + if (is_file($srcfile)) { + if(is_file($dstfile)) $ow = filemtime($srcfile) - filemtime($dstfile); else $ow = 1; + if ($ow > 0) { + try { + if($convertSrcFile) $tmpPath = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $srcfile); + else $tmpPath = $srcfile; + if($verbose) echo "Copying '$tmpPath' to '$dstfile'..."; + copy($tmpPath, $dstfile); + $success[] = $srcfile; + $num ++; + $this->changeMode($dstfile); + } catch (Exception $e) { + $errors[] = $srcfile; + } + } + } else { + $recurse[] = array("src" => $srcfile, "dest"=> $dstfile); + } + } + } + closedir($curdir); + foreach ($recurse as $rec) { + if($verbose) echo "Dircopy $srcfile"; + $num += $this->dircopy($rec["src"], $rec["dest"], $errors, $success, $verbose, $convertSrcFile); + } + } + return $num; + } + + public function simpleCopy($origFile, $destFile) + { + return copy($origFile, $destFile); + } + + public function isWriteable($dir, $type="dir") + { + if ( $this->getFilteredOption("USE_POSIX", $this->repository->getId()) == true && extension_loaded('posix')) { + $real = call_user_func(array( $this->wrapperClassName, "getRealFSReference"), $dir); + return posix_access($real, POSIX_W_OK); + } + return is_writable($dir); + } + + public function deldir($location) + { + if (is_dir($location)) { + AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($location))); + $all=opendir($location); + while ($file=readdir($all)) { + if (is_dir("$location/$file") && $file !=".." && $file!=".") { + $this->deldir("$location/$file"); + if (file_exists("$location/$file")) { + rmdir("$location/$file"); + } + unset($file); + } elseif (!is_dir("$location/$file")) { + if (file_exists("$location/$file")) { + unlink("$location/$file"); + } + unset($file); + } + } + closedir($all); + rmdir($location); + } else { + if (file_exists("$location")) { + AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($location))); + $test = @unlink("$location"); + if(!$test) throw new Exception("Cannot delete file ".$location); + } + } + if (basename(dirname($location)) == $this->repository->getOption("RECYCLE_BIN")) { + // DELETING FROM RECYCLE + RecycleBinManager::deleteFromRecycle($location); + } + } + + /** + * Change file permissions + * + * @param String $path + * @param String $chmodValue + * @param Boolean $recursive + * @param String $nodeType "both", "file", "dir" + */ + public function chmod($path, $chmodValue, $recursive=false, $nodeType="both", &$changedFiles) + { + $realValue = octdec(ltrim($chmodValue, "0")); + if (is_file($this->urlBase.$path)) { + if ($nodeType=="both" || $nodeType=="file") { + call_user_func(array($this->wrapperClassName, "changeMode"), $this->urlBase.$path, $realValue); + $changedFiles[] = $path; + } + } else { + if ($nodeType=="both" || $nodeType=="dir") { + call_user_func(array($this->wrapperClassName, "changeMode"), $this->urlBase.$path, $realValue); + $changedFiles[] = $path; + } + if ($recursive) { + $handler = opendir($this->urlBase.$path); + while ($child=readdir($handler)) { + if($child == "." || $child == "..") continue; + // do not pass realValue or it will be re-decoded. + $this->chmod($path."/".$child, $chmodValue, $recursive, $nodeType, $changedFiles); + } + closedir($handler); + } + } + } + + /** + * @param String $from + * @param String $to + * @param Boolean $copy + */ + public function nodeChanged(&$from, &$to, $copy = false) + { + $fromNode = $toNode = null; + if($from != null) $fromNode = new AJXP_Node($this->urlBase.$from); + if($to != null) $toNode = new AJXP_Node($this->urlBase.$to); + AJXP_Controller::applyHook("node.change", array($fromNode, $toNode, $copy)); + } + + /** + * @param String $node + */ + public function nodeWillChange($node, $newSize = null) + { + if ($newSize != null) { + AJXP_Controller::applyHook("node.before_change", array(new AJXP_Node($this->urlBase.$node), $newSize)); + } else { + AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($this->urlBase.$node))); + } + } + + + /** + * @var fsAccessDriver + */ + public static $filteringDriverInstance; + /** + * @return zipfile + */ + public function makeZip ($src, $dest, $basedir) + { + @set_time_limit(0); + require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); + $filePaths = array(); + foreach ($src as $item) { + $realFile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $this->urlBase."/".$item); + $realFile = AJXP_Utils::securePath($realFile); + $basedir = trim(dirname($realFile)); + if (basename($item) == "") { + $filePaths[] = array(PCLZIP_ATT_FILE_NAME => $realFile); + } else { + $filePaths[] = array(PCLZIP_ATT_FILE_NAME => $realFile, + PCLZIP_ATT_FILE_NEW_SHORT_NAME => basename($item)); + } + } + AJXP_Logger::debug("Pathes", $filePaths); + AJXP_Logger::debug("Basedir", array($basedir)); + self::$filteringDriverInstance = $this; + $archive = new PclZip($dest); + $vList = $archive->create($filePaths, PCLZIP_OPT_REMOVE_PATH, $basedir, PCLZIP_OPT_NO_COMPRESSION, PCLZIP_OPT_ADD_TEMP_FILE_ON, PCLZIP_CB_PRE_ADD, 'zipPreAddCallback'); + if (!$vList) { + throw new Exception("Zip creation error : ($dest) ".$archive->errorInfo(true)); + } + self::$filteringDriverInstance = null; + return $vList; + } + + + public function recursivePurge($dirName, $purgeTime) + { + $handle=opendir($dirName); + $count = 0; + while (strlen($file = readdir($handle)) > 0) { + if ($file == "" || $file == ".." || AJXP_Utils::isHidden($file) ) { + continue; + } + if (is_file($dirName."/".$file)) { + $time = filemtime($dirName."/".$file); + $docAge = time() - $time; + if ($docAge > $purgeTime) { + $node = new AJXP_Node($dirName."/".$file); + AJXP_Controller::applyHook("node.before_path_change", array($node)); + unlink($dirName."/".$file); + AJXP_Controller::applyHook("node.change", array($node)); + AJXP_Logger::logAction("Purge", array("file" => $dirName."/".$file)); + print(" - Purging document : ".$dirName."/".$file."\n"); + } + } else { + $this->recursivePurge($dirName."/".$file, $purgeTime); + } + } + closedir($handle); + + + } + + + /** The publiclet URL making */ + public function makePublicletOptions($filePath, $password, $expire, $downloadlimit, $repository) + { + $data = array( + "DRIVER"=>$repository->getAccessType(), + "OPTIONS"=>NULL, + "FILE_PATH"=>$filePath, + "ACTION"=>"download", + "EXPIRE_TIME"=>$expire ? (time() + $expire * 86400) : 0, + "DOWNLOAD_LIMIT"=>$downloadlimit ? $downloadlimit : 0, + "PASSWORD"=>$password + ); + return $data; + } + + public function makeSharedRepositoryOptions($httpVars, $repository) + { + $newOptions = array( + "PATH" => $repository->getOption("PATH").AJXP_Utils::decodeSecureMagic($httpVars["file"]), + "CREATE" => false, + "RECYCLE_BIN" => "", + "DEFAULT_RIGHTS" => ""); + if ($repository->getOption("USE_SESSION_CREDENTIALS")===true) { + $newOptions["ENCODED_CREDENTIALS"] = AJXP_Safe::getEncodedCredentialString(); + } + return $newOptions; + } + + +} + +function zipPreAddCallback($value, $header) +{ + if(fsAccessDriver::$filteringDriverInstance == null) return true; + $search = $header["filename"]; + return !(fsAccessDriver::$filteringDriverInstance->filterFile($search) + || fsAccessDriver::$filteringDriverInstance->filterFolder($search, "contains")); +} \ No newline at end of file diff --git a/core/src/plugins/access.fs/class.fsAccessWrapper.php b/core/src/plugins/access.fs/class.fsAccessWrapper.php index ec37858319..2a928cb72d 100644 --- a/core/src/plugins/access.fs/class.fsAccessWrapper.php +++ b/core/src/plugins/access.fs/class.fsAccessWrapper.php @@ -26,23 +26,23 @@ * @package AjaXplorer_Plugins * @subpackage Access */ -class fsAccessWrapper implements AjxpWrapper { - - /** - * FileHandle resource - * - * @var resource - */ +class fsAccessWrapper implements AjxpWrapper +{ + /** + * FileHandle resource + * + * @var resource + */ protected $fp; - /** - * DirHandle resource - * - * @var resource - */ - protected $dH; - /** - * If dH is not used but an array containing the listing + * DirHandle resource + * + * @var resource + */ + protected $dH; + + /** + * If dH is not used but an array containing the listing * instead. dH == -1 in that case. * * @var array() @@ -51,99 +51,100 @@ class fsAccessWrapper implements AjxpWrapper { protected static $currentListingKeys; protected static $currentListingIndex; protected static $currentFileKey; - protected static $crtZip; - protected $realPath; + protected static $crtZip; + protected $realPath; protected static $lastRealSize; /** - * Initialize the stream from the given path. + * Initialize the stream from the given path. * * @param string $path * @return mixed Real path or -1 if currentListing contains the listing : original path converted to real path */ - protected static function initPath($path, $streamType, $storeOpenContext = false, $skipZip = false){ + protected static function initPath($path, $streamType, $storeOpenContext = false, $skipZip = false) + { $path = self::unPatchPathForBaseDir($path); - $url = parse_url($path); - $repoId = $url["host"]; + $url = parse_url($path); + $repoId = $url["host"]; $test = trim($url["path"], "/"); $atRoot = empty($test); - if(isSet($url["fragment"]) && strlen($url["fragment"]) > 0){ - $url["path"] .= "#".$url["fragment"]; - } - $repoObject = ConfService::getRepositoryById($repoId); - if(!isSet($repoObject)) throw new Exception("Cannot find repository with id ".$repoId); - $split = UserSelection::detectZip($url["path"]); - $insideZip = false; - if($split && $streamType == "file" && $split[1] != "/") $insideZip = true; - if($split && $streamType == "dir") $insideZip = true; - if($skipZip) $insideZip = false; - //var_dump($path); - //var_dump($skipZip); - // Inside a zip : copy the file to a tmp file and return a reference to it - if($insideZip){ - $zipPath = $split[0]; - $localPath = $split[1]; - require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); - //print($streamType.$path); - if($streamType == "file"){ - if(self::$crtZip == null || !is_array(self::$currentListingKeys)){ - $tmpDir = AJXP_Utils::getAjxpTmpDir() . DIRECTORY_SEPARATOR . md5(time()-rand()); - mkdir($tmpDir); - $tmpFileName = $tmpDir.DIRECTORY_SEPARATOR.basename($localPath); - AJXP_Logger::debug("Tmp file $tmpFileName"); - register_shutdown_function(array("fsAccessWrapper", "removeTmpFile"), $tmpDir, $tmpFileName); - $crtZip = new PclZip(AJXP_Utils::securePath(realpath($repoObject->getOption("PATH")).$repoObject->resolveVirtualRoots($zipPath))); - $content = $crtZip->listContent(); - foreach ($content as $item){ - $fName = AJXP_Utils::securePath($item["stored_filename"]); - if($fName == $localPath || "/".$fName == $localPath){ - $localPath = $fName; - break; - } - } - $res = $crtZip->extract(PCLZIP_OPT_BY_NAME, $localPath, PCLZIP_OPT_PATH, $tmpDir, PCLZIP_OPT_REMOVE_ALL_PATH); - AJXP_Logger::debug("Extracted ".$path." to ".dirname($localPath)); - if($storeOpenContext) self::$crtZip = $crtZip; - return $tmpFileName; - }else{ - $key = basename($localPath); - if(array_key_exists($key, self::$currentListing)){ - self::$currentFileKey = $key; - return -1; - }else{ - throw new AJXP_Exception("Cannot find key"); - } - } - }else{ - $crtZip = new PclZip(AJXP_Utils::securePath(realpath($repoObject->getOption("PATH")).$repoObject->resolveVirtualRoots($zipPath))); - $liste = $crtZip->listContent(); - if($storeOpenContext) self::$crtZip = $crtZip; - $folders = array(); $files = array();$builtFolders = array(); - if($localPath[strlen($localPath)-1] != "/") $localPath.="/"; - foreach ($liste as $item){ - $stored = $item["stored_filename"]; - if($stored[0] != "/") $stored = "/".$stored; - $pathPos = strpos($stored, $localPath); - if($pathPos !== false){ - $afterPath = substr($stored, $pathPos+strlen($localPath)); - if($afterPath != "" && substr_count($afterPath, "/") < 2){ - $statValue = array(); - if(substr_count($afterPath, "/") == 0){ + if (isSet($url["fragment"]) && strlen($url["fragment"]) > 0) { + $url["path"] .= "#".$url["fragment"]; + } + $repoObject = ConfService::getRepositoryById($repoId); + if(!isSet($repoObject)) throw new Exception("Cannot find repository with id ".$repoId); + $split = UserSelection::detectZip($url["path"]); + $insideZip = false; + if($split && $streamType == "file" && $split[1] != "/") $insideZip = true; + if($split && $streamType == "dir") $insideZip = true; + if($skipZip) $insideZip = false; + //var_dump($path); + //var_dump($skipZip); + // Inside a zip : copy the file to a tmp file and return a reference to it + if ($insideZip) { + $zipPath = $split[0]; + $localPath = $split[1]; + require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); + //print($streamType.$path); + if ($streamType == "file") { + if (self::$crtZip == null || !is_array(self::$currentListingKeys)) { + $tmpDir = AJXP_Utils::getAjxpTmpDir() . DIRECTORY_SEPARATOR . md5(time()-rand()); + mkdir($tmpDir); + $tmpFileName = $tmpDir.DIRECTORY_SEPARATOR.basename($localPath); + AJXP_Logger::debug("Tmp file $tmpFileName"); + register_shutdown_function(array("fsAccessWrapper", "removeTmpFile"), $tmpDir, $tmpFileName); + $crtZip = new PclZip(AJXP_Utils::securePath(realpath($repoObject->getOption("PATH")).$repoObject->resolveVirtualRoots($zipPath))); + $content = $crtZip->listContent(); + foreach ($content as $item) { + $fName = AJXP_Utils::securePath($item["stored_filename"]); + if ($fName == $localPath || "/".$fName == $localPath) { + $localPath = $fName; + break; + } + } + $res = $crtZip->extract(PCLZIP_OPT_BY_NAME, $localPath, PCLZIP_OPT_PATH, $tmpDir, PCLZIP_OPT_REMOVE_ALL_PATH); + AJXP_Logger::debug("Extracted ".$path." to ".dirname($localPath)); + if($storeOpenContext) self::$crtZip = $crtZip; + return $tmpFileName; + } else { + $key = basename($localPath); + if (array_key_exists($key, self::$currentListing)) { + self::$currentFileKey = $key; + return -1; + } else { + throw new AJXP_Exception("Cannot find key"); + } + } + } else { + $crtZip = new PclZip(AJXP_Utils::securePath(realpath($repoObject->getOption("PATH")).$repoObject->resolveVirtualRoots($zipPath))); + $liste = $crtZip->listContent(); + if($storeOpenContext) self::$crtZip = $crtZip; + $folders = array(); $files = array();$builtFolders = array(); + if($localPath[strlen($localPath)-1] != "/") $localPath.="/"; + foreach ($liste as $item) { + $stored = $item["stored_filename"]; + if($stored[0] != "/") $stored = "/".$stored; + $pathPos = strpos($stored, $localPath); + if ($pathPos !== false) { + $afterPath = substr($stored, $pathPos+strlen($localPath)); + if ($afterPath != "" && substr_count($afterPath, "/") < 2) { + $statValue = array(); + if (substr_count($afterPath, "/") == 0) { $statValue[2] = $statValue["mode"] = ($item["folder"]?"00040000":"0100000"); $statValue[7] = $statValue["size"] = $item["size"]; $statValue[8] = $statValue["atime"] = $item["mtime"]; $statValue[9] = $statValue["mtime"] = $item["mtime"]; $statValue[10] = $statValue["ctime"] = $item["mtime"]; - if(strpos($afterPath, "/") == strlen($afterPath)-1){ + if (strpos($afterPath, "/") == strlen($afterPath)-1) { $afterPath = substr($afterPath, 0, strlen($afterPath)-1); } //$statValue["filename"] = $zipPath.$localPath.$afterPath; - if($item["folder"]){ + if ($item["folder"]) { $folders[$afterPath] = $statValue; - }else{ + } else { $files[$afterPath] = $statValue; } - }else{ + } else { $arr = explode("/", $afterPath); $afterPath = array_shift($arr); if(isSet($folders[$afterPath]) || isSet($builtFolders[$afterPath])) continue; @@ -154,20 +155,20 @@ protected static function initPath($path, $streamType, $storeOpenContext = false $statValue[10] = $statValue["ctime"] = $item["mtime"]; $builtFolders[$afterPath] = $statValue; } - } - } - } - self::$currentListing = array_merge($folders, $builtFolders, $files); - self::$currentListingKeys = array_keys(self::$currentListing); - self::$currentListingIndex = 0; - return -1; - } - }else{ - if($atRoot){ + } + } + } + self::$currentListing = array_merge($folders, $builtFolders, $files); + self::$currentListingKeys = array_keys(self::$currentListing); + self::$currentListingIndex = 0; + return -1; + } + } else { + if ($atRoot) { $virtual = $repoObject->listVirtualRoots(); - if(count($virtual)){ + if (count($virtual)) { self::$currentListing = array(); - foreach($virtual as $rootKey => $rootValue){ + foreach ($virtual as $rootKey => $rootValue) { $statValue = array(); $statValue[2] = $statValue["mode"] = 00040000;//($rootValue["right"] == "rw" ? "00040000" : "00070000"); self::$currentListing[$rootKey] = $statValue; @@ -177,75 +178,83 @@ protected static function initPath($path, $streamType, $storeOpenContext = false return -1; } } - return realpath($repoObject->getOption("PATH")).$repoObject->resolveVirtualRoots($url["path"]); - } + return realpath($repoObject->getOption("PATH")).$repoObject->resolveVirtualRoots($url["path"]); + } } - public static function patchPathForBaseDir($dirPath){ + public static function patchPathForBaseDir($dirPath) + { if(!ini_get("open_basedir") || !preg_match('/\.zip/i', $dirPath)) return $dirPath; return str_replace(".zip", "__ZIP_EXTENSION__", $dirPath); } - public static function unPatchPathForBaseDir($dirPath){ + public static function unPatchPathForBaseDir($dirPath) + { if(!ini_get("open_basedir")) return $dirPath; return str_replace("__ZIP_EXTENSION__", ".zip", $dirPath); } - public static function removeTmpFile($tmpDir, $tmpFile){ - if(is_file($tmpFile)) unlink($tmpFile); - if(is_dir($tmpDir)) rmdir($tmpDir); + public static function removeTmpFile($tmpDir, $tmpFile) + { + if(is_file($tmpFile)) unlink($tmpFile); + if(is_dir($tmpDir)) rmdir($tmpDir); } - - protected static function closeWrapper(){ - if(self::$crtZip != null) { - self::$crtZip = null; - self::$currentListing = null; - self::$currentListingKeys = null; - self::$currentListingIndex = null; - self::$currentFileKey = null; - } + + protected static function closeWrapper() + { + if (self::$crtZip != null) { + self::$crtZip = null; + self::$currentListing = null; + self::$currentListingKeys = null; + self::$currentListingIndex = null; + self::$currentFileKey = null; + } + } + + public static function getRealFSReference($path, $persistent = false) + { + $contextOpened =false; + if (self::$crtZip != null) { + $contextOpened = true; + $crtZip = self::$crtZip; + self::$crtZip = null; + } + $realPath = self::initPath($path, "file"); + if (!$contextOpened) { + self::closeWrapper(); + } else { + self::$crtZip = $crtZip; + } + return $realPath; } - - public static function getRealFSReference($path, $persistent = false){ - $contextOpened =false; - if(self::$crtZip != null){ - $contextOpened = true; - $crtZip = self::$crtZip; - self::$crtZip = null; - } - $realPath = self::initPath($path, "file"); - if(!$contextOpened) { - self::closeWrapper(); - }else{ - self::$crtZip = $crtZip; - } - return $realPath; + + public static function isRemote() + { + return false; } - - public static function isRemote(){ - return false; + + public static function copyFileInStream($path, $stream) + { + $fp = fopen(self::getRealFSReference($path), "rb"); + while (!feof($fp)) { + if(!ini_get("safe_mode")) @set_time_limit(60); + $data = fread($fp, 4096); + fwrite($stream, $data, strlen($data)); + } + fclose($fp); } - - public static function copyFileInStream($path, $stream){ - $fp = fopen(self::getRealFSReference($path), "rb"); - while (!feof($fp)) { - if(!ini_get("safe_mode")) @set_time_limit(60); - $data = fread($fp, 4096); - fwrite($stream, $data, strlen($data)); - } - fclose($fp); - } - - public static function changeMode($path, $chmodValue){ - $realPath = self::initPath($path, "file"); - @chmod($realPath, $chmodValue); + + public static function changeMode($path, $chmodValue) + { + $realPath = self::initPath($path, "file"); + @chmod($realPath, $chmodValue); } - + /** * Opens the strem * - * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" + * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" * @param String $mode * @param unknown_type $options * @param unknown_type $context @@ -253,223 +262,237 @@ public static function changeMode($path, $chmodValue){ */ public function stream_open($path, $mode, $options, &$context) { - try{ - $this->realPath = AJXP_Utils::securePath(self::initPath($path, "file")); - }catch (Exception $e){ - AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); - return false; - } - if($this->realPath == -1){ - $this->fp = -1; - return true; - }else{ - $this->fp = fopen($this->realPath, $mode, $options); - return ($this->fp !== false); - } + try { + $this->realPath = AJXP_Utils::securePath(self::initPath($path, "file")); + } catch (Exception $e) { + AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); + return false; + } + if ($this->realPath == -1) { + $this->fp = -1; + return true; + } else { + $this->fp = fopen($this->realPath, $mode, $options); + return ($this->fp !== false); + } } - - public function stream_seek($offset , $whence = SEEK_SET){ - fseek($this->fp, $offset, SEEK_SET); + + public function stream_seek($offset , $whence = SEEK_SET) + { + fseek($this->fp, $offset, SEEK_SET); } - - public function stream_tell(){ - return ftell($this->fp); + + public function stream_tell() + { + return ftell($this->fp); } - - public function stream_stat(){ - $PROBE_REAL_SIZE = ConfService::getConf("PROBE_REAL_SIZE"); - if(is_resource($this->fp)){ - $statValue = fstat($this->fp); + + public function stream_stat() + { + $PROBE_REAL_SIZE = ConfService::getConf("PROBE_REAL_SIZE"); + if (is_resource($this->fp)) { + $statValue = fstat($this->fp); fsAccessWrapper::$lastRealSize = false; - if($statValue[2] > 0 && $PROBE_REAL_SIZE && !ini_get("safe_mode")){ - fsAccessWrapper::$lastRealSize = floatval(trim($this->getTrueSizeOnFileSystem($this->realPath))); - } - return $statValue; - } - if(is_resource($this->dH)){ - return fstat($this->dH); - } - if($this->fp == -1){ - return self::$currentListing[self::$currentFileKey]; - } - return null; + if ($statValue[2] > 0 && $PROBE_REAL_SIZE && !ini_get("safe_mode")) { + fsAccessWrapper::$lastRealSize = floatval(trim($this->getTrueSizeOnFileSystem($this->realPath))); + } + return $statValue; + } + if (is_resource($this->dH)) { + return fstat($this->dH); + } + if ($this->fp == -1) { + return self::$currentListing[self::$currentFileKey]; + } + return null; } - - public function url_stat($path, $flags){ - // File and zip case + + public function url_stat($path, $flags) + { + // File and zip case $patchedPath = self::patchPathForBaseDir($path); - if(ini_get("open_basedir") && preg_match('/__ZIP_EXTENSION__/', $patchedPath)){ + if (ini_get("open_basedir") && preg_match('/__ZIP_EXTENSION__/', $patchedPath)) { // Zip Folder case self::$lastRealSize = false; $search = basename($path); $realBase = $this->initPath(dirname($path), "dir"); - if($realBase == -1){ - if(array_key_exists($search, self::$currentListing)){ + if ($realBase == -1) { + if (array_key_exists($search, self::$currentListing)) { return self::$currentListing[$search]; } } } - if($fp = @fopen($path, "r")){ - $stat = fstat($fp); - fclose($fp); - return $stat; - } - // Folder case - $real = $this->initPath($path, "dir", false, true); - if($real!=-1 && is_dir($real)){ - return stat($real); - } - // Zip Folder case - $search = basename($path); - $realBase = $this->initPath(dirname($path), "dir"); - if($realBase == -1){ - if(array_key_exists($search, self::$currentListing)){ - return self::$currentListing[$search]; - } - } - // 000 permission file - if($real != -1 && is_file($real)){ - return stat($real); - } + if ($fp = @fopen($path, "r")) { + $stat = fstat($fp); + fclose($fp); + return $stat; + } + // Folder case + $real = $this->initPath($path, "dir", false, true); + if ($real!=-1 && is_dir($real)) { + return stat($real); + } + // Zip Folder case + $search = basename($path); + $realBase = $this->initPath(dirname($path), "dir"); + if ($realBase == -1) { + if (array_key_exists($search, self::$currentListing)) { + return self::$currentListing[$search]; + } + } + // 000 permission file + if ($real != -1 && is_file($real)) { + return stat($real); + } // Handle symlinks! - if($real != -1 && is_link($real)){ - $realFile = @readlink($real); - if(is_file($realFile) || is_dir($realFile)) { - return stat($realFile); - } else { + if ($real != -1 && is_link($real)) { + $realFile = @readlink($real); + if (is_file($realFile) || is_dir($realFile)) { + return stat($realFile); + } else { // symlink is broken, delete it. - @unlink($real); - return null; - } - } + @unlink($real); + return null; + } + } - // Non existing file - return null; + // Non existing file + return null; } - - public function rename($from, $to){ - return rename($this->initPath($from, "file", false, true), $this->initPath($to, "file", false, true)); + + public function rename($from, $to) + { + return rename($this->initPath($from, "file", false, true), $this->initPath($to, "file", false, true)); } - - public function stream_read($count){ - return fread($this->fp, $count); + + public function stream_read($count) + { + return fread($this->fp, $count); } - public function stream_write($data){ - fwrite($this->fp, $data, strlen($data)); + public function stream_write($data) + { + fwrite($this->fp, $data, strlen($data)); return strlen($data); } - public function stream_eof(){ - return feof($this->fp); + public function stream_eof() + { + return feof($this->fp); } - - public function stream_close(){ - if(isSet($this->fp) && $this->fp!=-1 && $this->fp!==false){ - fclose($this->fp); - } + + public function stream_close() + { + if (isSet($this->fp) && $this->fp!=-1 && $this->fp!==false) { + fclose($this->fp); + } } - - public function stream_flush(){ - if(isSet($this->fp) && $this->fp!=-1 && $this->fp!==false){ - fflush($this->fp); - } + + public function stream_flush() + { + if (isSet($this->fp) && $this->fp!=-1 && $this->fp!==false) { + fflush($this->fp); + } } - - public function unlink($path){ - $this->realPath = $this->initPath($path, "file", false, true); - return unlink($this->realPath); + + public function unlink($path) + { + $this->realPath = $this->initPath($path, "file", false, true); + return unlink($this->realPath); } - - public function rmdir($path, $options){ - $this->realPath = $this->initPath($path, "file", false, true); - return rmdir($this->realPath); + + public function rmdir($path, $options) + { + $this->realPath = $this->initPath($path, "file", false, true); + return rmdir($this->realPath); } - - public function mkdir($path, $mode, $options){ - return mkdir($this->initPath($path, "file"), $mode); + + public function mkdir($path, $mode, $options) + { + return mkdir($this->initPath($path, "file"), $mode); } - + /** * Readdir functions * * @param string $path * @param int $options */ - public function dir_opendir ($path , $options ){ - $this->realPath = $this->initPath($path, "dir", true); - if(is_string($this->realPath)){ - $this->dH = @opendir($this->realPath); - }else if($this->realPath == -1){ - $this->dH = -1; - } - return $this->dH !== false; - } - public function dir_closedir (){ - $this->closeWrapper(); - if($this->dH == -1){ - return true; - }else{ - return closedir($this->dH); - } - } - public function dir_readdir (){ - if($this->dH == -1){ - if(isSet(self::$currentListingKeys[self::$currentListingIndex])){ - self::$currentListingIndex ++; - return self::$currentListingKeys[self::$currentListingIndex-1]; - }else{ - return false; - } - }else{ - return readdir($this->dH); - } - } - public function dir_rewinddir () { - if($this->dH == -1){ - self::$currentListingIndex = 0; - }else{ - return rewinddir($this->dH); - } - } - - public static function getLastRealSize(){ + public function dir_opendir ($path , $options ) + { + $this->realPath = $this->initPath($path, "dir", true); + if (is_string($this->realPath)) { + $this->dH = @opendir($this->realPath); + } else if ($this->realPath == -1) { + $this->dH = -1; + } + return $this->dH !== false; + } + public function dir_closedir () + { + $this->closeWrapper(); + if ($this->dH == -1) { + return true; + } else { + return closedir($this->dH); + } + } + public function dir_readdir () + { + if ($this->dH == -1) { + if (isSet(self::$currentListingKeys[self::$currentListingIndex])) { + self::$currentListingIndex ++; + return self::$currentListingKeys[self::$currentListingIndex-1]; + } else { + return false; + } + } else { + return readdir($this->dH); + } + } + public function dir_rewinddir () + { + if ($this->dH == -1) { + self::$currentListingIndex = 0; + } else { + return rewinddir($this->dH); + } + } + + public static function getLastRealSize() + { return self::$lastRealSize; } - protected function getTrueSizeOnFileSystem($file) { - if (!(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')){ - $cmd = "stat -L -c%s ".escapeshellarg($file); - $val = trim(`$cmd`); - if (strlen($val) == 0 || floatval($val) == 0) - { - // No stat on system - $cmd = "ls -1s --block-size=1 ".escapeshellarg($file); - $val = trim(`$cmd`); - } - if (strlen($val) == 0 || floatval($val) == 0) - { - // No block-size on system (probably busybox), try long output - $cmd = "ls -l ".escapeshellarg($file).""; - - $arr = explode("/[\s]+/", `$cmd`); - $val = trim($arr[4]); - } - if (strlen($val) == 0 || floatval($val) == 0){ - // Still not working, get a value at least, not 0... - $val = sprintf("%u", filesize($file)); - } - return floatval($val); - }else if (class_exists("COM")){ - $fsobj = new COM("Scripting.FileSystemObject"); - $f = $fsobj->GetFile($file); - return floatval($f->Size); - } - else if (is_file($file)){ - return exec('FOR %A IN ("'.$file.'") DO @ECHO %~zA'); - } - else return sprintf("%u", filesize($file)); - } - + protected function getTrueSizeOnFileSystem($file) + { + if (!(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')) { + $cmd = "stat -L -c%s ".escapeshellarg($file); + $val = trim(`$cmd`); + if (strlen($val) == 0 || floatval($val) == 0) { + // No stat on system + $cmd = "ls -1s --block-size=1 ".escapeshellarg($file); + $val = trim(`$cmd`); + } + if (strlen($val) == 0 || floatval($val) == 0) { + // No block-size on system (probably busybox), try long output + $cmd = "ls -l ".escapeshellarg($file).""; + + $arr = explode("/[\s]+/", `$cmd`); + $val = trim($arr[4]); + } + if (strlen($val) == 0 || floatval($val) == 0) { + // Still not working, get a value at least, not 0... + $val = sprintf("%u", filesize($file)); + } + return floatval($val); + } else if (class_exists("COM")) { + $fsobj = new COM("Scripting.FileSystemObject"); + $f = $fsobj->GetFile($file); + return floatval($f->Size); + } else if (is_file($file)) { + return exec('FOR %A IN ("'.$file.'") DO @ECHO %~zA'); + } else return sprintf("%u", filesize($file)); + } + } -?> \ No newline at end of file diff --git a/core/src/plugins/access.fs/fsActions.xml b/core/src/plugins/access.fs/fsActions.xml index c0d4020c26..7a9cc22e5b 100644 --- a/core/src/plugins/access.fs/fsActions.xml +++ b/core/src/plugins/access.fs/fsActions.xml @@ -1,995 +1,995 @@ - - - - - - - - - - - - - - 0){ - path = window.actionArguments[0]; - if(Object.isString(path)){path = new AjxpNode(path,false,getBaseName(path));} - }else{ - userSelection = ajaxplorer.getUserSelection(); - if(userSelection && userSelection.isUnique() && (userSelection.hasDir() || userSelection.hasMime("AJXP_MIMES_ZIP".split(",")))){ - path = userSelection.getUniqueNode(); - } - } - if(path){ - ajaxplorer.updateContextData(path); - } - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    AJXP_MESSAGE[119]

    -
    -
    - - -
    - - ]]> -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - AJXP_MESSAGE[315]
    - - - ]]>
    - - -
    -
    - - - - - - - - - - - - - - 0){ - context.builderMenuItems.push({separator:true}); - } - sepAdded = true; - } - context.builderMenuItems.push({ - name:el.text, - alt:el.title, - isDefault : (index == 0), - image:resolveImageSource(el.icon, '/images/actions/ICON_SIZE', 22), - icon_class: el.icon_class, - callback:function(e){this.apply([el]);}.bind(context) - } ); - index++; - } ); - } - if(!index){ - context.builderMenuItems.push({ - name:MessageHash[324], - alt:MessageHash[324], - image:resolveImageSource('button_cancel.png', '/images/actions/ICON_SIZE', 22), - callback:function(e){} - } ); - } - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - 0){ - url = url.substring(0, url.indexOf('#')); - } - if(url.indexOf('?') > 0){ - url = url.substring(0, url.indexOf('?')); - } - var repoId = ajaxplorer.repositoryId || (ajaxplorer.user ? ajaxplorer.user.activeRepository : null); - if(ajaxplorer.user){ - var slug = ajaxplorer.user.repositories.get(repoId).getSlug(); - if(slug) repoId = slug; - } - link = url + '?goto=' + repoId + encodeURIComponent(ajaxplorer.getUserSelection().getUniqueNode().getPath()); - input.value = link; - var email = oForm.down('a[id="email"]'); - if (email){ - email.setAttribute('href', 'mailto:unknown@unknown.com?Subject=UPLOAD&Body='+encodeURIComponent(link)); - } - input.select(); - }; - modal.showDialogForm('Get', 'ajxp_link_form', loadFunc, function(){ - hideLightBox(true); - return false; - }, null, true); - ]]> - -
    - AJXP_MESSAGE[296] - - -
    - - ]]>
    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AJXP_MESSAGE[173]
    - - - ]]>
    - -
    -
    - - - - - - - - - AJXP_MESSAGE[174]
    - - - ]]>
    - -
    -
    - - - - - - - - - - - - - - - - - - - - - -
    AJXP_MESSAGE[175]
    - -
    -
    -
    - - - ]]>
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - ]]> - - - - - - - - - - - - - - ]]> - - - - - - - - - - - - '+MessageHash[401]+''+MessageHash[402]+''); - dObject.insert({before:'\ -
    \ - '+MessageHash[400]+' \ - \ -
    \ - '}); - $("dl_form_submit").observe("click", function(e){ - Event.stop(e); - var conn = new Connexion(); - conn.addParameter("get_action", "prepare_chunk_dl"); - conn.addParameter("chunk_count", $("chunk_count").value ); - conn.addParameter("file", userSelection.getUniqueNode().getPath()); - var downloader = new MultiDownloader(dObject, ''); - conn.onComplete = function(transp){ - var chunkData = transp.responseJSON; - downloader.setDownloadUrl(ajxpServerAccessPath+'&action=download_chunk&file_id='+chunkData.file_id); - downloader.triggerEnd = function(){hideLightBox();}; - for(var i=0; i
    - -
    AJXP_MESSAGE[119]

    -
    -
    - - -
    - - ]]> -
    - -
    -
    - - - - - -
    - - - - - - - - - - - - #{select_something_string} - -
    - - - - - - - - - - - - - -
    #{folders_string}#{filelist_folders_count}
    #{files_string}#{filelist_files_count}
    #{totalsize_string}#{filelist_totalsize}
    -
    - ]]> -
    - - - - - - - - - - #{preview_rich} - - - ]]> - - - - - - - - - - - - ]]> - -
    -
    -
    + + + + + + + + + + + + + + 0){ + path = window.actionArguments[0]; + if(Object.isString(path)){path = new AjxpNode(path,false,getBaseName(path));} + }else{ + userSelection = ajaxplorer.getUserSelection(); + if(userSelection && userSelection.isUnique() && (userSelection.hasDir() || userSelection.hasMime("AJXP_MIMES_ZIP".split(",")))){ + path = userSelection.getUniqueNode(); + } + } + if(path){ + ajaxplorer.updateContextData(path); + } + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AJXP_MESSAGE[119]

    +
    +
    + + +
    + + ]]> +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + AJXP_MESSAGE[315]
    + + + ]]>
    + + +
    +
    + + + + + + + + + + + + + + 0){ + context.builderMenuItems.push({separator:true}); + } + sepAdded = true; + } + context.builderMenuItems.push({ + name:el.text, + alt:el.title, + isDefault : (index == 0), + image:resolveImageSource(el.icon, '/images/actions/ICON_SIZE', 22), + icon_class: el.icon_class, + callback:function(e){this.apply([el]);}.bind(context) + } ); + index++; + } ); + } + if(!index){ + context.builderMenuItems.push({ + name:MessageHash[324], + alt:MessageHash[324], + image:resolveImageSource('button_cancel.png', '/images/actions/ICON_SIZE', 22), + callback:function(e){} + } ); + } + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + 0){ + url = url.substring(0, url.indexOf('#')); + } + if(url.indexOf('?') > 0){ + url = url.substring(0, url.indexOf('?')); + } + var repoId = ajaxplorer.repositoryId || (ajaxplorer.user ? ajaxplorer.user.activeRepository : null); + if(ajaxplorer.user){ + var slug = ajaxplorer.user.repositories.get(repoId).getSlug(); + if(slug) repoId = slug; + } + link = url + '?goto=' + repoId + encodeURIComponent(ajaxplorer.getUserSelection().getUniqueNode().getPath()); + input.value = link; + var email = oForm.down('a[id="email"]'); + if (email){ + email.setAttribute('href', 'mailto:unknown@unknown.com?Subject=UPLOAD&Body='+encodeURIComponent(link)); + } + input.select(); + }; + modal.showDialogForm('Get', 'ajxp_link_form', loadFunc, function(){ + hideLightBox(true); + return false; + }, null, true); + ]]> + +
    + AJXP_MESSAGE[296] + + +
    + + ]]>
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AJXP_MESSAGE[173]
    + + + ]]>
    + +
    +
    + + + + + + + + + AJXP_MESSAGE[174]
    + + + ]]>
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    AJXP_MESSAGE[175]
    + +
    +
    +
    + + + ]]>
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + '+MessageHash[401]+''+MessageHash[402]+''); + dObject.insert({before:'\ +
    \ + '+MessageHash[400]+' \ + \ +
    \ + '}); + $("dl_form_submit").observe("click", function(e){ + Event.stop(e); + var conn = new Connexion(); + conn.addParameter("get_action", "prepare_chunk_dl"); + conn.addParameter("chunk_count", $("chunk_count").value ); + conn.addParameter("file", userSelection.getUniqueNode().getPath()); + var downloader = new MultiDownloader(dObject, ''); + conn.onComplete = function(transp){ + var chunkData = transp.responseJSON; + downloader.setDownloadUrl(ajxpServerAccessPath+'&action=download_chunk&file_id='+chunkData.file_id); + downloader.triggerEnd = function(){hideLightBox();}; + for(var i=0; i
    + +
    AJXP_MESSAGE[119]

    +
    +
    + + +
    + + ]]> +
    + +
    +
    + + + + + +
    + + + + + + + + + + + + #{select_something_string} + +
    + + + + + + + + + + + + + +
    #{folders_string}#{filelist_folders_count}
    #{files_string}#{filelist_files_count}
    #{totalsize_string}#{filelist_totalsize}
    +
    + ]]> +
    + + + + + + + + + + #{preview_rich} + + + ]]> + + + + + + + + + + + + ]]> + +
    +
    +
    diff --git a/core/src/plugins/access.fs/i18n/conf/en.php b/core/src/plugins/access.fs/i18n/conf/en.php index f5862d6113..a7abdf366c 100644 --- a/core/src/plugins/access.fs/i18n/conf/en.php +++ b/core/src/plugins/access.fs/i18n/conf/en.php @@ -35,4 +35,4 @@ "Delegates all download operations to the webserver using the X-SendFile header. Warning, this is an external module to install for Apache. Module is active by default in Lighttpd. Warning, you have to manually add the folders where files will be downloaded in the module configuration (XSendFilePath directive)" => "Delegates all download operations to the webserver using the X-SendFile header. Warning, this is an external module to install for Apache. Module is active by default in Lighttpd. Warning, you have to manually add the folders where files will be downloaded in the module configuration (XSendFilePath directive)", "Data template" => "Data template", "Path to a directory on the filesystem whose content will be copied to the repository the first time it is loaded." => "Path to a directory on the filesystem whose content will be copied to the workspace the first time it is loaded." -); \ No newline at end of file +); diff --git a/core/src/plugins/access.fs/i18n/conf/fr.php b/core/src/plugins/access.fs/i18n/conf/fr.php index c558b13f79..f4b587f9f4 100644 --- a/core/src/plugins/access.fs/i18n/conf/fr.php +++ b/core/src/plugins/access.fs/i18n/conf/fr.php @@ -35,4 +35,4 @@ "Delegates all download operations to the webserver using the X-SendFile header. Warning, this is an external module to install for Apache. Module is active by default in Lighttpd. Warning, you have to manually add the folders where files will be downloaded in the module configuration (XSendFilePath directive)" => "Déleguer les opérations de téléchargement au serveur web grâce au module X-SendFile. Attention, il est packagé par défaut dans Lighttpd mais doit être téléchargé et ajouté manuellement dans Apache. Il faut aussi configurer manuellement les chemins autorisés pour télécharger des fichiers, voir la directive XSendFilePath.", "Data template" => "Données préchargées", "Path to a directory on the filesystem whose content will be copied to the repository the first time it is loaded." => "Chemin vers un répertoire sur le filesystem dont le contenu va être copié dans le dépôt à la première connexion." -); \ No newline at end of file +); diff --git a/core/src/plugins/access.fs/i18n/conf/pt.php b/core/src/plugins/access.fs/i18n/conf/pt.php index 47023e1e71..8e8c07c602 100644 --- a/core/src/plugins/access.fs/i18n/conf/pt.php +++ b/core/src/plugins/access.fs/i18n/conf/pt.php @@ -35,4 +35,4 @@ "Delegates all download operations to the webserver using the X-SendFile header. Warning, this is an external module to install for Apache. Module is active by default in Lighttpd. Warning, you have to manually add the folders where files will be downloaded in the module configuration (XSendFilePath directive)" => "Delega todas as operações de transferência para o servidor utilizado o X-SendFile header. ATENÇÃO: Este é um módulo externo que tem que ser instalado no Apache. Este módulo encontra-se activado por pré definição no Lighttpd. ATENÇÃO: Tem que manualmente adicionar as pastas onde os ficheiros serão transferidos na configuração do módulo (Na pasta XSendFilePath)", "Data template" => "Modelo de Dados", "Path to a directory on the filesystem whose content will be copied to the repository the first time it is loaded." => "Caminho para a pasta no sistema de ficheiros cujo conteúdos serão copiados para a Área de Trabalho na primeira vez que esta for carregada." -); \ No newline at end of file +); diff --git a/core/src/plugins/access.fs/manifest.xml b/core/src/plugins/access.fs/manifest.xml index e78c93879b..76fb51b3ed 100644 --- a/core/src/plugins/access.fs/manifest.xml +++ b/core/src/plugins/access.fs/manifest.xml @@ -31,7 +31,7 @@ - + diff --git a/core/src/plugins/access.fs/test.fsAccess.php b/core/src/plugins/access.fs/test.fsAccess.php index 091f989b5f..9a6cf28d05 100644 --- a/core/src/plugins/access.fs/test.fsAccess.php +++ b/core/src/plugins/access.fs/test.fsAccess.php @@ -28,7 +28,7 @@ */ class fsAccessTest extends AbstractTest { - function fsAccessTest() { parent::AbstractTest("Filesystem Plugin", ""); } + public function fsAccessTest() { parent::AbstractTest("Filesystem Plugin", ""); } /** * Test Repository @@ -36,24 +36,20 @@ function fsAccessTest() { parent::AbstractTest("Filesystem Plugin", ""); } * @param Repository $repo * @return Boolean */ - function doRepositoryTest($repo){ + public function doRepositoryTest($repo) + { if ($repo->accessType != 'fs' ) return -1; // Check the destination path $this->failedInfo = ""; $path = $repo->getOption("PATH", false); $createOpt = $repo->getOption("CREATE"); $create = (($createOpt=="true"||$createOpt===true)?true:false); - if(strstr($path, "AJXP_USER")!==false) return TRUE; // CANNOT TEST THIS CASE! - if (!$create && !@is_dir($path)) - { - $this->failedInfo .= "Selected repository path ".$path." doesn't exist, and the CREATE option is false"; return FALSE; - } - else if (!$create && !is_writeable($path)) - { $this->failedInfo .= "Selected repository path ".$path." isn't writeable"; return FALSE; } - // Do more tests here - return TRUE; + if(strstr($path, "AJXP_USER")!==false) return TRUE; // CANNOT TEST THIS CASE! + if (!$create && !@is_dir($path)) { + $this->failedInfo .= "Selected repository path ".$path." doesn't exist, and the CREATE option is false"; return FALSE; + } else if (!$create && !is_writeable($path)) { $this->failedInfo .= "Selected repository path ".$path." isn't writeable"; return FALSE; } + // Do more tests here + return TRUE; } - -}; -?> +}; diff --git a/core/src/plugins/access.ftp/class.ftpAccessDriver.php b/core/src/plugins/access.ftp/class.ftpAccessDriver.php index 3cd2b1e157..da52f466f3 100644 --- a/core/src/plugins/access.ftp/class.ftpAccessDriver.php +++ b/core/src/plugins/access.ftp/class.ftpAccessDriver.php @@ -26,245 +26,240 @@ * @package AjaXplorer_Plugins * @subpackage Access */ -class ftpAccessDriver extends fsAccessDriver { - - public function loadManifest(){ - parent::loadManifest(); - // BACKWARD COMPATIBILITY! - $res = $this->xPath->query('//param[@name="USER"] | //param[@name="PASS"] | //user_param[@name="USER"] | //user_param[@name="PASS"]'); - foreach($res as $node){ - if($node->getAttribute("name") == "USER"){ - $node->setAttribute("name", "FTP_USER"); - }else if($node->getAttribute("name") == "PASS"){ - $node->setAttribute("name", "FTP_PASS"); - } - } - $this->reloadXPath(); - } - - /** - * Parse - * @param DOMNode $contribNode - */ - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($contribNode->nodeName != "actions") return ; - $this->disableArchiveBrowsingContributions($contribNode); +class ftpAccessDriver extends fsAccessDriver +{ + public function loadManifest() + { + parent::loadManifest(); + // BACKWARD COMPATIBILITY! + $res = $this->xPath->query('//param[@name="USER"] | //param[@name="PASS"] | //user_param[@name="USER"] | //user_param[@name="PASS"]'); + foreach ($res as $node) { + if ($node->getAttribute("name") == "USER") { + $node->setAttribute("name", "FTP_USER"); + } else if ($node->getAttribute("name") == "PASS") { + $node->setAttribute("name", "FTP_PASS"); + } + } + $this->reloadXPath(); + } + + /** + * Parse + * @param DOMNode $contribNode + */ + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if($contribNode->nodeName != "actions") return ; + $this->disableArchiveBrowsingContributions($contribNode); $this->redirectActionsToMethod($contribNode, array("upload", "next_to_remote", "trigger_remote_copy"), "uploadActions"); - } - - function initRepository(){ - if(is_array($this->pluginConf)){ - $this->driverConf = $this->pluginConf; - }else{ - $this->driverConf = array(); - } - $wrapperData = $this->detectStreamWrapper(true); - $this->wrapperClassName = $wrapperData["classname"]; - $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); - $recycle = $this->repository->getOption("RECYCLE_BIN"); - if($recycle != ""){ - RecycleBinManager::init($this->urlBase, "/".$recycle); - } - } + } + + public function initRepository() + { + if (is_array($this->pluginConf)) { + $this->driverConf = $this->pluginConf; + } else { + $this->driverConf = array(); + } + $wrapperData = $this->detectStreamWrapper(true); + $this->wrapperClassName = $wrapperData["classname"]; + $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); + $recycle = $this->repository->getOption("RECYCLE_BIN"); + if ($recycle != "") { + RecycleBinManager::init($this->urlBase, "/".$recycle); + } + } - function uploadActions($action, $httpVars, $filesVars){ - switch ($action){ - case "trigger_remote_copy": - if(!$this->hasFilesToCopy()) break; - $toCopy = $this->getFileNameToCopy(); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::triggerBgAction("next_to_remote", array(), "Copying file ".$toCopy." to ftp server"); - AJXP_XMLWriter::close(); - exit(1); - break; - case "next_to_remote": - if(!$this->hasFilesToCopy()) break; - $fData = $this->getNextFileToCopy(); - $nextFile = ''; - if($this->hasFilesToCopy()){ - $nextFile = $this->getFileNameToCopy(); - } - AJXP_Logger::debug("Base64 : ", array("from"=>$fData["destination"], "to"=>base64_decode($fData['destination']))); - $destPath = $this->urlBase.base64_decode($fData['destination'])."/".$fData['name']; - //$destPath = AJXP_Utils::decodeSecureMagic($destPath); - // DO NOT "SANITIZE", THE URL IS ALREADY IN THE FORM ajxp.ftp://repoId/filename - $destPath = SystemTextEncoding::fromPostedFileName($destPath); + public function uploadActions($action, $httpVars, $filesVars) + { + switch ($action) { + case "trigger_remote_copy": + if(!$this->hasFilesToCopy()) break; + $toCopy = $this->getFileNameToCopy(); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::triggerBgAction("next_to_remote", array(), "Copying file ".$toCopy." to ftp server"); + AJXP_XMLWriter::close(); + exit(1); + break; + case "next_to_remote": + if(!$this->hasFilesToCopy()) break; + $fData = $this->getNextFileToCopy(); + $nextFile = ''; + if ($this->hasFilesToCopy()) { + $nextFile = $this->getFileNameToCopy(); + } + AJXP_Logger::debug("Base64 : ", array("from"=>$fData["destination"], "to"=>base64_decode($fData['destination']))); + $destPath = $this->urlBase.base64_decode($fData['destination'])."/".$fData['name']; + //$destPath = AJXP_Utils::decodeSecureMagic($destPath); + // DO NOT "SANITIZE", THE URL IS ALREADY IN THE FORM ajxp.ftp://repoId/filename + $destPath = SystemTextEncoding::fromPostedFileName($destPath); $node = new AJXP_Node($destPath); - AJXP_Logger::debug("Copying file to server", array("from"=>$fData["tmp_name"], "to"=>$destPath, "name"=>$fData["name"])); - try { + AJXP_Logger::debug("Copying file to server", array("from"=>$fData["tmp_name"], "to"=>$destPath, "name"=>$fData["name"])); + try { AJXP_Controller::applyHook("node.before_change", array(&$node)); $fp = fopen($destPath, "w"); - $fSource = fopen($fData["tmp_name"], "r"); - while(!feof($fSource)){ - fwrite($fp, fread($fSource, 4096)); - } - fclose($fSource); - AJXP_Logger::debug("Closing target : begin ftp copy"); - // Make sur the script does not time out! - @set_time_limit(240); - fclose($fp); - AJXP_Logger::debug("FTP Upload : end of ftp copy"); - @unlink($fData["tmp_name"]); + $fSource = fopen($fData["tmp_name"], "r"); + while (!feof($fSource)) { + fwrite($fp, fread($fSource, 4096)); + } + fclose($fSource); + AJXP_Logger::debug("Closing target : begin ftp copy"); + // Make sur the script does not time out! + @set_time_limit(240); + fclose($fp); + AJXP_Logger::debug("FTP Upload : end of ftp copy"); + @unlink($fData["tmp_name"]); AJXP_Controller::applyHook("node.change", array(&$node)); - }catch (Exception $e){ - AJXP_Logger::debug("Error during ftp copy", array($e->getMessage(), $e->getTrace())); - } - AJXP_Logger::debug("FTP Upload : shoud trigger next or reload nextFile=$nextFile"); - AJXP_XMLWriter::header(); - if($nextFile!=''){ - AJXP_XMLWriter::triggerBgAction("next_to_remote", array(), "Copying file ".SystemTextEncoding::toUTF8($nextFile)." to remote server"); - }else{ - AJXP_XMLWriter::triggerBgAction("reload_node", array(), "Upload done, reloading client."); - } - AJXP_XMLWriter::close(); - exit(1); - break; - case "upload": - $rep_source = AJXP_Utils::securePath("/".$httpVars['dir']); - AJXP_Logger::debug("Upload : rep_source ", array($rep_source)); - $logMessage = ""; - foreach ($filesVars as $boxName => $boxData) - { - if(substr($boxName, 0, 9) != "userfile_") continue; - AJXP_Logger::debug("Upload : rep_source ", array($rep_source)); - $err = AJXP_Utils::parseFileDataErrors($boxData); - if($err != null) - { - $errorCode = $err[0]; - $errorMessage = $err[1]; - break; - } - if(isSet($httpVars["auto_rename"])){ + } catch (Exception $e) { + AJXP_Logger::debug("Error during ftp copy", array($e->getMessage(), $e->getTrace())); + } + AJXP_Logger::debug("FTP Upload : shoud trigger next or reload nextFile=$nextFile"); + AJXP_XMLWriter::header(); + if ($nextFile!='') { + AJXP_XMLWriter::triggerBgAction("next_to_remote", array(), "Copying file ".SystemTextEncoding::toUTF8($nextFile)." to remote server"); + } else { + AJXP_XMLWriter::triggerBgAction("reload_node", array(), "Upload done, reloading client."); + } + AJXP_XMLWriter::close(); + exit(1); + break; + case "upload": + $rep_source = AJXP_Utils::securePath("/".$httpVars['dir']); + AJXP_Logger::debug("Upload : rep_source ", array($rep_source)); + $logMessage = ""; + foreach ($filesVars as $boxName => $boxData) { + if(substr($boxName, 0, 9) != "userfile_") continue; + AJXP_Logger::debug("Upload : rep_source ", array($rep_source)); + $err = AJXP_Utils::parseFileDataErrors($boxData); + if ($err != null) { + $errorCode = $err[0]; + $errorMessage = $err[1]; + break; + } + if (isSet($httpVars["auto_rename"])) { $destination = $this->urlBase.$rep_source; $boxData["name"] = fsAccessDriver::autoRenameForDest($destination, $boxData["name"]); } - $boxData["destination"] = base64_encode($rep_source); - $destCopy = AJXP_XMLWriter::replaceAjxpXmlKeywords($this->repository->getOption("TMP_UPLOAD")); - AJXP_Logger::debug("Upload : tmp upload folder", array($destCopy)); - if(!is_dir($destCopy)){ - if(! @mkdir($destCopy)){ - AJXP_Logger::debug("Upload error : cannot create temporary folder", array($destCopy)); - $errorCode = 413; - $errorMessage = "Warning, cannot create folder for temporary copy."; - break; - } - } - if(!$this->isWriteable($destCopy)){ - AJXP_Logger::debug("Upload error: cannot write into temporary folder"); - $errorCode = 414; - $errorMessage = "Warning, cannot write into temporary folder."; - break; - } - AJXP_Logger::debug("Upload : tmp upload folder", array($destCopy)); - if(isSet($boxData["input_upload"])){ - try{ - $destName = tempnam($destCopy, ""); - AJXP_Logger::debug("Begining reading INPUT stream"); - $input = fopen("php://input", "r"); - $output = fopen($destName, "w"); - $sizeRead = 0; - while($sizeRead < intval($boxData["size"])){ - $chunk = fread($input, 4096); - $sizeRead += strlen($chunk); - fwrite($output, $chunk, strlen($chunk)); - } - fclose($input); - fclose($output); - $boxData["tmp_name"] = $destName; - $this->storeFileToCopy($boxData); - AJXP_Logger::debug("End reading INPUT stream"); - }catch (Exception $e){ - $errorCode=411; - $errorMessage = $e->getMessage(); - break; - } - }else{ - $destName = $destCopy."/".basename($boxData["tmp_name"]); - if ($destName == $boxData["tmp_name"]) $destName .= "1"; - if(move_uploaded_file($boxData["tmp_name"], $destName)){ - $boxData["tmp_name"] = $destName; - $this->storeFileToCopy($boxData); - }else{ - $mess = ConfService::getMessages(); - $errorCode = 411; - $errorMessage="$mess[33] ".$boxData["name"]; - break; - } - } - } - if(isSet($errorMessage)){ - AJXP_Logger::debug("Return error $errorCode $errorMessage"); - return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $errorMessage)); - }else{ - AJXP_Logger::debug("Return success"); - return array("SUCCESS" => true, "PREVENT_NOTIF" => true); - } - - break; - default: - break; - } - session_write_close(); - exit; + $boxData["destination"] = base64_encode($rep_source); + $destCopy = AJXP_XMLWriter::replaceAjxpXmlKeywords($this->repository->getOption("TMP_UPLOAD")); + AJXP_Logger::debug("Upload : tmp upload folder", array($destCopy)); + if (!is_dir($destCopy)) { + if (! @mkdir($destCopy)) { + AJXP_Logger::debug("Upload error : cannot create temporary folder", array($destCopy)); + $errorCode = 413; + $errorMessage = "Warning, cannot create folder for temporary copy."; + break; + } + } + if (!$this->isWriteable($destCopy)) { + AJXP_Logger::debug("Upload error: cannot write into temporary folder"); + $errorCode = 414; + $errorMessage = "Warning, cannot write into temporary folder."; + break; + } + AJXP_Logger::debug("Upload : tmp upload folder", array($destCopy)); + if (isSet($boxData["input_upload"])) { + try { + $destName = tempnam($destCopy, ""); + AJXP_Logger::debug("Begining reading INPUT stream"); + $input = fopen("php://input", "r"); + $output = fopen($destName, "w"); + $sizeRead = 0; + while ($sizeRead < intval($boxData["size"])) { + $chunk = fread($input, 4096); + $sizeRead += strlen($chunk); + fwrite($output, $chunk, strlen($chunk)); + } + fclose($input); + fclose($output); + $boxData["tmp_name"] = $destName; + $this->storeFileToCopy($boxData); + AJXP_Logger::debug("End reading INPUT stream"); + } catch (Exception $e) { + $errorCode=411; + $errorMessage = $e->getMessage(); + break; + } + } else { + $destName = $destCopy."/".basename($boxData["tmp_name"]); + if ($destName == $boxData["tmp_name"]) $destName .= "1"; + if (move_uploaded_file($boxData["tmp_name"], $destName)) { + $boxData["tmp_name"] = $destName; + $this->storeFileToCopy($boxData); + } else { + $mess = ConfService::getMessages(); + $errorCode = 411; + $errorMessage="$mess[33] ".$boxData["name"]; + break; + } + } + } + if (isSet($errorMessage)) { + AJXP_Logger::debug("Return error $errorCode $errorMessage"); + return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $errorMessage)); + } else { + AJXP_Logger::debug("Return success"); + return array("SUCCESS" => true, "PREVENT_NOTIF" => true); + } - } + break; + default: + break; + } + session_write_close(); + exit; - public function isWriteable($path, $type="dir"){ - - $parts = parse_url($path); - $dir = $parts["path"]; - if($type == "dir" && ($dir == "" || $dir == "/" || $dir == "\\")){ // ROOT, WE ARE NOT SURE TO BE ABLE TO READ THE PARENT - return true; - }else{ - return is_writable($path); - } - - } - - function deldir($location) - { - if(is_dir($location)) - { - $dirsToRecurse = array(); - $all=opendir($location); - while ($file=readdir($all)) - { - if (is_dir("$location/$file") && $file !=".." && $file!=".") - { - $dirsToRecurse[] = "$location/$file"; - } - elseif (!is_dir("$location/$file")) - { - if(file_exists("$location/$file")){ - unlink("$location/$file"); - } - unset($file); - } - } - closedir($all); - foreach ($dirsToRecurse as $recurse){ - $this->deldir($recurse); - } - rmdir($location); - } - else - { - if(file_exists("$location")) { - $test = @unlink("$location"); - if(!$test) throw new Exception("Cannot delete file ".$location); - } - } - if(basename(dirname($location)) == $this->repository->getOption("RECYCLE_BIN")) - { - // DELETING FROM RECYCLE - RecycleBinManager::deleteFromRecycle($location); - } - } - - - function storeFileToCopy($fileData){ + } + + public function isWriteable($path, $type="dir") + { + $parts = parse_url($path); + $dir = $parts["path"]; + if ($type == "dir" && ($dir == "" || $dir == "/" || $dir == "\\")) { // ROOT, WE ARE NOT SURE TO BE ABLE TO READ THE PARENT + return true; + } else { + return is_writable($path); + } + + } + + public function deldir($location) + { + if (is_dir($location)) { + $dirsToRecurse = array(); + $all=opendir($location); + while ($file=readdir($all)) { + if (is_dir("$location/$file") && $file !=".." && $file!=".") { + $dirsToRecurse[] = "$location/$file"; + } elseif (!is_dir("$location/$file")) { + if (file_exists("$location/$file")) { + unlink("$location/$file"); + } + unset($file); + } + } + closedir($all); + foreach ($dirsToRecurse as $recurse) { + $this->deldir($recurse); + } + rmdir($location); + } else { + if (file_exists("$location")) { + $test = @unlink("$location"); + if(!$test) throw new Exception("Cannot delete file ".$location); + } + } + if (basename(dirname($location)) == $this->repository->getOption("RECYCLE_BIN")) { + // DELETING FROM RECYCLE + RecycleBinManager::deleteFromRecycle($location); + } + } + + + public function storeFileToCopy($fileData) + { $user = AuthService::getLoggedUser(); $files = $user->getTemporaryData("tmp_upload"); AJXP_Logger::debug("Saving user temporary data", array($fileData)); @@ -277,13 +272,15 @@ function storeFileToCopy($fileData){ } } - function getFileNameToCopy(){ + public function getFileNameToCopy() + { $user = AuthService::getLoggedUser(); $files = $user->getTemporaryData("tmp_upload"); return $files[0]["name"]; } - function getNextFileToCopy(){ + public function getNextFileToCopy() + { if(!$this->hasFilesToCopy()) return ""; $user = AuthService::getLoggedUser(); $files = $user->getTemporaryData("tmp_upload"); @@ -293,31 +290,32 @@ function getNextFileToCopy(){ return $fData; } - function hasFilesToCopy(){ + public function hasFilesToCopy() + { $user = AuthService::getLoggedUser(); $files = $user->getTemporaryData("tmp_upload"); return (count($files)?true:false); } - function testParameters($params){ - if(empty($params["FTP_USER"])){ + public function testParameters($params) + { + if (empty($params["FTP_USER"])) { throw new AJXP_Exception("Even if you intend to use the credentials stored in the session, temporarily set a user and password to perform the connexion test."); } - if($params["FTP_SECURE"]){ + if ($params["FTP_SECURE"]) { $link = @ftp_ssl_connect($params["FTP_HOST"], $params["FTP_PORT"]); - }else{ + } else { $link = @ftp_connect($params["FTP_HOST"], $params["FTP_PORT"]); } - if(!$link) { + if (!$link) { throw new AJXP_Exception("Cannot connect to FTP server (".$params["FTP_HOST"].",". $params["FTP_PORT"].")"); } @ftp_set_option($link, FTP_TIMEOUT_SEC, 10); - if(!@ftp_login($link,$params["FTP_USER"],$params["FTP_PASS"])){ + if (!@ftp_login($link,$params["FTP_USER"],$params["FTP_PASS"])) { ftp_close($link); throw new AJXP_Exception("Cannot login to FTP server with user ".$params["FTP_USER"]); } - if (!$params["FTP_DIRECT"]) - { + if (!$params["FTP_DIRECT"]) { @ftp_pasv($link, true); global $_SESSION; $_SESSION["ftpPasv"]="true"; @@ -327,5 +325,5 @@ function testParameters($params){ return "SUCCESS: Could succesfully connect to the FTP server with user '".$params["FTP_USER"]."'."; } - -} \ No newline at end of file + +} diff --git a/core/src/plugins/access.ftp/class.ftpAccessWrapper.php b/core/src/plugins/access.ftp/class.ftpAccessWrapper.php index 1bf6a9d154..55aa35b31d 100644 --- a/core/src/plugins/access.ftp/class.ftpAccessWrapper.php +++ b/core/src/plugins/access.ftp/class.ftpAccessWrapper.php @@ -28,116 +28,128 @@ * @package AjaXplorer_Plugins * @subpackage Access */ -class ftpAccessWrapper implements AjxpWrapper { - - // Instance vars $this-> - protected $host; - protected $port; - protected $secure; - protected $path; - protected $user; - protected $password; - protected $ftpActive; - protected $repoCharset; - protected $repositoryId; - protected $fp; - - protected $crtMode; - protected $crtLink; - protected $crtTarget; - - // Shared vars self:: - private static $dirContentLoopPath; - private static $dirContent; - private static $dirContentKeys; - private static $dirContentIndex; +class ftpAccessWrapper implements AjxpWrapper +{ + // Instance vars $this-> + protected $host; + protected $port; + protected $secure; + protected $path; + protected $user; + protected $password; + protected $ftpActive; + protected $repoCharset; + protected $repositoryId; + protected $fp; + + protected $crtMode; + protected $crtLink; + protected $crtTarget; + + // Shared vars self:: + private static $dirContentLoopPath; + private static $dirContent; + private static $dirContentKeys; + private static $dirContentIndex; private $monthes = array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Juil", "Aug", "Sep", "Oct", "Nov", "Dec"); - public static function getRealFSReference($path, $persistent = false){ - $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()); - $tmpHandle = fopen($tmpFile, "wb"); - self::copyFileInStream($path, $tmpHandle); - fclose($tmpHandle); - if(!$persistent){ - register_shutdown_function(array("AJXP_Utils", "silentUnlink"), $tmpFile); - } - return $tmpFile; + public static function getRealFSReference($path, $persistent = false) + { + $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()); + $tmpHandle = fopen($tmpFile, "wb"); + self::copyFileInStream($path, $tmpHandle); + fclose($tmpHandle); + if (!$persistent) { + register_shutdown_function(array("AJXP_Utils", "silentUnlink"), $tmpFile); + } + return $tmpFile; } - public static function isRemote(){ - return true; + public static function isRemote() + { + return true; } - public static function copyFileInStream($path, $stream){ - $fake = new ftpAccessWrapper(); - $parts = $fake->parseUrl($path); - $link = $fake->createFTPLink(); - $serverPath = AJXP_Utils::securePath($fake->path."/".$parts["path"]); - AJXP_Logger::debug($serverPath); - ftp_fget($link, $stream, $serverPath, FTP_BINARY); + public static function copyFileInStream($path, $stream) + { + $fake = new ftpAccessWrapper(); + $parts = $fake->parseUrl($path); + $link = $fake->createFTPLink(); + $serverPath = AJXP_Utils::securePath($fake->path."/".$parts["path"]); + AJXP_Logger::debug($serverPath); + ftp_fget($link, $stream, $serverPath, FTP_BINARY); } - public static function changeMode($path, $chmodValue){ - $fake = new ftpAccessWrapper(); - $parts = $fake->parseUrl($path); - $link = $fake->createFTPLink(); - $serverPath = AJXP_Utils::securePath($fake->path."/".$parts["path"]); - ftp_chmod($link, $chmodValue, $serverPath); + public static function changeMode($path, $chmodValue) + { + $fake = new ftpAccessWrapper(); + $parts = $fake->parseUrl($path); + $link = $fake->createFTPLink(); + $serverPath = AJXP_Utils::securePath($fake->path."/".$parts["path"]); + ftp_chmod($link, $chmodValue, $serverPath); } - public function stream_open($url, $mode, $options, &$context){ - if(stripos($mode, "w") !== false){ - $this->crtMode = 'write'; - $parts = $this->parseUrl($url); - $this->crtTarget = AJXP_Utils::securePath($this->path."/".$parts["path"]); - $this->crtLink = $this->createFTPLink(); - $this->fp = tmpfile(); - }else{ - $this->crtMode = 'read'; - $this->fp = tmpfile(); - $this->copyFileInStream($url, $this->fp); - rewind($this->fp); - } - /* - if($context){ - $this->fp = @fopen($this->buildRealUrl($url), $mode, $options, $context); - }else{ - $this->fp = @fopen($this->buildRealUrl($url), $mode); - } - */ - return ($this->fp !== false); - } + public function stream_open($url, $mode, $options, &$context) + { + if (stripos($mode, "w") !== false) { + $this->crtMode = 'write'; + $parts = $this->parseUrl($url); + $this->crtTarget = AJXP_Utils::securePath($this->path."/".$parts["path"]); + $this->crtLink = $this->createFTPLink(); + $this->fp = tmpfile(); + } else { + $this->crtMode = 'read'; + $this->fp = tmpfile(); + $this->copyFileInStream($url, $this->fp); + rewind($this->fp); + } + /* + if ($context) { + $this->fp = @fopen($this->buildRealUrl($url), $mode, $options, $context); + } else { + $this->fp = @fopen($this->buildRealUrl($url), $mode); + } + */ + return ($this->fp !== false); + } - public function stream_stat(){ - return fstat($this->fp); + public function stream_stat() + { + return fstat($this->fp); } - public function stream_seek($offset , $whence = SEEK_SET){ - fseek($this->fp, $offset, SEEK_SET); + public function stream_seek($offset , $whence = SEEK_SET) + { + fseek($this->fp, $offset, SEEK_SET); } - public function stream_tell(){ - return ftell($this->fp); + public function stream_tell() + { + return ftell($this->fp); } - public function stream_read($count){ - return fread($this->fp, $count); + public function stream_read($count) + { + return fread($this->fp, $count); } - public function stream_write($data){ - fwrite($this->fp, $data, strlen($data)); + public function stream_write($data) + { + fwrite($this->fp, $data, strlen($data)); return strlen($data); } - public function stream_eof(){ - return feof($this->fp); + public function stream_eof() + { + return feof($this->fp); } - public function stream_close(){ - if(isSet($this->fp) && $this->fp!=-1 && $this->fp!==false){ - fclose($this->fp); - } + public function stream_close() + { + if (isSet($this->fp) && $this->fp!=-1 && $this->fp!==false) { + fclose($this->fp); + } } // PHP bug #62035 @@ -148,198 +160,203 @@ public static function fput_quota_hack($errno, $errstr, $errfile, $errline, $err AJXP_XMLWriter::catchError($errno, $errstr, $errfile, $errline, $errcontext); } - public function stream_flush(){ - if(isSet($this->fp) && $this->fp!=-1 && $this->fp!==false){ - if($this->crtMode == 'write'){ - rewind($this->fp); - AJXP_Logger::debug("Ftp_fput", array("target"=>$this->crtTarget)); - set_error_handler(array("ftpAccessWrapper", "fput_quota_hack"), E_ALL & ~E_NOTICE ); - ftp_fput($this->crtLink, $this->crtTarget, $this->fp, FTP_BINARY); - restore_error_handler(); - AJXP_Logger::debug("Ftp_fput end", array("target"=>$this->crtTarget)); - }else{ - fflush($this->fp); - } - } - } - - public function unlink($url){ - return unlink($this->buildRealUrl($url)); - } - - public function rmdir($url, $options){ - return rmdir($this->buildRealUrl($url)); - } - - public function mkdir($url, $mode, $options){ - return mkdir($this->buildRealUrl($url), $mode); - } - - public function rename($from, $to){ - return rename($this->buildRealUrl($from), $this->buildRealUrl($to)); - } - - public function url_stat($path, $flags){ - // We are in an opendir loop - AJXP_Logger::debug("URL_STAT", $path); - if(self::$dirContent != null && self::$dirContentLoopPath == $this->safeDirname($path)){ - $search = $this->safeBasename($path); - //if($search == "") $search = "."; - if(array_key_exists($search, self::$dirContent)){ - return self::$dirContent[$search]; - } - } - $parts = $this->parseUrl($path); - $link = $this->createFTPLink(); - $serverPath = AJXP_Utils::securePath($this->path."/".$parts["path"]); - if($parts["path"] == "/"){ - $basename = "."; - }else{ - $basename = $this->safeBasename($serverPath); - } - - $serverParent = $this->safeDirname($parts["path"]); - $serverParent = AJXP_Utils::securePath($this->path."/".$serverParent); - - $testCd = @ftp_chdir($link, $serverPath); - if($testCd === true){ - // DIR - $contents = $this->rawList($link, $serverParent, 'd'); - foreach ($contents as $entry){ - $res = $this->rawListEntryToStat($entry); - AJXP_Logger::debug("RAWLISTENTRY ".$res["name"]. " (searching ".$basename.")", $res["stat"]); - if($res["name"] == $basename){ - AbstractAccessDriver::fixPermissions($res["stat"], ConfService::getRepositoryById($this->repositoryId), array($this, "getRemoteUserId")); - $statValue = $res["stat"]; - return $statValue; - } - } - }else{ - // FILE - $contents = $this->rawList($link, $serverPath, 'f'); - if(count($contents) == 1){ - $res = $this->rawListEntryToStat($contents[0]); - AbstractAccessDriver::fixPermissions($res["stat"], ConfService::getRepositoryById($this->repositoryId), array($this, "getRemoteUserId")); - $statValue = $res["stat"]; - AJXP_Logger::debug("STAT FILE $serverPath", $statValue); - return $statValue; - } - } - return null; - } - - public function dir_opendir ($url , $options ){ - $parts = $this->parseUrl($url); - $link = $this->createFTPLink(); - $serverPath = AJXP_Utils::securePath($this->path."/".$parts["path"]); - $contents = $this->rawList($link, $serverPath); + public function stream_flush() + { + if (isSet($this->fp) && $this->fp!=-1 && $this->fp!==false) { + if ($this->crtMode == 'write') { + rewind($this->fp); + AJXP_Logger::debug("Ftp_fput", array("target"=>$this->crtTarget)); + set_error_handler(array("ftpAccessWrapper", "fput_quota_hack"), E_ALL & ~E_NOTICE ); + ftp_fput($this->crtLink, $this->crtTarget, $this->fp, FTP_BINARY); + restore_error_handler(); + AJXP_Logger::debug("Ftp_fput end", array("target"=>$this->crtTarget)); + } else { + fflush($this->fp); + } + } + } + + public function unlink($url) + { + return unlink($this->buildRealUrl($url)); + } + + public function rmdir($url, $options) + { + return rmdir($this->buildRealUrl($url)); + } + + public function mkdir($url, $mode, $options) + { + return mkdir($this->buildRealUrl($url), $mode); + } + + public function rename($from, $to) + { + return rename($this->buildRealUrl($from), $this->buildRealUrl($to)); + } + + public function url_stat($path, $flags) + { + // We are in an opendir loop + AJXP_Logger::debug("URL_STAT", $path); + if (self::$dirContent != null && self::$dirContentLoopPath == $this->safeDirname($path)) { + $search = $this->safeBasename($path); + //if($search == "") $search = "."; + if (array_key_exists($search, self::$dirContent)) { + return self::$dirContent[$search]; + } + } + $parts = $this->parseUrl($path); + $link = $this->createFTPLink(); + $serverPath = AJXP_Utils::securePath($this->path."/".$parts["path"]); + if ($parts["path"] == "/") { + $basename = "."; + } else { + $basename = $this->safeBasename($serverPath); + } + + $serverParent = $this->safeDirname($parts["path"]); + $serverParent = AJXP_Utils::securePath($this->path."/".$serverParent); + + $testCd = @ftp_chdir($link, $serverPath); + if ($testCd === true) { + // DIR + $contents = $this->rawList($link, $serverParent, 'd'); + foreach ($contents as $entry) { + $res = $this->rawListEntryToStat($entry); + AJXP_Logger::debug("RAWLISTENTRY ".$res["name"]. " (searching ".$basename.")", $res["stat"]); + if ($res["name"] == $basename) { + AbstractAccessDriver::fixPermissions($res["stat"], ConfService::getRepositoryById($this->repositoryId), array($this, "getRemoteUserId")); + $statValue = $res["stat"]; + return $statValue; + } + } + } else { + // FILE + $contents = $this->rawList($link, $serverPath, 'f'); + if (count($contents) == 1) { + $res = $this->rawListEntryToStat($contents[0]); + AbstractAccessDriver::fixPermissions($res["stat"], ConfService::getRepositoryById($this->repositoryId), array($this, "getRemoteUserId")); + $statValue = $res["stat"]; + AJXP_Logger::debug("STAT FILE $serverPath", $statValue); + return $statValue; + } + } + return null; + } + + public function dir_opendir ($url , $options ) + { + $parts = $this->parseUrl($url); + $link = $this->createFTPLink(); + $serverPath = AJXP_Utils::securePath($this->path."/".$parts["path"]); + $contents = $this->rawList($link, $serverPath); $folders = $files = array(); - foreach($contents as $entry) - { - $result = $this->rawListEntryToStat($entry); + foreach ($contents as $entry) { + $result = $this->rawListEntryToStat($entry); AbstractAccessDriver::fixPermissions($result["stat"], ConfService::getRepositoryById($this->repositoryId), array($this, "getRemoteUserId")); - $isDir = $result["dir"]; - $statValue = $result["stat"]; - $file = $result["name"]; - if($isDir){ - $folders[$file] = $statValue; - }else{ - $files[$file] = $statValue; - } - } - // Append all files keys to folders. Do not use array_merge. - foreach ($files as $key => $value){ - $folders[$key] = $value; - } - AJXP_Logger::debug("OPENDIR ", $folders); + $isDir = $result["dir"]; + $statValue = $result["stat"]; + $file = $result["name"]; + if ($isDir) { + $folders[$file] = $statValue; + } else { + $files[$file] = $statValue; + } + } + // Append all files keys to folders. Do not use array_merge. + foreach ($files as $key => $value) { + $folders[$key] = $value; + } + AJXP_Logger::debug("OPENDIR ", $folders); self::$dirContentLoopPath = $this->safeDirname($url); - self::$dirContent = $folders;//array_merge($folders, $files); - self::$dirContentKeys = array_keys(self::$dirContent); - self::$dirContentIndex = 0; - return true; - } - - public function dir_closedir (){ - AJXP_Logger::debug("CLOSEDIR"); - self::$dirContent = null; - self::$dirContentKeys = null; + self::$dirContent = $folders;//array_merge($folders, $files); + self::$dirContentKeys = array_keys(self::$dirContent); + self::$dirContentIndex = 0; + return true; + } + + public function dir_closedir () + { + AJXP_Logger::debug("CLOSEDIR"); + self::$dirContent = null; + self::$dirContentKeys = null; self::$dirContentLoopPath = null; - self::$dirContentIndex = 0; - } - - public function dir_readdir (){ - self::$dirContentIndex ++; - if(isSet(self::$dirContentKeys[self::$dirContentIndex-1])){ - return self::$dirContentKeys[self::$dirContentIndex-1]; - }else{ - return false; - } - } - - public function dir_rewinddir (){ - self::$dirContentIndex = 0; - } - - protected function rawList($link, $serverPath, $target = 'd', $retry = true){ - - if ($target == 'f') - { - $parentDir = $this->safeDirname($serverPath); - $fileName = $this->safeBasename($serverPath); - ftp_chdir($link, $parentDir); - $rl_dirlist = @ftp_rawlist($link, "-a ."); - //AJXP_Logger::debug("FILE RAWLIST FROM ".$parentDir); - if (is_array($rl_dirlist)){ + self::$dirContentIndex = 0; + } + + public function dir_readdir () + { + self::$dirContentIndex ++; + if (isSet(self::$dirContentKeys[self::$dirContentIndex-1])) { + return self::$dirContentKeys[self::$dirContentIndex-1]; + } else { + return false; + } + } + + public function dir_rewinddir () + { + self::$dirContentIndex = 0; + } + + protected function rawList($link, $serverPath, $target = 'd', $retry = true) + { + if ($target == 'f') { + $parentDir = $this->safeDirname($serverPath); + $fileName = $this->safeBasename($serverPath); + ftp_chdir($link, $parentDir); + $rl_dirlist = @ftp_rawlist($link, "-a ."); + //AJXP_Logger::debug("FILE RAWLIST FROM ".$parentDir); + if (is_array($rl_dirlist)) { $escaped = preg_quote($fileName); - foreach($rl_dirlist as $rl_index => $rl_entry){ - if (preg_match("/ $escaped$/" , $rl_entry)){ - $contents = array($rl_dirlist[$rl_index]); - } - } - } - } - else - { - ftp_chdir($link, $serverPath); - $contents = ftp_rawlist($link, "-a ."); - //AJXP_Logger::debug("RAW LIST RESULT ".print_r($contents, true)); - } - - if (!is_array($contents) && !$this->ftpActive) - { - if($retry == false){ - return array(); - } + foreach ($rl_dirlist as $rl_index => $rl_entry) { + if (preg_match("/ $escaped$/" , $rl_entry)) { + $contents = array($rl_dirlist[$rl_index]); + } + } + } + } else { + ftp_chdir($link, $serverPath); + $contents = ftp_rawlist($link, "-a ."); + //AJXP_Logger::debug("RAW LIST RESULT ".print_r($contents, true)); + } + + if (!is_array($contents) && !$this->ftpActive) { + if ($retry == false) { + return array(); + } // We might have timed out, so let's go passive if not done yet global $_SESSION; - if ($_SESSION["ftpPasv"] == "true"){ - return array(); + if ($_SESSION["ftpPasv"] == "true") { + return array(); } @ftp_pasv($link, TRUE); $_SESSION["ftpPasv"]="true"; - // RETRY! - return $this->rawList($link, $serverPath, $target, FALSE); + // RETRY! + return $this->rawList($link, $serverPath, $target, FALSE); } - if(!is_array($contents)){ - return array(); + if (!is_array($contents)) { + return array(); } - return $contents; - } - - protected function rawListEntryToStat($entry, $filterStatPerms = false) + return $contents; + } + + protected function rawListEntryToStat($entry, $filterStatPerms = false) { $info = array(); $monthes = array_flip( $this->monthes ); - $vinfo = preg_split("/[\s]+/", $entry); - AJXP_Logger::debug("RAW LIST", $entry); - $statValue = array(); - if ($vinfo[0] !== "total"){ + $vinfo = preg_split("/[\s]+/", $entry); + AJXP_Logger::debug("RAW LIST", $entry); + $statValue = array(); + if ($vinfo[0] !== "total") { $fileperms = $vinfo[0]; $info['num'] = $vinfo[1]; $info['owner'] = $vinfo[2]; $info['groups'] = array(); $i = 3; - while(true){ + while (true) { $info['groups'][] = $vinfo[$i]; $i++; // Detect "Size" and "Month" @@ -348,116 +365,117 @@ protected function rawListEntryToStat($entry, $filterStatPerms = false) $info['group'] = implode(" ", $info["groups"]); $info['size'] = $vinfo[$i]; $i++; $info['month'] = $vinfo[$i]; $i++; - $info['day'] = $vinfo[$i]; $i++; - $info['timeOrYear'] = $vinfo[$i]; $i++; - //$info['name'] = $vinfo[$i]; $i++; - } + $info['day'] = $vinfo[$i]; $i++; + $info['timeOrYear'] = $vinfo[$i]; $i++; + //$info['name'] = $vinfo[$i]; $i++; + } $resplit = preg_split("/[\s]+/", $entry, 8 + count($info["groups"])); - $file = trim(array_pop($resplit)); - $statValue[7] = $statValue["size"] = trim($info['size']); - if(strstr($info["timeOrYear"], ":")){ - $info["time"] = $info["timeOrYear"]; + $file = trim(array_pop($resplit)); + $statValue[7] = $statValue["size"] = trim($info['size']); + if (strstr($info["timeOrYear"], ":")) { + $info["time"] = $info["timeOrYear"]; $monthKey = $monthes[$info['month']] + 1; - if(intval(date('m')) < $monthKey){ + if (intval(date('m')) < $monthKey) { $info['year'] = date("Y") -1; - }else{ + } else { $info["year"] = date("Y"); } - }else{ - $info["time"] = '09:00'; - $info["year"] = $info["timeOrYear"]; - } - $statValue[4] = $statValue["uid"] = $info["owner"]; - $statValue[5] = $statValue["gid"] = $info["group"]; - $filedate = trim($info['day'])." ".trim($info['month'])." ".trim($info['year'])." ".trim($info['time']); - $statValue[9] = $statValue["mtime"] = strtotime($filedate); - - $isDir = false; - if (strpos($fileperms,"d")!==FALSE || strpos($fileperms,"l")!==FALSE) - { - if(strpos($fileperms,"l")!==FALSE) - { - $test=explode(" ->", $file); - $file=$test[0]; - } - $isDir = true; - } - $boolIsDir = $isDir; - $statValue[2] = $statValue["mode"] = $this->convertingChmod($fileperms); - $statValue["ftp_perms"] = $fileperms; - return array("name"=>$file, "stat"=>$statValue, "dir"=>$isDir); - } - - protected function parseUrl($url, $forceLogin = false){ - // URL MAY BE ajxp.ftp://username:password@host/path - $urlParts = parse_url($url); - $this->repositoryId = $urlParts["host"]; - $repository = ConfService::getRepositoryById($this->repositoryId); - if($repository == null){ + } else { + $info["time"] = '09:00'; + $info["year"] = $info["timeOrYear"]; + } + $statValue[4] = $statValue["uid"] = $info["owner"]; + $statValue[5] = $statValue["gid"] = $info["group"]; + $filedate = trim($info['day'])." ".trim($info['month'])." ".trim($info['year'])." ".trim($info['time']); + $statValue[9] = $statValue["mtime"] = strtotime($filedate); + + $isDir = false; + if (strpos($fileperms,"d")!==FALSE || strpos($fileperms,"l")!==FALSE) { + if (strpos($fileperms,"l")!==FALSE) { + $test=explode(" ->", $file); + $file=$test[0]; + } + $isDir = true; + } + $boolIsDir = $isDir; + $statValue[2] = $statValue["mode"] = $this->convertingChmod($fileperms); + $statValue["ftp_perms"] = $fileperms; + return array("name"=>$file, "stat"=>$statValue, "dir"=>$isDir); + } + + protected function parseUrl($url, $forceLogin = false) + { + // URL MAY BE ajxp.ftp://username:password@host/path + $urlParts = parse_url($url); + $this->repositoryId = $urlParts["host"]; + $repository = ConfService::getRepositoryById($this->repositoryId); + if ($repository == null) { throw new Exception("Cannot find repository for dynamic ftp authentification."); } - $credentials = AJXP_Safe::tryLoadingCredentialsFromSources($urlParts, $repository); - $this->user = $credentials["user"]; - $this->password = $credentials["password"]; - if($this->user==""){ - throw new AJXP_Exception("Cannot find user/pass for FTP access!"); - } - if($repository->getOption("DYNAMIC_FTP") == "TRUE" && isSet($_SESSION["AJXP_DYNAMIC_FTP_DATA"])){ - $data = $_SESSION["AJXP_DYNAMIC_FTP_DATA"]; - $this->host = $data["FTP_HOST"]; - $this->path = $data["PATH"]; - $this->secure = ($data["FTP_SECURE"] == "TRUE"?true:false); - $this->port = ($data["FTP_PORT"]!=""?intval($data["FTP_PORT"]):($this->secure?22:21)); - $this->ftpActive = ($data["FTP_DIRECT"] == "TRUE"?true:false); - $this->repoCharset = $data["CHARSET"]; - }else{ - $this->host = $repository->getOption("FTP_HOST"); - $this->path = $repository->getOption("PATH"); - $this->secure = ($repository->getOption("FTP_SECURE") == "TRUE"?true:false); - $this->port = ($repository->getOption("FTP_PORT")!=""?intval($repository->getOption("FTP_PORT")):($this->secure?22:21)); - $this->ftpActive = ($repository->getOption("FTP_DIRECT") == "TRUE"?true:false); - $this->repoCharset = $repository->getOption("CHARSET"); - } - - // Test Connexion and server features + $credentials = AJXP_Safe::tryLoadingCredentialsFromSources($urlParts, $repository); + $this->user = $credentials["user"]; + $this->password = $credentials["password"]; + if ($this->user=="") { + throw new AJXP_Exception("Cannot find user/pass for FTP access!"); + } + if ($repository->getOption("DYNAMIC_FTP") == "TRUE" && isSet($_SESSION["AJXP_DYNAMIC_FTP_DATA"])) { + $data = $_SESSION["AJXP_DYNAMIC_FTP_DATA"]; + $this->host = $data["FTP_HOST"]; + $this->path = $data["PATH"]; + $this->secure = ($data["FTP_SECURE"] == "TRUE"?true:false); + $this->port = ($data["FTP_PORT"]!=""?intval($data["FTP_PORT"]):($this->secure?22:21)); + $this->ftpActive = ($data["FTP_DIRECT"] == "TRUE"?true:false); + $this->repoCharset = $data["CHARSET"]; + } else { + $this->host = $repository->getOption("FTP_HOST"); + $this->path = $repository->getOption("PATH"); + $this->secure = ($repository->getOption("FTP_SECURE") == "TRUE"?true:false); + $this->port = ($repository->getOption("FTP_PORT")!=""?intval($repository->getOption("FTP_PORT")):($this->secure?22:21)); + $this->ftpActive = ($repository->getOption("FTP_DIRECT") == "TRUE"?true:false); + $this->repoCharset = $repository->getOption("CHARSET"); + } + + // Test Connexion and server features global $_SESSION; $cacheKey = $repository->getId()."_ftpCharset"; - if (!isset($_SESSION[$cacheKey]) || !strlen($_SESSION[$cacheKey]) || $forceLogin) - { + if (!isset($_SESSION[$cacheKey]) || !strlen($_SESSION[$cacheKey]) || $forceLogin) { $features = $this->getServerFeatures(); if(!isSet($_SESSION["AJXP_CHARSET"]) || $_SESSION["AJXP_CHARSET"] == "") $_SESSION["AJXP_CHARSET"] = $features["charset"]; $_SESSION[$cacheKey] = $_SESSION["AJXP_CHARSET"]; } return $urlParts; - } - - public function getRemoteUserId(){ - return array($this->user, "-1"); - } - - protected function buildRealUrl($url){ - if(!isSet($this->user)){ - $parts = $this->parseUrl($url); - }else{ - // parseUrl already called before (rename case). - $parts = parse_url($url); - } - $serverPath = AJXP_Utils::securePath("/$this->path/".$parts["path"]); - return "ftp".($this->secure?"s":"")."://$this->user:$this->password@$this->host:$this->port".$serverPath; - } + } + + public function getRemoteUserId() + { + return array($this->user, "-1"); + } + + protected function buildRealUrl($url) + { + if (!isSet($this->user)) { + $parts = $this->parseUrl($url); + } else { + // parseUrl already called before (rename case). + $parts = parse_url($url); + } + $serverPath = AJXP_Utils::securePath("/$this->path/".$parts["path"]); + return "ftp".($this->secure?"s":"")."://$this->user:$this->password@$this->host:$this->port".$serverPath; + } /** This method retrieves the FTP server features as described in RFC2389 * A decent FTP server support MLST command to list file using UTF-8 encoding * @return an array of features (see code) - */ - protected function getServerFeatures(){ - $link = $this->createFTPLink(); + */ + protected function getServerFeatures() + { + $link = $this->createFTPLink(); - if(ConfService::getRepositoryById($this->repositoryId)->getOption("CREATE") == true){ + if (ConfService::getRepositoryById($this->repositoryId)->getOption("CREATE") == true) { // Test if root exists and create it otherwise $serverPath = AJXP_Utils::securePath($this->path."/"); $testCd = @ftp_chdir($link, $serverPath); - if($testCd !== true){ + if ($testCd !== true) { $res = @ftp_mkdir($link, $serverPath); if(!$res) throw new Exception("Cannot create path on remote server!"); } @@ -465,18 +483,16 @@ protected function getServerFeatures(){ $features = @ftp_raw($link, "FEAT"); // Check the answer code - if (isSet($features[0]) && $features[0][0] != "2"){ - //ftp_close($link); - return array("list"=>"LIST", "charset"=>$this->repoCharset); + if (isSet($features[0]) && $features[0][0] != "2") { + //ftp_close($link); + return array("list"=>"LIST", "charset"=>$this->repoCharset); } $retArray = array("list"=>"LIST", "charset"=>$this->repoCharset); // Ok, find out the encoding used - foreach($features as $feature) - { - if (strstr($feature, "UTF8") !== FALSE) - { // See http://wiki.filezilla-project.org/Character_Set for an explaination + foreach ($features as $feature) { + if (strstr($feature, "UTF8") !== FALSE) { // See http://wiki.filezilla-project.org/Character_Set for an explaination @ftp_raw($link, "OPTS UTF-8 ON"); - $retArray['charset'] = "UTF-8"; + $retArray['charset'] = "UTF-8"; //ftp_close($link); return $retArray; } @@ -485,83 +501,83 @@ protected function getServerFeatures(){ return $retArray; } - protected function createFTPLink(){ - - // If connexion exist and is still connected - if(is_array($_SESSION["FTP_CONNEXIONS"]) - && array_key_exists($this->repositoryId, $_SESSION["FTP_CONNEXIONS"]) - && @ftp_systype($_SESSION["FTP_CONNEXIONS"][$this->repositoryId])){ - AJXP_Logger::debug("Using stored FTP Session"); - return $_SESSION["FTP_CONNEXIONS"][$this->repositoryId]; - } - AJXP_Logger::debug("Creating new FTP Session"); - $link = FALSE; - //Connects to the FTP. - if($this->secure){ - $link = @ftp_ssl_connect($this->host, $this->port); - }else{ - $link = @ftp_connect($this->host, $this->port); - } - if(!$link) { - throw new AJXP_Exception("Cannot connect to FTP server ($this->host, $this->port)"); - } - //register_shutdown_function('ftp_close', $link); + protected function createFTPLink() + { + // If connexion exist and is still connected + if(is_array($_SESSION["FTP_CONNEXIONS"]) + && array_key_exists($this->repositoryId, $_SESSION["FTP_CONNEXIONS"]) + && @ftp_systype($_SESSION["FTP_CONNEXIONS"][$this->repositoryId])){ + AJXP_Logger::debug("Using stored FTP Session"); + return $_SESSION["FTP_CONNEXIONS"][$this->repositoryId]; + } + AJXP_Logger::debug("Creating new FTP Session"); + $link = FALSE; + //Connects to the FTP. + if ($this->secure) { + $link = @ftp_ssl_connect($this->host, $this->port); + } else { + $link = @ftp_connect($this->host, $this->port); + } + if (!$link) { + throw new AJXP_Exception("Cannot connect to FTP server ($this->host, $this->port)"); + } + //register_shutdown_function('ftp_close', $link); @ftp_set_option($link, FTP_TIMEOUT_SEC, 10); - if(!@ftp_login($link,$this->user,$this->password)){ + if (!@ftp_login($link,$this->user,$this->password)) { throw new AJXP_Exception("Cannot login to FTP server with user $this->user"); } - if (!$this->ftpActive) - { + if (!$this->ftpActive) { @ftp_pasv($link, true); global $_SESSION; $_SESSION["ftpPasv"]="true"; } - if(!is_array($_SESSION["FTP_CONNEXIONS"])){ - $_SESSION["FTP_CONNEXIONS"] = array(); + if (!is_array($_SESSION["FTP_CONNEXIONS"])) { + $_SESSION["FTP_CONNEXIONS"] = array(); } $_SESSION["FTP_CONNEXIONS"][$this->repositoryId] = $link; return $link; - } - - protected function convertingChmod($permissions, $filterForStat = false) - { - $mode = 0; - - if ($permissions[1] == 'r') $mode += 0400; - if ($permissions[2] == 'w') $mode += 0200; - if ($permissions[3] == 'x') $mode += 0100; - else if ($permissions[3] == 's') $mode += 04100; - else if ($permissions[3] == 'S') $mode += 04000; - - if ($permissions[4] == 'r') $mode += 040; - if ($permissions[5] == 'w' || ($filterForStat && $permissions[2] == 'w')) $mode += 020; - if ($permissions[6] == 'x' || ($filterForStat && $permissions[3] == 'x')) $mode += 010; - else if ($permissions[6] == 's') $mode += 02010; - else if ($permissions[6] == 'S') $mode += 02000; - - if ($permissions[7] == 'r') $mode += 04; - if ($permissions[8] == 'w' || ($filterForStat && $permissions[2] == 'w')) $mode += 02; - if ($permissions[9] == 'x' || ($filterForStat && $permissions[3] == 'x')) $mode += 01; - else if ($permissions[9] == 't') $mode += 01001; - else if ($permissions[9] == 'T') $mode += 01000; - - if($permissions[0] != "d") { - $mode += 0100000; - }else{ - $mode += 0040000; - } - - $mode = (string)("0".$mode); - return $mode; - } - - protected function safeDirname($path){ - return (DIRECTORY_SEPARATOR === "\\" ? str_replace("\\", "/", dirname($path)): dirname($path)); - } - - protected function safeBasename($path){ - return (DIRECTORY_SEPARATOR === "\\" ? str_replace("\\", "/", basename($path)): basename($path)); - } - + } + + protected function convertingChmod($permissions, $filterForStat = false) + { + $mode = 0; + + if ($permissions[1] == 'r') $mode += 0400; + if ($permissions[2] == 'w') $mode += 0200; + if ($permissions[3] == 'x') $mode += 0100; + else if ($permissions[3] == 's') $mode += 04100; + else if ($permissions[3] == 'S') $mode += 04000; + + if ($permissions[4] == 'r') $mode += 040; + if ($permissions[5] == 'w' || ($filterForStat && $permissions[2] == 'w')) $mode += 020; + if ($permissions[6] == 'x' || ($filterForStat && $permissions[3] == 'x')) $mode += 010; + else if ($permissions[6] == 's') $mode += 02010; + else if ($permissions[6] == 'S') $mode += 02000; + + if ($permissions[7] == 'r') $mode += 04; + if ($permissions[8] == 'w' || ($filterForStat && $permissions[2] == 'w')) $mode += 02; + if ($permissions[9] == 'x' || ($filterForStat && $permissions[3] == 'x')) $mode += 01; + else if ($permissions[9] == 't') $mode += 01001; + else if ($permissions[9] == 'T') $mode += 01000; + + if ($permissions[0] != "d") { + $mode += 0100000; + } else { + $mode += 0040000; + } + + $mode = (string) ("0".$mode); + return $mode; + } + + protected function safeDirname($path) + { + return (DIRECTORY_SEPARATOR === "\\" ? str_replace("\\", "/", dirname($path)): dirname($path)); + } + + protected function safeBasename($path) + { + return (DIRECTORY_SEPARATOR === "\\" ? str_replace("\\", "/", basename($path)): basename($path)); + } + } -?> diff --git a/core/src/plugins/access.ftp/i18n/conf/de.php b/core/src/plugins/access.ftp/i18n/conf/de.php index bafbf95ed4..f28c316b2d 100644 --- a/core/src/plugins/access.ftp/i18n/conf/de.php +++ b/core/src/plugins/access.ftp/i18n/conf/de.php @@ -41,4 +41,3 @@ "Pass Ftp data through Auth driver" => "FTP-Daten durch Auth Treiber erlauben", "In conjunction with a correctly configured auth.ftp driver, this allow to transform ajaxplorer into a simple netFtp client." => "In Zusammenarbeit mit einem korrekt konfigurierten Auth.ftp-Treiber, kann Ajaxplorer als einfacher netFTP Client genutzt werden.", ); -?> diff --git a/core/src/plugins/access.ftp/i18n/conf/en.php b/core/src/plugins/access.ftp/i18n/conf/en.php index 09076607b3..3e9c1d63df 100644 --- a/core/src/plugins/access.ftp/i18n/conf/en.php +++ b/core/src/plugins/access.ftp/i18n/conf/en.php @@ -41,4 +41,3 @@ "Pass Ftp data through Auth driver" => "Pass Ftp data through Auth driver", "In conjunction with a correctly configured auth.ftp driver, this allow to transform ajaxplorer into a simple netFtp client." => "In conjunction with a correctly configured auth.ftp driver, this allow to transform ajaxplorer into a simple netFtp client.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.ftp/i18n/conf/fr.php b/core/src/plugins/access.ftp/i18n/conf/fr.php index 90310810e7..b584e2c308 100644 --- a/core/src/plugins/access.ftp/i18n/conf/fr.php +++ b/core/src/plugins/access.ftp/i18n/conf/fr.php @@ -41,4 +41,3 @@ "Pass Ftp data through Auth driver" => "Paramêtres passés par l'Auth", "In conjunction with a correctly configured auth.ftp driver, this allow to transform ajaxplorer into a simple netFtp client." => "A utiliser en conjonction avec Auth.ftp, utiliser les données de FTP passées par le driver auth. Ceci permet de transformer AjaXplorer en un client WebFTP générique.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.ftp/i18n/conf/pt.php b/core/src/plugins/access.ftp/i18n/conf/pt.php index 1c1567d233..2df50f2cb3 100644 --- a/core/src/plugins/access.ftp/i18n/conf/pt.php +++ b/core/src/plugins/access.ftp/i18n/conf/pt.php @@ -41,4 +41,3 @@ "Pass Ftp data through Auth driver" => "Passar os dados FTP pelo controlador auth", "In conjunction with a correctly configured auth.ftp driver, this allow to transform ajaxplorer into a simple netFtp client." => "Em conjunto com um controlador de auth.ftp correctamente configurado, irá permitir transformar o AjaxPlorer num simples cliente netFTP.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.ftp/test.ftpAccess.php b/core/src/plugins/access.ftp/test.ftpAccess.php index 4dd54761ca..3f94a71960 100644 --- a/core/src/plugins/access.ftp/test.ftpAccess.php +++ b/core/src/plugins/access.ftp/test.ftpAccess.php @@ -19,7 +19,7 @@ * The latest code can be found at . */ defined('AJXP_EXEC') or die( 'Access not allowed'); - + require_once(AJXP_BIN_FOLDER . '/class.AbstractTest.php'); /** @@ -28,20 +28,18 @@ */ class ftpAccessTest extends AbstractTest { - function ftpAccessTest() { parent::AbstractTest("Remote FTP Filesystem Plugin", ""); } - - function doRepositoryTest($repo) + public function ftpAccessTest() { parent::AbstractTest("Remote FTP Filesystem Plugin", ""); } + + public function doRepositoryTest($repo) { - if($repo->accessType != "ftp") return -1; - + if($repo->accessType != "ftp") return -1; + $basePath = AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/access.ftp/" ; // Check file exists if (!file_exists($basePath."class.ftpAccessDriver.php") || !file_exists($basePath."manifest.xml")) { $this->failedInfo .= "Missing at least one of the plugin files (class.ftpAccessDriver.php, manifest.xml, ftpActions.xml).\nPlease reinstall from lastest release."; return FALSE; } - - return TRUE; + + return TRUE; } }; - -?> diff --git a/core/src/plugins/access.hpcloud/HPCloud_Patch/Storage/ObjectStorage/StreamWrapper.php b/core/src/plugins/access.hpcloud/HPCloud_Patch/Storage/ObjectStorage/StreamWrapper.php index ffa9ba0239..59d941ac74 100755 --- a/core/src/plugins/access.hpcloud/HPCloud_Patch/Storage/ObjectStorage/StreamWrapper.php +++ b/core/src/plugins/access.hpcloud/HPCloud_Patch/Storage/ObjectStorage/StreamWrapper.php @@ -11,7 +11,7 @@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER @@ -182,7 +182,7 @@ * characters such as '/' to be used to designate namespaces on object * names. (For simplicity, this library uses only '/' as a separator). * - * This allows for simulated directory listings. Requesting + * This allows for simulated directory listings. Requesting * `scandir('swift://foo/bar/')` is really a request to "find all of the items * in the 'foo' container whose names start with 'bar/'". * @@ -219,7 +219,7 @@ * -# Existing (valid) token: token, swift_endpoint * * The third method (token) can be used when the application has already - * authenticated. In this case, a token has been generated and assigneet + * authenticated. In this case, a token has been generated and assigneet * to an account and tenant ID. * * The following parameters may be set either in the stream context @@ -261,8 +261,8 @@ * @todo The service catalog should be cached in the context like the token so that * it can be retrieved later. */ -class StreamWrapper { - +class StreamWrapper +{ const DEFAULT_SCHEME = 'swift'; /** @@ -311,7 +311,7 @@ class StreamWrapper { /** * Indicate whether the local differs from remote. * - * When the file is modified in such a way that + * When the file is modified in such a way that * it needs to be written remotely, the isDirty flag * is set to TRUE. */ @@ -369,7 +369,8 @@ class StreamWrapper { * closing, and the handle can occasionally remain accessible for * some period of time. */ - public function dir_closedir() { + public function dir_closedir() + { $this->dirIndex = 0; $this->dirListing = array(); @@ -404,10 +405,11 @@ public function dir_closedir() { * @retval boolean * TRUE if the directory is opened, FALSE otherwise. */ - public function dir_opendir($path, $options) { + public function dir_opendir($path, $options) + { \AJXP_Logger::debug("OPENDIR ".$path); $url = $this->parseUrl($path); - if(isSet(self::$statCacheData["HPC_MAIN_PATH"]) && self::$statCacheData["HPC_MAIN_PATH"] == $path){ + if (isSet(self::$statCacheData["HPC_MAIN_PATH"]) && self::$statCacheData["HPC_MAIN_PATH"] == $path) { \AJXP_Logger::debug(">> listing from cache"); $this->listFromCache = true; return TRUE; @@ -429,8 +431,7 @@ public function dir_opendir($path, $options) { if (empty($url['path'])) { $this->dirPrefix = ''; - } - else { + } else { $this->dirPrefix = $url['path']; } @@ -438,8 +439,7 @@ public function dir_opendir($path, $options) { $this->dirListing = $container->objectsWithPrefix($this->dirPrefix, $sep); - } - catch (\HPCloud\Exception $e) { + } catch (\HPCloud\Exception $e) { trigger_error('Directory could not be opened: ' . $e->getMessage(), E_USER_WARNING); return FALSE; } @@ -471,9 +471,9 @@ public function dir_opendir($path, $options) { * The name of the resource or FALSE when the directory has no more * entries. */ - public function dir_readdir() { - - if($this->listFromCache){ + public function dir_readdir() + { + if ($this->listFromCache) { $values = array_keys(self::$statCache); if (count($values) <= $this->dirIndex) { return FALSE; @@ -500,8 +500,7 @@ public function dir_readdir() { \AJXP_Logger::debug("Full path should be dir ".$fullpath); $fullpath = rtrim($fullpath, "/"); self::$statCache[basename($fullpath)] = $this->fakeStat(true); - } - else { + } else { $fullpath = $curr->name(); self::$statCache[basename($fullpath)] = $this->generateStat($curr, self::$statCacheData["HPC_CONTAINER"], $curr->contentLength() ); } @@ -522,8 +521,8 @@ public function dir_readdir() { * Under certain conditions we have to return totally trumped-up * stats. This generates those. */ - protected function fakeStat($dir = FALSE) { - + protected function fakeStat($dir = FALSE) + { $request_time = time(); // Set inode type to directory or file. @@ -577,17 +576,18 @@ protected function fakeStat($dir = FALSE) { * ?> * @endcode */ - public function dir_rewinddir() { + public function dir_rewinddir() + { $this->dirIndex = 0; } /* - public function mkdir($path, $mode, $options) { - + public function mkdir($path, $mode, $options) + { } - public function rmdir($path, $options) { - + public function rmdir($path, $options) + { } */ @@ -626,7 +626,8 @@ public function rmdir($path, $options) { * @retval boolean * TRUE on success, FALSE otherwise. */ - public function rename($path_from, $path_to) { + public function rename($path_from, $path_to) + { $this->initializeObjectStorage(); $src = $this->parseUrl($path_from); $dest = $this->parseUrl($path_to); @@ -650,15 +651,15 @@ public function rename($path_from, $path_to) { if ($ret) { return $container->delete($src['path']); } - } - catch (\HPCloud\Exception $e) { + } catch (\HPCloud\Exception $e) { trigger_error('Rename was not completed: ' . $e->getMessage(), E_USER_WARNING); return FALSE; } } /* - public function copy($path_from, $path_to) { + public function copy($path_from, $path_to) + { throw new \Exception("UNDOCUMENTED."); } */ @@ -673,7 +674,8 @@ public function copy($path_from, $path_to) { * @retval resource * this returns the underlying stream. */ - public function stream_cast($cast_as) { + public function stream_cast($cast_as) + { return $this->objStream; } @@ -698,12 +700,11 @@ public function stream_cast($cast_as) { * * See stream_open(). */ - public function stream_close() { - + public function stream_close() + { try { $this->writeRemote(); - } - catch (\HPCloud\Exception $e) { + } catch (\HPCloud\Exception $e) { trigger_error('Error while closing: ' . $e->getMessage(), E_USER_NOTICE); return FALSE; } @@ -726,7 +727,8 @@ public function stream_close() { * @retval boolean * TRUE if it has reached the end, FALSE otherwise. */ - public function stream_eof() { + public function stream_eof() + { return feof($this->objStream); } @@ -738,11 +740,11 @@ public function stream_eof() { * * Called when \c fflush() is called on a stream. */ - public function stream_flush() { + public function stream_flush() + { try { $this->writeRemote(); - } - catch (\HPCloud\Exception $e) { + } catch (\HPCloud\Exception $e) { syslog(LOG_WARNING, $e); trigger_error('Error while flushing: ' . $e->getMessage(), E_USER_NOTICE); return FALSE; @@ -754,8 +756,8 @@ public function stream_flush() { * * Internally, this is used by flush and close. */ - protected function writeRemote() { - + protected function writeRemote() + { $contentType = $this->cxt('content_type'); if (!empty($contentType)) { $this->obj->setContentType($contentType); @@ -782,10 +784,10 @@ protected function writeRemote() { /* * Locking is currently unsupported. * - * There is no remote support for locking a + * There is no remote support for locking a * file. - public function stream_lock($operation) { - + public function stream_lock($operation) + { } */ @@ -836,8 +838,8 @@ public function stream_lock($operation) { * @param string $opened_path * This is not used, as this wrapper deals only with remote objects. */ - public function stream_open($path, $mode, $options, &$opened_path) { - + public function stream_open($path, $mode, $options, &$opened_path) + { //syslog(LOG_WARNING, "I received this URL: " . $path); // If STREAM_REPORT_ERRORS is set, we are responsible for @@ -890,8 +892,7 @@ public function stream_open($path, $mode, $options, &$opened_path) { try { $this->initializeObjectStorage(); - } - catch (\HPCloud\Exception $e) { + } catch (\HPCloud\Exception $e) { trigger_error('Failed to init object storage: ' . $e->getMessage(), E_USER_WARNING); return FALSE; } @@ -927,24 +928,23 @@ public function stream_open($path, $mode, $options, &$opened_path) { // server roundtrip? \AJXP_Logger::debug(">> Getting the container $containerName"); try { - if(isSet(self::$statCacheData["HPC_CONTAINER"]) && self::$statCacheData["HPC_MAIN_PATH"] == $containerName){ + if (isSet(self::$statCacheData["HPC_CONTAINER"]) && self::$statCacheData["HPC_MAIN_PATH"] == $containerName) { $this->container = self::$statCacheData["HPC_CONTAINER"]; - }else{ + } else { $this->container = $this->store->container($containerName); self::$statCacheData["HPC_MAIN_PATH"] = $containerName; self::$statCacheData["HPC_CONTAINER"] = $this->container; } - } - catch (\HPCloud\Transport\FileNotFoundException $e) { + } catch (\HPCloud\Transport\FileNotFoundException $e) { trigger_error('Container not found.', E_USER_WARNING); return FALSE; } - try{ + try { \AJXP_Logger::debug(">> Now fetching the file"); // Now we fetch the file. Only under certain circumstances do we generate // an error if the file is not found. - // FIXME: We should probably allow a context param that can be set to + // FIXME: We should probably allow a context param that can be set to // mark the file as lazily fetched. $this->obj = $this->container->object($objectName); $stream = $this->obj->stream(); @@ -972,8 +972,7 @@ public function stream_open($path, $mode, $options, &$opened_path) { } $this->objStream = $tmpStream; - } - else { + } else { $this->objStream = $this->obj->stream(); } @@ -992,8 +991,7 @@ public function stream_open($path, $mode, $options, &$opened_path) { $this->obj = new Object($objectName); $this->objStream = fopen('php://temp', 'rb+'); $this->isDirty = TRUE; - } - else { + } else { //if ($this->triggerErrors) { trigger_error($nf->getMessage(), E_USER_WARNING); //} @@ -1042,7 +1040,8 @@ public function stream_open($path, $mode, $options, &$opened_path) { * @retval string * The data read. */ - public function stream_read($count) { + public function stream_read($count) + { return fread($this->objStream, $count); } @@ -1057,7 +1056,8 @@ public function stream_read($count) { * allows you to fseek() inside of a file opened * in append mode ('a' or 'a+'). */ - public function stream_seek($offset, $whence) { + public function stream_seek($offset, $whence) + { $ret = fseek($this->objStream, $offset, $whence); // fseek returns 0 for success, -1 for failure. @@ -1076,7 +1076,8 @@ public function stream_seek($offset, $whence) { * * See stream_set_blocking(), stream_set_timeout(), and stream_write_buffer(). */ - public function stream_set_option($option, $arg1, $arg2) { + public function stream_set_option($option, $arg1, $arg2) + { switch ($option) { case STREAM_OPTION_BLOCKING: return stream_set_blocking($this->objStream, $arg1); @@ -1107,7 +1108,8 @@ public function stream_set_option($option, $arg1, $arg2) { * @retval array * The stats array. */ - public function stream_stat() { + public function stream_stat() + { $stat = fstat($this->objStream); // FIXME: Need to calculate the length of the $objStream. @@ -1125,7 +1127,8 @@ public function stream_stat() { * @retval int * The current position in the stream. */ - public function stream_tell() { + public function stream_tell() + { return ftell($this->objStream); } @@ -1133,7 +1136,7 @@ public function stream_tell() { * Write data to stream. * * This writes data to the local stream buffer. Data - * is not pushed remotely until stream_close() or + * is not pushed remotely until stream_close() or * stream_flush() is called. * * @param string $data @@ -1141,7 +1144,8 @@ public function stream_tell() { * @retval int * The number of bytes written. 0 indicates and error. */ - public function stream_write($data) { + public function stream_write($data) + { $this->isDirty = TRUE; return fwrite($this->objStream, $data); } @@ -1167,7 +1171,8 @@ public function stream_write($data) { * @retval boolean * TRUE if the file was deleted, FALSE otherwise. */ - public function unlink($path) { + public function unlink($path) + { $url = $this->parseUrl($path); // Host is required. @@ -1192,8 +1197,7 @@ public function unlink($path) { $endpoint_url = $this->store->url() . '/' . rawurlencode($name); $container = new \HPCloud\Storage\ObjectStorage\Container($name, $endpoint_url, $token); return $container->delete($url['path']); - } - catch (\HPCLoud\Exception $e) { + } catch (\HPCLoud\Exception $e) { trigger_error('Error during unlink: ' . $e->getMessage(), E_USER_WARNING); return FALSE; } @@ -1203,19 +1207,20 @@ public function unlink($path) { /** * @see stream_stat(). */ - public function url_stat($path, $flags) { + public function url_stat($path, $flags) + { $url = $this->parseUrl($path); \AJXP_Logger::debug("STATING ".$path); $base = $url["host"]; //dirname($path)."/"; $name = basename($path); - if(isSet(self::$statCacheData["HPC_MAIN_PATH"]) && $path."/" == self::$statCacheData["HPC_MAIN_PATH"]){ + if (isSet(self::$statCacheData["HPC_MAIN_PATH"]) && $path."/" == self::$statCacheData["HPC_MAIN_PATH"]) { return $this->fakeStat(true); } - if(isset(self::$statCache[$name]) && self::$statCacheData["HPC_MAIN_PATH"] == $base){ + if (isset(self::$statCache[$name]) && self::$statCacheData["HPC_MAIN_PATH"] == $base) { return self::$statCache[$name]; } - if(is_array(self::$statCache) && isSet(self::$statCache[$path])){ + if (is_array(self::$statCache) && isSet(self::$statCache[$path])) { \AJXP_Logger::debug("Cached path!"); return self::$statCache[$path]; } @@ -1235,10 +1240,10 @@ public function url_stat($path, $flags) { //$container = $this->store->container($url['host']); $name = $url['host']; try { - if(isSet(self::$statCacheData["HPC_CONTAINER"]) && self::$statCacheData["HPC_MAIN_PATH"] == $name){ + if (isSet(self::$statCacheData["HPC_CONTAINER"]) && self::$statCacheData["HPC_MAIN_PATH"] == $name) { \AJXP_Logger::debug("URL_STAT Getting container from cache"); $container = self::$statCacheData["HPC_CONTAINER"]; - }else{ + } else { \AJXP_Logger::debug("URL_STAT Instanciating container ".$name); $token = $this->store->token(); $endpoint_url = $this->store->url() . '/' . rawurlencode($name); @@ -1247,15 +1252,13 @@ public function url_stat($path, $flags) { self::$statCacheData["HPC_MAIN_PATH"] = $name; self::$statCacheData["HPC_CONTAINER"] = $container; } - } - catch (\HPCloud\Transport\FileNotFoundException $e) { + } catch (\HPCloud\Transport\FileNotFoundException $e) { trigger_error('Container not found.', E_USER_WARNING); return FALSE; } $obj = $container->remoteObject($url['path']); - } - catch(\HPCloud\Exception $e) { + } catch (\HPCloud\Exception $e) { // Apparently file_exists does not set STREAM_URL_STAT_QUIET. //if ($flags & STREAM_URL_STAT_QUIET) { //trigger_error('Could not stat remote file: ' . $e->getMessage(), E_USER_WARNING); @@ -1270,8 +1273,7 @@ public function url_stat($path, $flags) { \AJXP_Logger::debug("CACHING1 ".$path, array_keys(self::$statCache)); self::$statCache[$path] = $s; return $s; - } - catch (\HPCloud\Exception $e) { + } catch (\HPCloud\Exception $e) { return FALSE; } } @@ -1306,7 +1308,8 @@ public function url_stat($path, $flags) { * ?> * @endcode */ - public function object() { + public function object() + { return $this->obj; } @@ -1317,7 +1320,8 @@ public function object() { * An ObjectStorage object. * @see object() */ - public function objectStorage() { + public function objectStorage() + { return $this->store; } @@ -1328,7 +1332,8 @@ public function objectStorage() { * A token. * @see object() */ - public function token() { + public function token() + { return $this->store->token(); } @@ -1341,7 +1346,8 @@ public function token() { * A service catalog. * @see object() */ - public function serviceCatalog() { + public function serviceCatalog() + { return self::$serviceCatalogCache[$this->token()]; } @@ -1365,7 +1371,8 @@ public function serviceCatalog() { * be the remote's Content-Length, and it will sometimes be * the cached stat['size'] for the underlying buffer. */ - protected function generateStat($object, $container, $size) { + protected function generateStat($object, $container, $size) + { // This is not entirely accurate. Basically, if the // file is marked public, it gets 100775, and if // it is private, it gets 100770. @@ -1383,16 +1390,14 @@ protected function generateStat($object, $container, $size) { if (function_exists('posix_geteuid')) { $uid = posix_geteuid(); $gid = posix_getegid(); - } - else { + } else { $uid = 0; $gid = 0; } if ($object instanceof \HPCloud\Storage\ObjectStorage\RemoteObject) { $modTime = $object->lastModified(); - } - else { + } else { $modTime = 0; } $values = array( @@ -1428,7 +1433,8 @@ protected function generateStat($object, $container, $size) { * @param string $mode * The mode string, e.g. `r+` or `wb`. */ - protected function setMode($mode) { + protected function setMode($mode) + { $mode = strtolower($mode); // These are largely ignored, as the remote @@ -1514,8 +1520,8 @@ protected function setMode($mode) { * The discovered result, or $default if specified, or NULL if * no $default is specified. */ - protected function cxt($name, $default = NULL) { - + protected function cxt($name, $default = NULL) + { // Lazilly populate the context array. if (is_resource($this->context) && empty($this->contextArray)) { $cxt = stream_context_get_options($this->context); @@ -1559,7 +1565,8 @@ protected function cxt($name, $default = NULL) { * @retval array * An array as documented in parse_url(). */ - protected function parseUrl($url) { + protected function parseUrl($url) + { $res = parse_url($url); @@ -1568,8 +1575,7 @@ protected function parseUrl($url) { foreach ($res as $key => $val) { if ($key == 'host') { $res[$key] = urldecode($val); - } - elseif ($key == 'path') { + } elseif ($key == 'path') { if (strpos($val, '/') === 0) { $val = substr($val, 1); } @@ -1601,15 +1607,15 @@ protected function parseUrl($url) { * the deprecated swiftAuth instead of IdentityServices authentication. * In general, you should avoid using this. * - * To find these params, the method first checks the supplied context. If the + * To find these params, the method first checks the supplied context. If the * key is not found there, it checks the Bootstrap::conf(). * * @fixme This should be rewritten to use ObjectStorage::newFromServiceCatalog(). */ - protected function initializeObjectStorage() { - + protected function initializeObjectStorage() + { $token = $this->cxt('token'); - if(empty($token) && isSet($_SESSION["HPCLOUD_TOKEN"])){ + if (empty($token) && isSet($_SESSION["HPCLOUD_TOKEN"])) { $token = $_SESSION["HPCLOUD_TOKEN"]; } @@ -1623,14 +1629,14 @@ protected function initializeObjectStorage() { $serviceCatalog = NULL; if (!empty($token) && ( isset(self::$serviceCatalogCache[$token]) || isset($_SESSION["HPCLOUD_CATALOG"])) ) { - if(isSet($_SESSION["HPCLOUD_CATALOG"])){ + if (isSet($_SESSION["HPCLOUD_CATALOG"])) { $serviceCatalog = $_SESSION["HPCLOUD_CATALOG"]; - }else{ + } else { $serviceCatalog = self::$serviceCatalogCache[$token]; } - if(empty($endpoint)){ - for($i=0;$iinitializeCDN($token, $serviceCatalog); - } - catch (\HPCloud\Exception $e) { + } catch (\HPCloud\Exception $e) { //fwrite(STDOUT, $e); throw new \HPCloud\Exception('CDN could not be initialized', 1, $e); @@ -1711,7 +1716,8 @@ protected function initializeObjectStorage() { * Also note that CDN's default behavior is to fetch over SSL CDN. * To disable this, set 'cdn_require_ssl' to FALSE. */ - protected function initializeCDN($token, $catalog) { + protected function initializeCDN($token, $catalog) + { $cdn = $this->cxt('use_cdn', FALSE); // No CDN should be enabled. @@ -1738,7 +1744,8 @@ protected function initializeCDN($token, $catalog) { return TRUE; } - protected function authenticate() { + protected function authenticate() + { $username = $this->cxt('username'); $password = $this->cxt('password'); @@ -1754,11 +1761,9 @@ protected function authenticate() { if (!empty($username) && !empty($password)) { $token = $ident->authenticateAsUser($username, $password, $tenantId); - } - elseif (!empty($account) && !empty($key)) { + } elseif (!empty($account) && !empty($key)) { $token = $ident->authenticateAsAccount($account, $key, $tenantId); - } - else { + } else { throw new \HPCloud\Exception('Either username/password or account/key must be provided.'); } // Cache the service catalog. diff --git a/core/src/plugins/access.hpcloud/HPCloud_Patch/Transport/CURLTransport.php b/core/src/plugins/access.hpcloud/HPCloud_Patch/Transport/CURLTransport.php index 27b04e04e6..39eefc9b67 100755 --- a/core/src/plugins/access.hpcloud/HPCloud_Patch/Transport/CURLTransport.php +++ b/core/src/plugins/access.hpcloud/HPCloud_Patch/Transport/CURLTransport.php @@ -11,7 +11,7 @@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER @@ -50,9 +50,8 @@ * The only downside to Curl is that it is not available on all hosts. * Some installations of PHP do not compile support. */ -class CURLTransport implements Transporter { - - +class CURLTransport implements Transporter +{ const HTTP_USER_AGENT_SUFFIX = ' (c93c0a) CURL/1.0'; protected $curlInst = NULL; @@ -65,7 +64,8 @@ class CURLTransport implements Transporter { */ protected $multi = NULL; - public function __destruct() { + public function __destruct() + { // Destroy the multi handle. if (!empty($this->multi)) { curl_multi_close($this->multi); @@ -73,7 +73,8 @@ public function __destruct() { } /* - public function curl($uri) { + public function curl($uri) + { //if (empty($this->curlInst)) { $this->curlInst = curl_init(); //} @@ -82,8 +83,8 @@ public function curl($uri) { } */ - public function doRequest($uri, $method = 'GET', $headers = array(), $body = NULL) { - + public function doRequest($uri, $method = 'GET', $headers = array(), $body = NULL) + { $in = NULL; if (!empty($body)) { // For whatever reason, CURL seems to want POST request data to be @@ -91,8 +92,7 @@ public function doRequest($uri, $method = 'GET', $headers = array(), $body = NUL // needs to be in a file handle. if ($method == 'POST') { $in = $body; - } - else { + } else { // First we turn our body into a temp-backed buffer. $in = fopen('php://temp', 'wr', FALSE); fwrite($in, $body, strlen($body)); @@ -104,11 +104,11 @@ public function doRequest($uri, $method = 'GET', $headers = array(), $body = NUL } - public function doRequestWithResource($uri, $method, $headers, $resource) { + public function doRequestWithResource($uri, $method, $headers, $resource) + { if (is_string($resource)) { $in = open($resource, 'rb', FALSE); - } - else { + } else { // FIXME: Is there a better way? // There is a bug(?) in CURL which prevents it // from writing the same stream twice. But we @@ -125,8 +125,8 @@ public function doRequestWithResource($uri, $method, $headers, $resource) { /** * Internal workhorse. */ - protected function handleDoRequest($uri, $method, $headers, $in = NULL) { - + protected function handleDoRequest($uri, $method, $headers, $in = NULL) + { // XXX: I don't like this, but I'm getting bug reports that mistakenly // assume this library is broken, when in fact CURL is not installed. if (!function_exists('curl_init')) { @@ -247,8 +247,7 @@ protected function handleDoRequest($uri, $method, $headers, $in = NULL) { if (!$ret || $status < 200 || $status > 299 || empty($responseHeaders)) { if (empty($responseHeaders)) { $err = 'Unknown (non-HTTP) error: ' . $status; - } - else { + } else { $err = $responseHeaders[0]; } //rewind($out); @@ -288,13 +287,13 @@ protected function handleDoRequest($uri, $method, $headers, $in = NULL) { * Returns a boolean value indicating whether or not CURL could process the * request. */ - protected function execCurl($handle) { + protected function execCurl($handle) + { if (empty($this->multi)) { $multi = curl_multi_init(); $this->multi = $multi; //echo "Creating MULTI handle.\n"; - } - else { + } else { //echo "Reusing MULTI handle.\n"; $multi = $this->multi; } @@ -341,7 +340,8 @@ protected function execCurl($handle) { * @retval array * An array of headers, one header per line. */ - protected function fetchHeaders($file) { + protected function fetchHeaders($file) + { $buffer = array(); while ($header = fgets($file)) { $header = trim($header); @@ -359,9 +359,9 @@ protected function fetchHeaders($file) { /** * Set the appropriate constant on the CURL object. * - * Curl handles method name setting in a slightly counter-intuitive - * way, so we have a special function for setting the method - * correctly. Note that since we do not POST as www-form-*, we + * Curl handles method name setting in a slightly counter-intuitive + * way, so we have a special function for setting the method + * correctly. Note that since we do not POST as www-form-*, we * use a custom post. * * @param resource $curl @@ -369,7 +369,8 @@ protected function fetchHeaders($file) { * @param string $method * An HTTP method name. */ - protected function determineMethod($curl, $method) { + protected function determineMethod($curl, $method) + { $method = strtoupper($method); switch ($method) { @@ -397,7 +398,8 @@ protected function determineMethod($curl, $method) { } - public function setHeaders($curl, $headers) { + public function setHeaders($curl, $headers) + { $buffer = array(); $format = '%s: %s'; diff --git a/core/src/plugins/access.hpcloud/class.hpcAccessDriver.php b/core/src/plugins/access.hpcloud/class.hpcAccessDriver.php index 70dc48b623..a557f63119 100755 --- a/core/src/plugins/access.hpcloud/class.hpcAccessDriver.php +++ b/core/src/plugins/access.hpcloud/class.hpcAccessDriver.php @@ -1,100 +1,104 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); -/** - * AJXP_Plugin to access a webdav enabled server - * @package AjaXplorer_Plugins - * @subpackage Access - */ -class hpcAccessDriver extends fsAccessDriver -{ - /** - * @var Repository - */ - public $repository; - public $driverConf; - protected $wrapperClassName; - protected $urlBase; - - public function performChecks(){ - // Check CURL, OPENSSL & AWS LIBRARY & PHP5.3 - if(version_compare(phpversion(), "5.3.0") < 0){ - throw new Exception("Php version 5.3+ is required for this plugin (must support namespaces)"); - } - } - - - function initRepository(){ - - include_once("libraryLoader.php"); - - if(is_array($this->pluginConf)){ - $this->driverConf = $this->pluginConf; - }else{ - $this->driverConf = array(); - } - - $path = $this->repository->getOption("PATH"); - $recycle = $this->repository->getOption("RECYCLE_BIN"); - ConfService::setConf("PROBE_REAL_SIZE", false); - $wrapperData = $this->detectStreamWrapper(true); - $this->wrapperClassName = $wrapperData["classname"]; - $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); - if($recycle != ""){ - RecycleBinManager::init($this->urlBase, "/".$recycle); - } - } - - /** - * Parse - * @param DOMNode $contribNode - */ - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($contribNode->nodeName != "actions") return ; - $this->disableArchiveBrowsingContributions($contribNode); - } - - function isWriteable($dir, $type="dir"){ - return true; - } - - function loadNodeInfo(AJXP_Node &$node, $parentNode = false, $details = false){ - parent::loadNodeInfo($node, $parentNode, $details); - if(!$node->isLeaf()){ - $node->setLabel(rtrim($node->getLabel(), "/")); - } - } - - function filesystemFileSize($filePath){ - $bytesize = filesize($filePath); - return $bytesize; - } - - function isRemote(){ - return true; - } - -} - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); +/** + * AJXP_Plugin to access a webdav enabled server + * @package AjaXplorer_Plugins + * @subpackage Access + */ +class hpcAccessDriver extends fsAccessDriver +{ + /** + * @var Repository + */ + public $repository; + public $driverConf; + protected $wrapperClassName; + protected $urlBase; + + public function performChecks() + { + // Check CURL, OPENSSL & AWS LIBRARY & PHP5.3 + if (version_compare(phpversion(), "5.3.0") < 0) { + throw new Exception("Php version 5.3+ is required for this plugin (must support namespaces)"); + } + } + + + public function initRepository() + { + include_once("libraryLoader.php"); + + if (is_array($this->pluginConf)) { + $this->driverConf = $this->pluginConf; + } else { + $this->driverConf = array(); + } + + $path = $this->repository->getOption("PATH"); + $recycle = $this->repository->getOption("RECYCLE_BIN"); + ConfService::setConf("PROBE_REAL_SIZE", false); + $wrapperData = $this->detectStreamWrapper(true); + $this->wrapperClassName = $wrapperData["classname"]; + $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); + if ($recycle != "") { + RecycleBinManager::init($this->urlBase, "/".$recycle); + } + } + + /** + * Parse + * @param DOMNode $contribNode + */ + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if($contribNode->nodeName != "actions") return ; + $this->disableArchiveBrowsingContributions($contribNode); + } + + public function isWriteable($dir, $type="dir") + { + return true; + } + + public function loadNodeInfo(AJXP_Node &$node, $parentNode = false, $details = false) + { + parent::loadNodeInfo($node, $parentNode, $details); + if (!$node->isLeaf()) { + $node->setLabel(rtrim($node->getLabel(), "/")); + } + } + + public function filesystemFileSize($filePath) + { + $bytesize = filesize($filePath); + return $bytesize; + } + + public function isRemote() + { + return true; + } + +} diff --git a/core/src/plugins/access.hpcloud/class.hpcAccessWrapper.php b/core/src/plugins/access.hpcloud/class.hpcAccessWrapper.php index b1292aaed6..37c1b4ad9c 100755 --- a/core/src/plugins/access.hpcloud/class.hpcAccessWrapper.php +++ b/core/src/plugins/access.hpcloud/class.hpcAccessWrapper.php @@ -28,28 +28,29 @@ * @package AjaXplorer_Plugins * @subpackage Access */ -class hpcAccessWrapper extends fsAccessWrapper { - +class hpcAccessWrapper extends fsAccessWrapper +{ public static $lastException; private static $cloudContext; /** - * Initialize the stream from the given path. + * Initialize the stream from the given path. * Concretely, transform ajxp.webdav:// into webdav:// * * @param string $path * @return mixed Real path or -1 if currentListing contains the listing : original path converted to real path */ - protected static function initPath($path, $streamType, $storeOpenContext = false, $skipZip = false){ - $url = parse_url($path); - $repoId = $url["host"]; - $repoObject = ConfService::getRepositoryById($repoId); - if(!isSet($repoObject)) { + protected static function initPath($path, $streamType, $storeOpenContext = false, $skipZip = false) + { + $url = parse_url($path); + $repoId = $url["host"]; + $repoObject = ConfService::getRepositoryById($repoId); + if (!isSet($repoObject)) { $e = new Exception("Cannot find repository with id ".$repoId); self::$lastException = $e; throw $e; } - if(self::$cloudContext == null){ + if (self::$cloudContext == null) { self::$cloudContext = stream_context_create( array("swiftfs" => array( @@ -65,12 +66,12 @@ protected static function initPath($path, $streamType, $storeOpenContext = false $p = "swiftfs://".$baseContainer.str_replace("//", "/", $url["path"]); return $p; } - + /** * Opens the stream * Diff with parent class : do not "securePath", as it removes double slash * - * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" + * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" * @param String $mode * @param unknown_type $options * @param unknown_type $opened_path @@ -78,19 +79,19 @@ protected static function initPath($path, $streamType, $storeOpenContext = false */ public function stream_open($path, $mode, $options, &$context) { - try{ - $this->realPath = $this->initPath($path, "file"); - }catch (Exception $e){ - AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); - return false; - } - if($this->realPath == -1){ - $this->fp = -1; - return true; - }else{ - $this->fp = fopen($this->realPath, $mode, $options, self::$cloudContext); - return ($this->fp !== false); - } + try { + $this->realPath = $this->initPath($path, "file"); + } catch (Exception $e) { + AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); + return false; + } + if ($this->realPath == -1) { + $this->fp = -1; + return true; + } else { + $this->fp = fopen($this->realPath, $mode, $options, self::$cloudContext); + return ($this->fp !== false); + } } /** @@ -101,100 +102,108 @@ public function stream_open($path, $mode, $options, &$context) * @param unknown_type $flags * @return unknown */ - public function url_stat($path, $flags){ - // File and zip case + public function url_stat($path, $flags) + { + // File and zip case // AJXP_Logger::debug("Stating $path"); $stat = @stat($this->initPath($path, "file")); if($stat == null) return null; - if($stat["mode"] == 0666){ + if ($stat["mode"] == 0666) { $stat[2] = $stat["mode"] |= 0100000; // S_ISREG } $parsed = parse_url($path); - if($stat["mtime"] == $stat["ctime"] && $stat["ctime"] == $stat["atime"] && $stat["atime"] == 0 && $parsed["path"] != "/") { + if ($stat["mtime"] == $stat["ctime"] && $stat["ctime"] == $stat["atime"] && $stat["atime"] == 0 && $parsed["path"] != "/") { //AJXP_Logger::debug("Nullifying stats"); return null; } return $stat; - // Non existing file - return null; + // Non existing file + return null; } - + /** * Opens a handle to the dir - * Fix PEAR by being sure it ends up with "/", to avoid + * Fix PEAR by being sure it ends up with "/", to avoid * adding the current dir to the children list. * * @param unknown_type $path * @param unknown_type $options * @return unknown */ - public function dir_opendir ($path , $options ){ - $this->realPath = $this->initPath($path, "dir", true); - if($this->realPath[strlen($this->realPath)-1] != "/"){ - $this->realPath.="/"; - } - if(is_string($this->realPath)){ - $this->dH = opendir($this->realPath, self::$cloudContext); - }else if($this->realPath == -1){ - $this->dH = -1; - } - return $this->dH !== false; - } - - public function mkdir($path, $mode, $options){ + public function dir_opendir ($path , $options ) + { + $this->realPath = $this->initPath($path, "dir", true); + if ($this->realPath[strlen($this->realPath)-1] != "/") { + $this->realPath.="/"; + } + if (is_string($this->realPath)) { + $this->dH = opendir($this->realPath, self::$cloudContext); + } else if ($this->realPath == -1) { + $this->dH = -1; + } + return $this->dH !== false; + } + + public function mkdir($path, $mode, $options) + { $this->realPath = $this->initPath($path, "dir", true); file_put_contents($this->realPath."/.marker", "tmpdata"); return true; } - // DUPBLICATE STATIC FUNCTIONS TO BE SURE - // NOT TO MESS WITH self:: CALLS - - public static function removeTmpFile($tmpDir, $tmpFile){ - if(is_file($tmpFile)) unlink($tmpFile, self::$cloudContext); - if(is_dir($tmpDir)) rmdir($tmpDir, self::$cloudContext); - } - - protected static function closeWrapper(){ - if(self::$crtZip != null) { - self::$crtZip = null; - self::$currentListing = null; - self::$currentListingKeys = null; - self::$currentListingIndex = null; - self::$currentFileKey = null; - } - } - - public static function getRealFSReference($path, $persistent = false){ + // DUPBLICATE STATIC FUNCTIONS TO BE SURE + // NOT TO MESS WITH self:: CALLS + + public static function removeTmpFile($tmpDir, $tmpFile) + { + if(is_file($tmpFile)) unlink($tmpFile, self::$cloudContext); + if(is_dir($tmpDir)) rmdir($tmpDir, self::$cloudContext); + } + + protected static function closeWrapper() + { + if (self::$crtZip != null) { + self::$crtZip = null; + self::$currentListing = null; + self::$currentListingKeys = null; + self::$currentListingIndex = null; + self::$currentFileKey = null; + } + } + + public static function getRealFSReference($path, $persistent = false) + { $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()).".".pathinfo($path, PATHINFO_EXTENSION); - $tmpHandle = fopen($tmpFile, "wb", null, self::$cloudContext); - self::copyFileInStream($path, $tmpHandle); - fclose($tmpHandle); - if(!$persistent){ - register_shutdown_function(array("AJXP_Utils", "silentUnlink"), $tmpFile); - } - return $tmpFile; - } - - - public static function isRemote(){ - return true; + $tmpHandle = fopen($tmpFile, "wb", null, self::$cloudContext); + self::copyFileInStream($path, $tmpHandle); + fclose($tmpHandle); + if (!$persistent) { + register_shutdown_function(array("AJXP_Utils", "silentUnlink"), $tmpFile); + } + return $tmpFile; } - - public static function copyFileInStream($path, $stream){ - $fp = fopen($path, "r", null, self::$cloudContext); - while (!feof($fp)) { - $data = fread($fp, 4096); - fwrite($stream, $data, strlen($data)); - } - fclose($fp); - } - - public static function changeMode($path, $chmodValue){ + + + public static function isRemote() + { + return true; + } + + public static function copyFileInStream($path, $stream) + { + $fp = fopen($path, "r", null, self::$cloudContext); + while (!feof($fp)) { + $data = fread($fp, 4096); + fwrite($stream, $data, strlen($data)); + } + fclose($fp); + } + + public static function changeMode($path, $chmodValue) + { // DO NOTHING! - //$realPath = self::initPath($path, "file"); - //chmod($realPath, $chmodValue); - } + //$realPath = self::initPath($path, "file"); + //chmod($realPath, $chmodValue); + } } -?> \ No newline at end of file diff --git a/core/src/plugins/access.hpcloud/i18n/conf/en.php b/core/src/plugins/access.hpcloud/i18n/conf/en.php index 112f72a4ec..684de4183a 100755 --- a/core/src/plugins/access.hpcloud/i18n/conf/en.php +++ b/core/src/plugins/access.hpcloud/i18n/conf/en.php @@ -29,4 +29,4 @@ "S3 storage region" => "S3 storage region", "Container" => "Bucket", "Root container in the S3 storage" => "S3 bucket" -); \ No newline at end of file +); diff --git a/core/src/plugins/access.hpcloud/i18n/conf/fr.php b/core/src/plugins/access.hpcloud/i18n/conf/fr.php index 0cf4e3d0db..f0b321dfb0 100755 --- a/core/src/plugins/access.hpcloud/i18n/conf/fr.php +++ b/core/src/plugins/access.hpcloud/i18n/conf/fr.php @@ -29,4 +29,4 @@ "S3 storage region" => "Région du stockage S3", "Container" => "Container", "Root container in the S3 storage" => "Container S3 sans lequel sont stockées les données" -); \ No newline at end of file +); diff --git a/core/src/plugins/access.hpcloud/i18n/conf/pt.php b/core/src/plugins/access.hpcloud/i18n/conf/pt.php index a7cb251855..4c562534cd 100644 --- a/core/src/plugins/access.hpcloud/i18n/conf/pt.php +++ b/core/src/plugins/access.hpcloud/i18n/conf/pt.php @@ -29,4 +29,4 @@ "S3 storage region" => "Opções de Registo da região S3", "Container" => "Contentor", "Root container in the S3 storage" => "Contentor S3" -); \ No newline at end of file +); diff --git a/core/src/plugins/access.hpcloud/libraryLoader.php b/core/src/plugins/access.hpcloud/libraryLoader.php index c43bf3fae7..f54135d10c 100644 --- a/core/src/plugins/access.hpcloud/libraryLoader.php +++ b/core/src/plugins/access.hpcloud/libraryLoader.php @@ -1,12 +1,12 @@ -getBaseDir()."/HPCloud/Bootstrap.php"); -\HPCloud\Bootstrap::useAutoloader(); -\HPCloud\Bootstrap::useStreamWrappers(); - -\HPCloud\Bootstrap::setConfiguration(array( - 'username' => $this->repository->getOption("USERNAME"), - 'password' => $this->repository->getOption("PASSWORD"), - 'tenantid' => $this->repository->getOption("TENANT_ID"), - 'endpoint' => $this->repository->getOption("ENDPOINT"), - 'transport.ssl.verify' => false -)); \ No newline at end of file +getBaseDir()."/HPCloud/Bootstrap.php"); +\HPCloud\Bootstrap::useAutoloader(); +\HPCloud\Bootstrap::useStreamWrappers(); + +\HPCloud\Bootstrap::setConfiguration(array( + 'username' => $this->repository->getOption("USERNAME"), + 'password' => $this->repository->getOption("PASSWORD"), + 'tenantid' => $this->repository->getOption("TENANT_ID"), + 'endpoint' => $this->repository->getOption("ENDPOINT"), + 'transport.ssl.verify' => false +)); diff --git a/core/src/plugins/access.hpcloud/manifest.xml b/core/src/plugins/access.hpcloud/manifest.xml index febfe2a518..c77e3727dc 100755 --- a/core/src/plugins/access.hpcloud/manifest.xml +++ b/core/src/plugins/access.hpcloud/manifest.xml @@ -24,4 +24,4 @@ - \ No newline at end of file + diff --git a/core/src/plugins/access.imap/class.imapAccessDriver.php b/core/src/plugins/access.imap/class.imapAccessDriver.php index ed76613cd2..a8f40e8c20 100644 --- a/core/src/plugins/access.imap/class.imapAccessDriver.php +++ b/core/src/plugins/access.imap/class.imapAccessDriver.php @@ -1,170 +1,178 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * AJXP_Plugin to browse a mailbox content (IMAP OR POP) - * @package AjaXplorer_Plugins - * @subpackage Access - */ -class imapAccessDriver extends fsAccessDriver -{ - /** - * @var Repository - */ - public $repository; - public $driverConf; - protected $wrapperClassName; - protected $urlBase; - - function initRepository(){ - if(is_array($this->pluginConf)){ - $this->driverConf = $this->pluginConf; - }else{ - $this->driverConf = array(); - } - - $wrapperData = $this->detectStreamWrapper(true); - $this->wrapperClassName = $wrapperData["classname"]; - $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); - if($this->repository->getOption("MAILBOX") != ""){ - //$this->urlBase .= "/INBOX"; - } - /* - if(!file_exists($this->urlBase)){ - throw new AJXP_Exception("Cannot find base path for your repository! Please check the configuration!"); - } - */ - } - - function performChecks(){ - if(!function_exists("imap_createmailbox")){ - throw new Exception("PHP Imap extension must be loaded to use this driver!"); - } - } - - public static function inverseSort($st1, $st2){ - return strnatcasecmp($st2, $st1); - } - - public static function sortInboxFirst($st1, $st2){ - if($st1 == "INBOX") return -1; - if($st2 == "INBOX") return 1; - return strcmp($st1, $st2); - } - - function switchAction($action, $httpVars, $fileVars){ - if($action == "ls"){ - $dir = $httpVars["dir"]; - if($dir == "/" || empty($dir)){ - // MAILBOXES CASE - $this->repository->addOption("PAGINATION_THRESHOLD", 500); - $this->driverConf["SCANDIR_RESULT_SORTFONC"] = array("imapAccessDriver", "sortInboxFirst"); - }else{ - // MAILS LISTING CASE - //$httpVars["dir"] = mb_convert_encoding($httpVars["dir"], "UTF7-IMAP", SystemTextEncoding::getEncoding()); - $this->driverConf["SCANDIR_RESULT_SORTFONC"] = array("imapAccessDriver", "inverseSort"); - } - } - parent::switchAction($action, $httpVars, $fileVars); - } - - /** - * - * @param AJXP_Node $ajxpNode - */ - public function enrichMetadata(&$ajxpNode){//, &$metadata, $wrapperClassName, &$realFile){ - $currentNode = $ajxpNode->getUrl(); - $metadata = $ajxpNode->metadata; - $parsed = parse_url($currentNode); - if( isSet($parsed["fragment"]) && strpos($parsed["fragment"], "attachments") === 0){ - list(, $attachmentId) = explode("/", $parsed["fragment"]); - $meta = imapAccessWrapper::getCurrentAttachmentsMetadata(); - if($meta != null){ - foreach ($meta as $attach){ - if($attach["x-attachment-id"] == $attachmentId){ - $metadata["text"] = $attach["filename"]; - $metadata["icon"] = AJXP_Utils::mimetype($attach["filename"], "image", false); - $metadata["mimestring"] = AJXP_Utils::mimetype($attach["filename"], "text", false); - } - } - } - } - - if(!$metadata["is_file"] && $currentNode != ""){ - $metadata["icon"] = "imap_images/ICON_SIZE/mail_folder_sent.png"; - } - if(basename($currentNode) == "INBOX"){ - $metadata["text"] = "Incoming Mails"; - } - if(strstr($currentNode, "__delim__")!==false){ - $parts = explode("/", $currentNode); - $metadata["text"] = str_replace("__delim__", "/", array_pop($parts)); - } - $ajxpNode->metadata = $metadata; - } - - public function attachmentDLName($currentNode, &$localName, $wrapperClassName){ - $parsed = parse_url($currentNode); - if( isSet($parsed["fragment"]) && strpos($parsed["fragment"], "attachments") === 0){ - list(, $attachmentId) = explode("/", $parsed["fragment"]); - $meta = imapAccessWrapper::getCurrentAttachmentsMetadata(); - if($meta == null){ - stat($currentNode); - $meta = imapAccessWrapper::getCurrentAttachmentsMetadata(); - } - if($meta != null){ - foreach ($meta as $attach){ - if($attach["x-attachment-id"] == $attachmentId){ - $localName = $attach["filename"]; - } - } - } - }else{ - $localName = basename($currentNode).".eml"; - } - } - - /** - * Parse - * @param DOMNode $contribNode - */ - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($contribNode->nodeName != "actions") return ; - $this->disableArchiveBrowsingContributions($contribNode); - } - - function filterNodeName($nodePath, $nodeName, &$isLeaf, $lsOptions){ - return true; - } - - function countFiles($dirName, $foldersOnly = false, $nonEmptyCheckOnly = false){ - if($foldersOnly) return 0; - // WILL USE IMAP FUNCTIONS TO COUNT; - $tmpHandle = opendir($dirName); - AJXP_Logger::debug("COUNT : ".imapAccessWrapper::getCurrentDirCount()); - return imapAccessWrapper::getCurrentDirCount(); - } - -} - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * AJXP_Plugin to browse a mailbox content (IMAP OR POP) + * @package AjaXplorer_Plugins + * @subpackage Access + */ +class imapAccessDriver extends fsAccessDriver +{ + /** + * @var Repository + */ + public $repository; + public $driverConf; + protected $wrapperClassName; + protected $urlBase; + + public function initRepository() + { + if (is_array($this->pluginConf)) { + $this->driverConf = $this->pluginConf; + } else { + $this->driverConf = array(); + } + + $wrapperData = $this->detectStreamWrapper(true); + $this->wrapperClassName = $wrapperData["classname"]; + $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); + if ($this->repository->getOption("MAILBOX") != "") { + //$this->urlBase .= "/INBOX"; + } + /* + if (!file_exists($this->urlBase)) { + throw new AJXP_Exception("Cannot find base path for your repository! Please check the configuration!"); + } + */ + } + + public function performChecks() + { + if (!function_exists("imap_createmailbox")) { + throw new Exception("PHP Imap extension must be loaded to use this driver!"); + } + } + + public static function inverseSort($st1, $st2) + { + return strnatcasecmp($st2, $st1); + } + + public static function sortInboxFirst($st1, $st2) + { + if($st1 == "INBOX") return -1; + if($st2 == "INBOX") return 1; + return strcmp($st1, $st2); + } + + public function switchAction($action, $httpVars, $fileVars) + { + if ($action == "ls") { + $dir = $httpVars["dir"]; + if ($dir == "/" || empty($dir)) { + // MAILBOXES CASE + $this->repository->addOption("PAGINATION_THRESHOLD", 500); + $this->driverConf["SCANDIR_RESULT_SORTFONC"] = array("imapAccessDriver", "sortInboxFirst"); + } else { + // MAILS LISTING CASE + //$httpVars["dir"] = mb_convert_encoding($httpVars["dir"], "UTF7-IMAP", SystemTextEncoding::getEncoding()); + $this->driverConf["SCANDIR_RESULT_SORTFONC"] = array("imapAccessDriver", "inverseSort"); + } + } + parent::switchAction($action, $httpVars, $fileVars); + } + + /** + * + * @param AJXP_Node $ajxpNode + */ + public function enrichMetadata(&$ajxpNode)//, &$metadata, $wrapperClassName, &$realFile) + { + $currentNode = $ajxpNode->getUrl(); + $metadata = $ajxpNode->metadata; + $parsed = parse_url($currentNode); + if ( isSet($parsed["fragment"]) && strpos($parsed["fragment"], "attachments") === 0) { + list(, $attachmentId) = explode("/", $parsed["fragment"]); + $meta = imapAccessWrapper::getCurrentAttachmentsMetadata(); + if ($meta != null) { + foreach ($meta as $attach) { + if ($attach["x-attachment-id"] == $attachmentId) { + $metadata["text"] = $attach["filename"]; + $metadata["icon"] = AJXP_Utils::mimetype($attach["filename"], "image", false); + $metadata["mimestring"] = AJXP_Utils::mimetype($attach["filename"], "text", false); + } + } + } + } + + if (!$metadata["is_file"] && $currentNode != "") { + $metadata["icon"] = "imap_images/ICON_SIZE/mail_folder_sent.png"; + } + if (basename($currentNode) == "INBOX") { + $metadata["text"] = "Incoming Mails"; + } + if (strstr($currentNode, "__delim__")!==false) { + $parts = explode("/", $currentNode); + $metadata["text"] = str_replace("__delim__", "/", array_pop($parts)); + } + $ajxpNode->metadata = $metadata; + } + + public function attachmentDLName($currentNode, &$localName, $wrapperClassName) + { + $parsed = parse_url($currentNode); + if ( isSet($parsed["fragment"]) && strpos($parsed["fragment"], "attachments") === 0) { + list(, $attachmentId) = explode("/", $parsed["fragment"]); + $meta = imapAccessWrapper::getCurrentAttachmentsMetadata(); + if ($meta == null) { + stat($currentNode); + $meta = imapAccessWrapper::getCurrentAttachmentsMetadata(); + } + if ($meta != null) { + foreach ($meta as $attach) { + if ($attach["x-attachment-id"] == $attachmentId) { + $localName = $attach["filename"]; + } + } + } + } else { + $localName = basename($currentNode).".eml"; + } + } + + /** + * Parse + * @param DOMNode $contribNode + */ + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if($contribNode->nodeName != "actions") return ; + $this->disableArchiveBrowsingContributions($contribNode); + } + + public function filterNodeName($nodePath, $nodeName, &$isLeaf, $lsOptions) + { + return true; + } + + public function countFiles($dirName, $foldersOnly = false, $nonEmptyCheckOnly = false) + { + if($foldersOnly) return 0; + // WILL USE IMAP FUNCTIONS TO COUNT; + $tmpHandle = opendir($dirName); + AJXP_Logger::debug("COUNT : ".imapAccessWrapper::getCurrentDirCount()); + return imapAccessWrapper::getCurrentDirCount(); + } + +} diff --git a/core/src/plugins/access.imap/class.imapAccessWrapper.php b/core/src/plugins/access.imap/class.imapAccessWrapper.php index f559c5aa12..3ec9ff9aba 100755 --- a/core/src/plugins/access.imap/class.imapAccessWrapper.php +++ b/core/src/plugins/access.imap/class.imapAccessWrapper.php @@ -27,442 +27,461 @@ function rejectEmpty($element){return !empty($element);} * @package AjaXplorer_Plugins * @subpackage Access */ -class imapAccessWrapper implements AjxpWrapper { - - var $ih; - var $host; - var $port; - var $username; - var $password; - var $path; - var $pop3; - // stuff for dir reading - var $dir; - var $pos; - // stuff for file reading - var $data; - var $gotbody; - var $size; - var $time; - - var $fragment; - var $mailbox; - - var $mailboxes; - var $currentAttachmentData; - - - private static $currentStream; - private static $currentRef; - private static $currentCount; - private static $delimiter; - private static $attachmentsMetadata; - - public static function closeStreamFunc(){ - if(self::$currentStream){ - AJXP_Logger::debug("Closing stream now!"); - imap_close(self::$currentStream); - } - } - - public static function getCurrentDirCount(){ - return self::$currentCount; - } - - public static function getCurrentAttachmentsMetadata(){ - return self::$attachmentsMetadata; - } - - function stream_open($path, $mode, $options, &$opened_path) { - // parse URL - $parts = parse_url($path); - $this->repositoryId = $parts["host"]; +class imapAccessWrapper implements AjxpWrapper +{ + public $ih; + public $host; + public $port; + public $username; + public $password; + public $path; + public $pop3; + // stuff for dir reading + public $dir; + public $pos; + // stuff for file reading + public $data; + public $gotbody; + public $size; + public $time; + + public $fragment; + public $mailbox; + + public $mailboxes; + public $currentAttachmentData; + + + private static $currentStream; + private static $currentRef; + private static $currentCount; + private static $delimiter; + private static $attachmentsMetadata; + + public static function closeStreamFunc() + { + if (self::$currentStream) { + AJXP_Logger::debug("Closing stream now!"); + imap_close(self::$currentStream); + } + } + + public static function getCurrentDirCount() + { + return self::$currentCount; + } + + public static function getCurrentAttachmentsMetadata() + { + return self::$attachmentsMetadata; + } + + public function stream_open($path, $mode, $options, &$opened_path) + { + // parse URL + $parts = parse_url($path); + $this->repositoryId = $parts["host"]; $mainCacheDir = (defined('AJXP_SHARED_CACHE_DIR')?AJXP_SHARED_CACHE_DIR:AJXP_CACHE_DIR); - if(!isset(self::$delimiter) && file_exists($mainCacheDir."/access.imap/mailbox_delim_".$this->repositoryId)){ - self::$delimiter = file_get_contents($mainCacheDir."/access.imap/mailbox_delim_".$this->repositoryId); - } - - $this->path = substr($parts["path"], 1); - //$this->mailbox = "INBOX"; - $pathParts = explode("/", $this->path); - $pathParts = array_filter($pathParts, "rejectEmpty"); - if(count($pathParts) > 1){ - $this->path = array_pop($pathParts); - $this->mailbox = implode("/", $pathParts); - }else if(count($pathParts) == 1){ - $this->mailbox = implode("/", $pathParts); - $this->path = ""; - }else{ - $this->mailbox = ""; - $this->path = ""; - } - $this->fragment = $parts["fragment"]; - if (empty ( $this->path ) && $mode !== 'np') { - return false; - } - if (!empty($this->mailbox)){ - $this->mailbox = mb_convert_encoding($this->mailbox, "UTF7-IMAP", SystemTextEncoding::getEncoding()); - $this->mailbox = str_replace("__delim__", (isSet(self::$delimiter)?self::$delimiter:"/"), $this->mailbox); - } - if(!empty($this->fragment) && strpos($this->fragment, "attachments") === 0 && strpos($this->fragment, "/")!== false){ - // remove fragment + if (!isset(self::$delimiter) && file_exists($mainCacheDir."/access.imap/mailbox_delim_".$this->repositoryId)) { + self::$delimiter = file_get_contents($mainCacheDir."/access.imap/mailbox_delim_".$this->repositoryId); + } + + $this->path = substr($parts["path"], 1); + //$this->mailbox = "INBOX"; + $pathParts = explode("/", $this->path); + $pathParts = array_filter($pathParts, "rejectEmpty"); + if (count($pathParts) > 1) { + $this->path = array_pop($pathParts); + $this->mailbox = implode("/", $pathParts); + } else if (count($pathParts) == 1) { + $this->mailbox = implode("/", $pathParts); + $this->path = ""; + } else { + $this->mailbox = ""; + $this->path = ""; + } + $this->fragment = $parts["fragment"]; + if (empty ( $this->path ) && $mode !== 'np') { + return false; + } + if (!empty($this->mailbox)) { + $this->mailbox = mb_convert_encoding($this->mailbox, "UTF7-IMAP", SystemTextEncoding::getEncoding()); + $this->mailbox = str_replace("__delim__", (isSet(self::$delimiter)?self::$delimiter:"/"), $this->mailbox); + } + if (!empty($this->fragment) && strpos($this->fragment, "attachments") === 0 && strpos($this->fragment, "/")!== false) { + // remove fragment $ar = explode("#", $path); - $mailPath = array_shift($ar); + $mailPath = array_shift($ar); $ar = explode("/", $this->fragment); - $attachmentId = array_pop($ar); - $this->currentAttachmentData = array("realPath" => $mailPath, "attachmentId" => $attachmentId); - // EXTRACT ATTACHMENT AND RETURN - require_once AJXP_INSTALL_PATH."/plugins/editor.eml/class.EmlParser.php"; - $emlParser = new EmlParser("", ""); - $attachMeta = array(); - $this->data = $emlParser->getAttachmentBody( - $this->currentAttachmentData["realPath"], - $this->currentAttachmentData["attachmentId"], - true, - $attachMeta - ); - if(self::$attachmentsMetadata == null){ - self::$attachmentsMetadata = array($attachMeta); - } - - $this->currentAttachmentData["size"] = strlen($this->data); - $this->pos = 0; - $this->size = strlen($this->data); - return true; - } - - // open IMAP connection - if(self::$currentStream != null){ - AJXP_Logger::debug("Using currently opened stream! ".print_r(self::$currentStream, true)); - $this->ih = self::$currentStream; - // Rewind everything - $this->dir_rewinddir(); - $this->stream_seek(0); - }else{ - $repository = ConfService::getRepositoryById($this->repositoryId); - $ssl = $repository->getOption("SSL") == "true" ? true: false ; - $this->pop3 = $repository->getOption("BOX_TYPE") == "pop3" ? true : false; - $this->host = $repository->getOption("HOST"); - $this->port = $repository->getOption("PORT"); - $this->username = $repository->getOption("USER"); - $this->password = $repository->getOption("PASS"); - $server = "{". $this->host . ":" . $this->port . "/".($this->pop3?"pop3/":"").($ssl?"ssl/novalidate-cert":"novalidate-cert")."}"; - self::$currentRef = $server; - AJXP_Logger::debug("Opening a new stream ".$server." with mailbox '".$this->mailbox."'"); - try{ - $this->ih = imap_open ( $server.$this->mailbox , $this->username, $this->password, (!$this->pop3 && empty($this->mailbox)?OP_HALFOPEN:NULL), 1); - }catch (Exception $e){ - throw new Exception($e->getMessage()." - imap errors : ".print_r(imap_errors(), true), $e->getCode()); - } - self::$currentStream = $this->ih; - register_shutdown_function(array("imapAccessWrapper", "closeStreamFunc")); - } - if ($this->ih) { - if (! empty ( $this->path )) { - list ( $stats, ) = imap_fetch_overview ( $this->ih, $this->path ); - $this->size = $stats->size; - $this->time = strtotime ( $stats->date ); - } - return true; - } else { - return false; - } - } - - function stream_close() { - if(empty($this->mailbox)){ - //self::$currentStream = null; - //imap_close ( $this->ih ); - } - if(!empty($this->currentAttachmentData)){ - $this->currentAttachmentBody = null; - } - } - - /* Smart reader, at first it only downloads the header to memory, but if a read request is made + $attachmentId = array_pop($ar); + $this->currentAttachmentData = array("realPath" => $mailPath, "attachmentId" => $attachmentId); + // EXTRACT ATTACHMENT AND RETURN + require_once AJXP_INSTALL_PATH."/plugins/editor.eml/class.EmlParser.php"; + $emlParser = new EmlParser("", ""); + $attachMeta = array(); + $this->data = $emlParser->getAttachmentBody( + $this->currentAttachmentData["realPath"], + $this->currentAttachmentData["attachmentId"], + true, + $attachMeta + ); + if (self::$attachmentsMetadata == null) { + self::$attachmentsMetadata = array($attachMeta); + } + + $this->currentAttachmentData["size"] = strlen($this->data); + $this->pos = 0; + $this->size = strlen($this->data); + return true; + } + + // open IMAP connection + if (self::$currentStream != null) { + AJXP_Logger::debug("Using currently opened stream! ".print_r(self::$currentStream, true)); + $this->ih = self::$currentStream; + // Rewind everything + $this->dir_rewinddir(); + $this->stream_seek(0); + } else { + $repository = ConfService::getRepositoryById($this->repositoryId); + $ssl = $repository->getOption("SSL") == "true" ? true: false ; + $this->pop3 = $repository->getOption("BOX_TYPE") == "pop3" ? true : false; + $this->host = $repository->getOption("HOST"); + $this->port = $repository->getOption("PORT"); + $this->username = $repository->getOption("USER"); + $this->password = $repository->getOption("PASS"); + $server = "{". $this->host . ":" . $this->port . "/".($this->pop3?"pop3/":"").($ssl?"ssl/novalidate-cert":"novalidate-cert")."}"; + self::$currentRef = $server; + AJXP_Logger::debug("Opening a new stream ".$server." with mailbox '".$this->mailbox."'"); + try { + $this->ih = imap_open ( $server.$this->mailbox , $this->username, $this->password, (!$this->pop3 && empty($this->mailbox)?OP_HALFOPEN:NULL), 1); + } catch (Exception $e) { + throw new Exception($e->getMessage()." - imap errors : ".print_r(imap_errors(), true), $e->getCode()); + } + self::$currentStream = $this->ih; + register_shutdown_function(array("imapAccessWrapper", "closeStreamFunc")); + } + if ($this->ih) { + if (! empty ( $this->path )) { + list ( $stats, ) = imap_fetch_overview ( $this->ih, $this->path ); + $this->size = $stats->size; + $this->time = strtotime ( $stats->date ); + } + return true; + } else { + return false; + } + } + + public function stream_close() + { + if (empty($this->mailbox)) { + //self::$currentStream = null; + //imap_close ( $this->ih ); + } + if (!empty($this->currentAttachmentData)) { + $this->currentAttachmentBody = null; + } + } + + /* Smart reader, at first it only downloads the header to memory, but if a read request is made beyond the header, we download the rest of the body */ - function stream_read($count) { - - //AJXP_Logger::debug("READING $count FROM $this->path", $this->currentAttachmentData); - if(!empty($this->currentAttachmentData)){ - if(empty($this->data)){ - AJXP_Logger::debug("Attachement", $this->currentAttachmentData); - // EXTRACT ATTACHMENT AND RETURN - require_once AJXP_INSTALL_PATH."/plugins/editor.eml/class.EmlParser.php"; - $emlParser = new EmlParser("", ""); - $attachMeta = array(); - $this->data = $emlParser->getAttachmentBody( - $this->currentAttachmentData["realPath"], - $this->currentAttachmentData["attachmentId"], - true, - $attachMeta - ); - $this->pos = 0; - $this->size = strlen($this->data); - } - }else{ - // smart... only download the header WHEN data is requested - if (empty ( $this->data )) { - $this->pos = 0; - $this->gotbody = false; - $this->data = imap_fetchheader ( $this->ih, $this->path ); - } - // only download the body once we read past the header - if ($this->gotbody == false && ($this->pos + $count > strlen ( $this->data )) && $this->fragment != "header") { - $this->gotbody = true; - $this->data .= imap_body ( $this->ih, $this->path ); - $this->size = strlen ( $this->data ); - } - } - if ($this->pos >= $this->size) { - return false; - } else { - $d = substr ( $this->data, $this->pos, $count ); - if ($this->pos + $count > strlen ( $this->data )) { - $this->pos = strlen ( $this->data ); - } else { - $this->pos = $this->pos + $count; - } - return $d; - } - } - - /* Can't write to POP3 */ - function stream_write($data) { - return false; - } - - function stream_eof() { - if ($this->pos >= $this->size) { - return true; - } else { - return false; - } - } - - function stream_tell() { - return $this->pos; - } - - public function stream_seek($offset , $whence = SEEK_SET){ - switch ($whence) { - case SEEK_SET : - $this->pos = $offset; - break; - case SEEK_CUR : - $this->pos = $this->pos + $offset; - break; - case SEEK_END : - $this->pos = $this->size + $offset; - break; - } - } - - function stream_stat() { - $keys = array('dev' => 0, 'ino' => 0, 'mode' => 33216, 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => $this->size, 'atime' => $this->time, 'mtime' => $this->time, 'ctime' => $this->time, 'blksize' => 0, 'blocks' => 0 ); - return $keys; - } - - function dir_opendir($path, $options) { - // Reset - self::$attachmentsMetadata = null; - - $st = ''; - $stream = $this->stream_open ( $path, 'np', $options, $st ); - if (!$stream) { - return false; - } - if(empty($this->mailbox)){ - // We are browsing root, we want the list of mailboxes - $this->mailboxes = imap_getmailboxes($this->ih, self::$currentRef, "*"); - $this->dir = count($this->mailboxes); - self::$currentCount = count($this->mailboxes); - $this->pos = $this->dir - 1; - }else if($this->fragment == "attachments"){ - require_once AJXP_INSTALL_PATH.'/plugins/editor.eml/class.EmlParser.php'; - $parser = new EmlParser("", ""); + public function stream_read($count) + { + //AJXP_Logger::debug("READING $count FROM $this->path", $this->currentAttachmentData); + if (!empty($this->currentAttachmentData)) { + if (empty($this->data)) { + AJXP_Logger::debug("Attachement", $this->currentAttachmentData); + // EXTRACT ATTACHMENT AND RETURN + require_once AJXP_INSTALL_PATH."/plugins/editor.eml/class.EmlParser.php"; + $emlParser = new EmlParser("", ""); + $attachMeta = array(); + $this->data = $emlParser->getAttachmentBody( + $this->currentAttachmentData["realPath"], + $this->currentAttachmentData["attachmentId"], + true, + $attachMeta + ); + $this->pos = 0; + $this->size = strlen($this->data); + } + } else { + // smart... only download the header WHEN data is requested + if (empty ( $this->data )) { + $this->pos = 0; + $this->gotbody = false; + $this->data = imap_fetchheader ( $this->ih, $this->path ); + } + // only download the body once we read past the header + if ($this->gotbody == false && ($this->pos + $count > strlen ( $this->data )) && $this->fragment != "header") { + $this->gotbody = true; + $this->data .= imap_body ( $this->ih, $this->path ); + $this->size = strlen ( $this->data ); + } + } + if ($this->pos >= $this->size) { + return false; + } else { + $d = substr ( $this->data, $this->pos, $count ); + if ($this->pos + $count > strlen ( $this->data )) { + $this->pos = strlen ( $this->data ); + } else { + $this->pos = $this->pos + $count; + } + return $d; + } + } + + /* Can't write to POP3 */ + public function stream_write($data) + { + return false; + } + + public function stream_eof() + { + if ($this->pos >= $this->size) { + return true; + } else { + return false; + } + } + + public function stream_tell() + { + return $this->pos; + } + + public function stream_seek($offset , $whence = SEEK_SET) + { + switch ($whence) { + case SEEK_SET : + $this->pos = $offset; + break; + case SEEK_CUR : + $this->pos = $this->pos + $offset; + break; + case SEEK_END : + $this->pos = $this->size + $offset; + break; + } + } + + public function stream_stat() + { + $keys = array('dev' => 0, 'ino' => 0, 'mode' => 33216, 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => $this->size, 'atime' => $this->time, 'mtime' => $this->time, 'ctime' => $this->time, 'blksize' => 0, 'blocks' => 0 ); + return $keys; + } + + public function dir_opendir($path, $options) + { + // Reset + self::$attachmentsMetadata = null; + + $st = ''; + $stream = $this->stream_open ( $path, 'np', $options, $st ); + if (!$stream) { + return false; + } + if (empty($this->mailbox)) { + // We are browsing root, we want the list of mailboxes + $this->mailboxes = imap_getmailboxes($this->ih, self::$currentRef, "*"); + $this->dir = count($this->mailboxes); + self::$currentCount = count($this->mailboxes); + $this->pos = $this->dir - 1; + } else if ($this->fragment == "attachments") { + require_once AJXP_INSTALL_PATH.'/plugins/editor.eml/class.EmlParser.php'; + $parser = new EmlParser("", ""); $ar = explode("#", $path); - $path = array_shift($ar);// remove fragment - self::$attachmentsMetadata = array(); - $parser->listAttachments($path, true, self::$attachmentsMetadata); - $this->dir = count(self::$attachmentsMetadata); - $this->pos = $this->dir - 1; - self::$currentCount = $this->dir; - - }else{ - // We are in a mailbox, we want the messages number - $this->dir = imap_num_msg ( $this->ih ); - self::$currentCount = $this->dir; - $this->pos = $this->dir; - } - $this->stream_close (); - return true; - } - - function dir_closedir() { - // do nothing. - // $this->stream_close(); - $this->mailboxes = null; - } - - function dir_readdir() { - if($this->mailboxes){ - if($this->pos < 0) return false; - else{ - $obj = $this->mailboxes[$this->pos]; - $this->pos --; - $x = $obj->name; - $x = mb_convert_encoding( $x, "UTF-8", "UTF7-IMAP" ); - $x = str_replace(self::$currentRef, "", $x); + $path = array_shift($ar);// remove fragment + self::$attachmentsMetadata = array(); + $parser->listAttachments($path, true, self::$attachmentsMetadata); + $this->dir = count(self::$attachmentsMetadata); + $this->pos = $this->dir - 1; + self::$currentCount = $this->dir; + + } else { + // We are in a mailbox, we want the messages number + $this->dir = imap_num_msg ( $this->ih ); + self::$currentCount = $this->dir; + $this->pos = $this->dir; + } + $this->stream_close (); + return true; + } + + public function dir_closedir() + { + // do nothing. + // $this->stream_close(); + $this->mailboxes = null; + } + + public function dir_readdir() + { + if ($this->mailboxes) { + if($this->pos < 0) return false; + else{ + $obj = $this->mailboxes[$this->pos]; + $this->pos --; + $x = $obj->name; + $x = mb_convert_encoding( $x, "UTF-8", "UTF7-IMAP" ); + $x = str_replace(self::$currentRef, "", $x); $mainCacheDir = (defined('AJXP_SHARED_CACHE_DIR')?AJXP_SHARED_CACHE_DIR:AJXP_CACHE_DIR); - if(!isSet(self::$delimiter) && !file_exists($mainCacheDir."/access.imap/mailbox_delim_".$this->repositoryId)){ + if (!isSet(self::$delimiter) && !file_exists($mainCacheDir."/access.imap/mailbox_delim_".$this->repositoryId)) { if(!is_dir($mainCacheDir ."/access.imap")) mkdir($mainCacheDir."/access.imap"); - file_put_contents($mainCacheDir."/access.imap/mailbox_delim_".$this->repositoryId, $obj->delimiter); - self::$delimiter = $obj->delimiter; - } - $x = str_replace($obj->delimiter, "__delim__", $x); - } - }else if(self::$attachmentsMetadata != null){ - if($this->pos < 0) return false; - $x = self::$attachmentsMetadata[$this->pos]["x-attachment-id"]; - $this->pos--; - }else{ - if ($this->pos < 1) { - return false; - } else { - $x = $this->pos; - $this->pos --; - //$x .= "#header"; - } - } - return $x; - } - - function dir_rewinddir() { - if(empty($this->mailbox)){ - $this->pos = $this->dir; - }else{ - $this->pos = count($this->mailboxes) - 1; - } - } - - function url_stat($path, $flags) { - $emptyString = ''; - if ($this->stream_open ( $path, 'np', $flags, $emptyString)) { - if(!empty($this->path) && empty($this->currentAttachmentData)){ - // Mail - //$stats = array(); - if(empty($this->size) && empty($this->time)){ - list ( $stats, ) = imap_fetch_overview ( $this->ih, $this->path ); - $this->size = $stats->size; - $this->time = strtotime ( $stats->date ); - } - $keys = array( - 'dev' => 0, - 'ino' => 0, - 'mode' => 33216, - 'nlink' => 0, - 'uid' => 0, - 'gid' => 0, - 'rdev' => 0, - 'size' => $this->size, - 'atime' => $this->time, - 'mtime' => $this->time, - 'ctime' => $this->time, - 'blksize' => 0, - 'blocks' => 0 ); - }else{ - // BOX - if(empty($this->currentAttachmentData) && !empty($this->mailbox) && !$this->pop3){ - // GET LAST MESSAGE - imap_reopen($this->ih, self::$currentRef.$this->mailbox); - $last = imap_num_msg($this->ih); - //AJXP_Logger::debug("Should get mailbox data ".self::$currentRef.$this->mailbox . $last); - list ( $stats, ) = imap_fetch_overview ( $this->ih, $last ); - $this->size = $stats->size; - $this->time = strtotime ( $stats->date ); - } - $keys = array( - 'dev' => 0, - 'ino' => 0, - 'mode' => (empty($this->currentAttachmentData)?(33216 | 0040000):33216), - 'nlink' => 0, - 'uid' => 0, - 'gid' => 0, - 'rdev' => 0, - 'size' => (!empty($this->currentAttachmentData)?$this->currentAttachmentData["size"]:0), - 'atime' => (!empty($this->time)?$this->time:0), - 'mtime' => (!empty($this->time)?$this->time:0), - 'ctime' => (!empty($this->time)?$this->time:0), - 'blksize' => 0, - 'blocks' => 0 - ); - } - $this->stream_close (); - return $keys; - } else { - return false; - } - } - - /* Delete an email from the mailbox */ - function unlink($path) { - $st=''; - if ($this->stream_open ( $path, '', '', $st )) { - imap_delete ( $this->ih, $this->path ); - $this->stream_close (); - return true; - } else { - return false; - } - } - - - /** - * Get a "usable" reference to a file : the real file or a tmp copy. - * - * @param unknown_type $path - */ - public static function getRealFSReference($path){ - return $path; + file_put_contents($mainCacheDir."/access.imap/mailbox_delim_".$this->repositoryId, $obj->delimiter); + self::$delimiter = $obj->delimiter; + } + $x = str_replace($obj->delimiter, "__delim__", $x); + } + } else if (self::$attachmentsMetadata != null) { + if($this->pos < 0) return false; + $x = self::$attachmentsMetadata[$this->pos]["x-attachment-id"]; + $this->pos--; + } else { + if ($this->pos < 1) { + return false; + } else { + $x = $this->pos; + $this->pos --; + //$x .= "#header"; + } + } + return $x; + } + + public function dir_rewinddir() + { + if (empty($this->mailbox)) { + $this->pos = $this->dir; + } else { + $this->pos = count($this->mailboxes) - 1; + } + } + + public function url_stat($path, $flags) + { + $emptyString = ''; + if ($this->stream_open ( $path, 'np', $flags, $emptyString)) { + if (!empty($this->path) && empty($this->currentAttachmentData)) { + // Mail + //$stats = array(); + if (empty($this->size) && empty($this->time)) { + list ( $stats, ) = imap_fetch_overview ( $this->ih, $this->path ); + $this->size = $stats->size; + $this->time = strtotime ( $stats->date ); + } + $keys = array( + 'dev' => 0, + 'ino' => 0, + 'mode' => 33216, + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => $this->size, + 'atime' => $this->time, + 'mtime' => $this->time, + 'ctime' => $this->time, + 'blksize' => 0, + 'blocks' => 0 ); + } else { + // BOX + if (empty($this->currentAttachmentData) && !empty($this->mailbox) && !$this->pop3) { + // GET LAST MESSAGE + imap_reopen($this->ih, self::$currentRef.$this->mailbox); + $last = imap_num_msg($this->ih); + //AJXP_Logger::debug("Should get mailbox data ".self::$currentRef.$this->mailbox . $last); + list ( $stats, ) = imap_fetch_overview ( $this->ih, $last ); + $this->size = $stats->size; + $this->time = strtotime ( $stats->date ); + } + $keys = array( + 'dev' => 0, + 'ino' => 0, + 'mode' => (empty($this->currentAttachmentData)?(33216 | 0040000):33216), + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => (!empty($this->currentAttachmentData)?$this->currentAttachmentData["size"]:0), + 'atime' => (!empty($this->time)?$this->time:0), + 'mtime' => (!empty($this->time)?$this->time:0), + 'ctime' => (!empty($this->time)?$this->time:0), + 'blksize' => 0, + 'blocks' => 0 + ); + } + $this->stream_close (); + return $keys; + } else { + return false; + } + } + + /* Delete an email from the mailbox */ + public function unlink($path) + { + $st=''; + if ($this->stream_open ( $path, '', '', $st )) { + imap_delete ( $this->ih, $this->path ); + $this->stream_close (); + return true; + } else { + return false; + } + } + + + /** + * Get a "usable" reference to a file : the real file or a tmp copy. + * + * @param unknown_type $path + */ + public static function getRealFSReference($path) + { + return $path; } - + /** * Read a file (by chunks) and copy the data directly inside the given stream. * * @param unknown_type $path * @param unknown_type $stream */ - public static function copyFileInStream($path, $stream){ - //return $path; - $fp = fopen($path, 'r'); - $bufferSize = 4096 * 8; - if($fp){ - $i = 0; - while(!feof($fp)){ - $data = fread($fp, $bufferSize); - fwrite($stream, $data, strlen($data)); - //if($i > 10) break; - //$i++; - } - fclose($fp); - } + public static function copyFileInStream($path, $stream) + { + //return $path; + $fp = fopen($path, 'r'); + $bufferSize = 4096 * 8; + if ($fp) { + $i = 0; + while (!feof($fp)) { + $data = fread($fp, $bufferSize); + fwrite($stream, $data, strlen($data)); + //if($i > 10) break; + //$i++; + } + fclose($fp); + } } - - public static function isRemote(){ - return true; + + public static function isRemote() + { + return true; } - + /** * Chmod implementation for this type of access. * * @param unknown_type $path * @param unknown_type $chmodValue */ - public static function changeMode($path, $chmodValue){ - + public static function changeMode($path, $chmodValue) + { } - + /** * Enter description here... * @@ -471,8 +490,8 @@ public static function changeMode($path, $chmodValue){ * @param int $options * @return bool */ - public function mkdir($path , $mode , $options){ - + public function mkdir($path , $mode , $options) + { } /** @@ -482,8 +501,8 @@ public function mkdir($path , $mode , $options){ * @param string $path_to * @return bool */ - public function rename($path_from , $path_to){ - + public function rename($path_from , $path_to) + { } /** @@ -493,8 +512,8 @@ public function rename($path_from , $path_to){ * @param int $options * @return bool */ - public function rmdir($path , $options){ - + public function rmdir($path , $options) + { } @@ -503,12 +522,10 @@ public function rmdir($path , $options){ * * @return bool */ - public function stream_flush(){ - - } + public function stream_flush() + { + } + - - -} -?> \ No newline at end of file +} diff --git a/core/src/plugins/access.imap/manifest.xml b/core/src/plugins/access.imap/manifest.xml index 4d645a0374..3aa1da5795 100755 --- a/core/src/plugins/access.imap/manifest.xml +++ b/core/src/plugins/access.imap/manifest.xml @@ -3,8 +3,8 @@ - - + + @@ -28,10 +28,10 @@ - +
    - \ No newline at end of file + diff --git a/core/src/plugins/access.imap/resources/i18n/conf/en.php b/core/src/plugins/access.imap/resources/i18n/conf/en.php index d4d9fb68be..2554bed557 100644 --- a/core/src/plugins/access.imap/resources/i18n/conf/en.php +++ b/core/src/plugins/access.imap/resources/i18n/conf/en.php @@ -45,4 +45,3 @@ "#Items per page" => "#Items per page", "Once in pagination mode, number of items to display per page." => "Once in pagination mode, number of items to display per page.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.imap/resources/i18n/conf/fr.php b/core/src/plugins/access.imap/resources/i18n/conf/fr.php index 8257482508..c9130dcd44 100644 --- a/core/src/plugins/access.imap/resources/i18n/conf/fr.php +++ b/core/src/plugins/access.imap/resources/i18n/conf/fr.php @@ -45,4 +45,3 @@ "#Items per page" => "Elements par page", "Once in pagination mode, number of items to display per page." => "Nombre d'items par page.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.imap/resources/i18n/conf/pt.php b/core/src/plugins/access.imap/resources/i18n/conf/pt.php index f9e35135de..0865026b2a 100644 --- a/core/src/plugins/access.imap/resources/i18n/conf/pt.php +++ b/core/src/plugins/access.imap/resources/i18n/conf/pt.php @@ -45,4 +45,3 @@ "#Items per page" => "#Itens por página", "Once in pagination mode, number of items to display per page." => "Uma vez em modo paginação, o número de itens a mostrar por página.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.jsapi/class.jsapiAccessDriver.php b/core/src/plugins/access.jsapi/class.jsapiAccessDriver.php index e999c86887..1c49d7204a 100644 --- a/core/src/plugins/access.jsapi/class.jsapiAccessDriver.php +++ b/core/src/plugins/access.jsapi/class.jsapiAccessDriver.php @@ -1,76 +1,75 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * AJXP_Plugin to send a javascript source to the browser - * @package AjaXplorer_Plugins - * @subpackage Access - */ -class jsapiAccessDriver extends AbstractAccessDriver{ - - public function switchAction($action, $httpVars, $fileVars){ - - switch ($action){ - case "get_js_source" : - $jsName = AJXP_Utils::decodeSecureMagic($httpVars["object_name"]); - $jsType = $httpVars["object_type"]; // class or interface? - $fName = "class.".strtolower($jsName).".js"; - if($jsName == "Splitter"){ - $fName = "splitter.js"; - } - if(!defined("CLIENT_RESOURCES_FOLDER")){ - define("CLIENT_RESOURCES_FOLDER", AJXP_PLUGINS_FOLDER."/gui.ajax/res"); - } - // Locate the file class.ClassName.js - if($jsType == "class"){ - $searchLocations = array( - CLIENT_RESOURCES_FOLDER."/js/ajaxplorer", - CLIENT_RESOURCES_FOLDER."/js/lib", - AJXP_INSTALL_PATH."/plugins/" - ); - }else if($jsType == "interface"){ - $searchLocations = array( - CLIENT_RESOURCES_FOLDER."/js/ajaxplorer/interfaces", - ); - } - foreach ($searchLocations as $location){ - $dir_iterator = new RecursiveDirectoryIterator($location); - $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST); - // could use CHILD_FIRST if you so wish - $break = false; - foreach ($iterator as $file) { - if(strtolower(basename($file->getPathname())) == $fName){ - HTMLWriter::charsetHeader("text/plain", "utf-8"); - echo(file_get_contents($file->getPathname())); - $break = true; - break; - } - } - if($break) break; - } - break; - } - - } - -} -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * AJXP_Plugin to send a javascript source to the browser + * @package AjaXplorer_Plugins + * @subpackage Access + */ +class jsapiAccessDriver extends AbstractAccessDriver +{ + public function switchAction($action, $httpVars, $fileVars) + { + switch ($action) { + case "get_js_source" : + $jsName = AJXP_Utils::decodeSecureMagic($httpVars["object_name"]); + $jsType = $httpVars["object_type"]; // class or interface? + $fName = "class.".strtolower($jsName).".js"; + if ($jsName == "Splitter") { + $fName = "splitter.js"; + } + if (!defined("CLIENT_RESOURCES_FOLDER")) { + define("CLIENT_RESOURCES_FOLDER", AJXP_PLUGINS_FOLDER."/gui.ajax/res"); + } + // Locate the file class.ClassName.js + if ($jsType == "class") { + $searchLocations = array( + CLIENT_RESOURCES_FOLDER."/js/ajaxplorer", + CLIENT_RESOURCES_FOLDER."/js/lib", + AJXP_INSTALL_PATH."/plugins/" + ); + } else if ($jsType == "interface") { + $searchLocations = array( + CLIENT_RESOURCES_FOLDER."/js/ajaxplorer/interfaces", + ); + } + foreach ($searchLocations as $location) { + $dir_iterator = new RecursiveDirectoryIterator($location); + $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST); + // could use CHILD_FIRST if you so wish + $break = false; + foreach ($iterator as $file) { + if (strtolower(basename($file->getPathname())) == $fName) { + HTMLWriter::charsetHeader("text/plain", "utf-8"); + echo(file_get_contents($file->getPathname())); + $break = true; + break; + } + } + if($break) break; + } + break; + } + + } + +} diff --git a/core/src/plugins/access.jsapi/i18n/conf/en.php b/core/src/plugins/access.jsapi/i18n/conf/en.php index 6d49df939a..1578555a7c 100644 --- a/core/src/plugins/access.jsapi/i18n/conf/en.php +++ b/core/src/plugins/access.jsapi/i18n/conf/en.php @@ -22,4 +22,3 @@ "Javascript Api Browser" => "Javascript Api Browser", "Browse AjaXplorer Javascript classes and interfaces. Helper for developpers, but also good demonstration of how Ajaxplorer data can be fed by something different than a remote server filesystem!" => "Browse AjaXplorer Javascript classes and interfaces. Helper for developpers, but also good demonstration of how Ajaxplorer data can be fed by something different than a remote server filesystem!", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.jsapi/i18n/conf/fr.php b/core/src/plugins/access.jsapi/i18n/conf/fr.php index ae67b43ebc..e17addab75 100644 --- a/core/src/plugins/access.jsapi/i18n/conf/fr.php +++ b/core/src/plugins/access.jsapi/i18n/conf/fr.php @@ -22,4 +22,3 @@ "Javascript Api Browser" => "Navigateur d'Api Javascript", "Browse AjaXplorer Javascript classes and interfaces. Helper for developpers, but also good demonstration of how Ajaxplorer data can be fed by something different than a remote server filesystem!" => "Lister les classes et interfaces javascript et leur methodes, avec affichage du code. Pratique non seulement pour le développement, mais aussi comme démonstration de l'utilisation d'AjaXplorer pour browser d'autres types de données.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.jsapi/i18n/de.php b/core/src/plugins/access.jsapi/i18n/de.php index b3bb1c49ea..72390f7d7d 100644 --- a/core/src/plugins/access.jsapi/i18n/de.php +++ b/core/src/plugins/access.jsapi/i18n/de.php @@ -1,7 +1,6 @@ - "Klassen und Schnittstellen", -"2" => "Eigenschaften und Methoden", -"3" => "Quelltext" -); -?> + "Klassen und Schnittstellen", +"2" => "Eigenschaften und Methoden", +"3" => "Quelltext" +); diff --git a/core/src/plugins/access.jsapi/i18n/en.php b/core/src/plugins/access.jsapi/i18n/en.php index 31d66f62a4..a5598ad400 100644 --- a/core/src/plugins/access.jsapi/i18n/en.php +++ b/core/src/plugins/access.jsapi/i18n/en.php @@ -1,7 +1,6 @@ - "Classes and Interfaces", -"2" => "Properties and Methods", -"3" => "Source File" -); -?> \ No newline at end of file + "Classes and Interfaces", +"2" => "Properties and Methods", +"3" => "Source File" +); diff --git a/core/src/plugins/access.jsapi/i18n/fr.php b/core/src/plugins/access.jsapi/i18n/fr.php index 0544d80045..b6e101f965 100644 --- a/core/src/plugins/access.jsapi/i18n/fr.php +++ b/core/src/plugins/access.jsapi/i18n/fr.php @@ -23,4 +23,3 @@ "2" => "Properties and Methods", "3" => "Source File", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.jsapi/i18n/si.php b/core/src/plugins/access.jsapi/i18n/si.php index 0c58b03c0f..2267fd250f 100644 --- a/core/src/plugins/access.jsapi/i18n/si.php +++ b/core/src/plugins/access.jsapi/i18n/si.php @@ -1,27 +1,26 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - // Slovenian translation: April 21 2011 by Vladimir Bohinc (vladimir.bohinc@gmail.com) -$mess = array( -"1" => "Razredi in vmesniki", -"2" => "Lastnosti in metode", -"3" => "Izvorna koda" -); -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + // Slovenian translation: April 21 2011 by Vladimir Bohinc (vladimir.bohinc@gmail.com) +$mess = array( +"1" => "Razredi in vmesniki", +"2" => "Lastnosti in metode", +"3" => "Izvorna koda" +); diff --git a/core/src/plugins/access.jsapi/manifest.xml b/core/src/plugins/access.jsapi/manifest.xml index 84301db852..dca8880321 100644 --- a/core/src/plugins/access.jsapi/manifest.xml +++ b/core/src/plugins/access.jsapi/manifest.xml @@ -1,99 +1,99 @@ - - - - - Charles du Jeu - - - - - - - - - - - - - - - - - - - - - - - - - - - 0){ - path = window.actionArguments[0]; - if(Object.isString(path)){path = new AjxpNode(path,false,getBaseName(path));} - }else{ - userSelection = ajaxplorer.getUserSelection(); - if(userSelection && userSelection.isUnique() && (userSelection.hasDir() || userSelection.hasMime("AJXP_MIMES_ZIP".split(",")))){ - path = userSelection.getUniqueNode(); - } - } - if(path){ - ajaxplorer.updateContextData(path); - } - ]]> - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + Charles du Jeu + + + + + + + + + + + + + + + + + + + + + + + + + + + 0){ + path = window.actionArguments[0]; + if(Object.isString(path)){path = new AjxpNode(path,false,getBaseName(path));} + }else{ + userSelection = ajaxplorer.getUserSelection(); + if(userSelection && userSelection.isUnique() && (userSelection.hasDir() || userSelection.hasMime("AJXP_MIMES_ZIP".split(",")))){ + path = userSelection.getUniqueNode(); + } + } + if(path){ + ajaxplorer.updateContextData(path); + } + ]]> + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/src/plugins/access.mysql/class.mysqlAccessDriver.php b/core/src/plugins/access.mysql/class.mysqlAccessDriver.php index a46459254f..4de4e19274 100644 --- a/core/src/plugins/access.mysql/class.mysqlAccessDriver.php +++ b/core/src/plugins/access.mysql/class.mysqlAccessDriver.php @@ -1,656 +1,662 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * @package AjaXplorer_Plugins - * @subpackage Access - */ -class mysqlAccessDriver extends AbstractAccessDriver -{ - /** The user name */ - var $user; - /** The user password */ - var $password; - - function initRepository(){ - $this->user = $this->repository->getOption("DB_USER"); - $this->password = $this->repository->getOption("DB_PASS"); - $link = $this->createDbLink(); - $this->closeDbLink($link); - } - - - function createDbLink(){ - $link = FALSE; - //Connects to the MySQL Database. - $host = $this->repository->getOption("DB_HOST"); - $dbname = $this->repository->getOption("DB_NAME"); - $link = @mysql_connect($host, $this->user, $this->password); - if(!$link) { - throw new AJXP_Exception("Cannot connect to server!"); - } - if(!@mysql_select_db($dbname, $link)){ - throw new AJXP_Exception("Cannot find database!"); - } - return $link; - } - - function closeDbLink($link){ - if(!mysql_close($link)){ - throw new AJXP_Exception("Cannot close connection!"); - } - } - - function switchAction($action, $httpVars, $fileVars){ - $repo = ConfService::getRepository(); - if(!isSet($this->actions[$action])) return; - parent::accessPreprocess($action, $httpVars, $fileVars); - $xmlBuffer = ""; - foreach($httpVars as $getName=>$getValue){ - $$getName = AJXP_Utils::securePath($getValue); - } - $selection = new UserSelection(); - $selection->initFromHttpVars($httpVars); - if(isSet($dir) && $action != "upload") { - $safeDir = $dir; - $dir = SystemTextEncoding::fromUTF8($dir); - } - // FILTER DIR PAGINATION ANCHOR - if(isSet($dir) && strstr($dir, "%23")!==false){ - $parts = explode("%23", $dir); - $dir = $parts[0]; - $page = $parts[1]; - } - if(isSet($dest)) { - $dest = SystemTextEncoding::fromUTF8($dest); - } - $mess = ConfService::getMessages(); - - switch($action) - { - - //------------------------------------ - // ONLINE EDIT - //------------------------------------ - case "edit_record"; - $isNew = false; - if(isSet($record_is_new) && $record_is_new == "true") $isNew = true; - $tableName = $_POST["table_name"]; - $pkName = $_POST["pk_name"]; - $query = ""; - $arrValues = array(); - foreach ($_POST as $key=>$value){ - if(substr($key, 0, strlen("ajxp_mysql_")) == "ajxp_mysql_"){ - $newKey = substr($key, strlen("ajxp_mysql_")); - $arrValues[$newKey] = $value; - } - } - if($isNew){ - $string = ""; - $index = 0; - foreach ($arrValues as $k=>$v){ - // CHECK IF AUTO KEY!!! - $string .= "'".addslashes(SystemTextEncoding::fromUTF8($v))."'"; - if($index < count($arrValues)-1) $string.=","; - $index++; - } - $query = "INSERT INTO $tableName VALUES ($string)"; - }else{ - $string = ""; - $index = 0; - foreach ($arrValues as $k=>$v){ - if($k == $pkName){ - $pkValue = $v; - }else{ - $string .= $k."='".addslashes(SystemTextEncoding::fromUTF8($v))."'"; - if($indexcreateDbLink(); - $res = $this->execQuery($query); - $this->closeDbLink($link); - - if(is_a($res, "AJXP_Exception")){ - $errorMessage = $res->messageId; - }else{ - $logMessage = $query; - $reload_file_list = true; - } - break; - - //------------------------------------ - // CHANGE COLUMNS OR CREATE TABLE - //------------------------------------ - case "edit_table": - $link = $this->createDbLink(); - if(isSet($httpVars["current_table"])){ - if(isSet($httpVars["delete_column"])){ - $query = "ALTER TABLE ".$httpVars["current_table"]." DROP COLUMN ".$httpVars["delete_column"]; - $res = $this->execQuery($query); - if(is_a($res, "AJXP_Exception")){ - $errorMessage = $res->messageId; - }else{ - $logMessage = $query; - $reload_file_list = true; - } - $this->closeDbLink($link); - break; - } - if(isSet($httpVars["add_column"])){ - $defString = $this->makeColumnDef($httpVars, "add_field_"); - $query = "ALTER TABLE ".$httpVars["current_table"]." ADD COLUMN ($defString)"; - if(isSet($httpVars["add_field_pk"]) && $httpVars["add_field_pk"]=="1"){ - $query.= ", ADD PRIMARY KEY (".$httpVars["add_field_name"].")"; - } - if(isSet($httpVars["add_field_index"]) && $httpVars["add_field_index"]=="1"){ - $query.= ", ADD INDEX (".$httpVars["add_field_name"].")"; - } - if(isSet($httpVars["add_field_uniq"]) && $httpVars["add_field_uniq"]=="1"){ - $query.= ", ADD UNIQUE (".$httpVars["add_field_name"].")"; - } - $res = $this->execQuery($query); - if(is_a($res, "AJXP_Exception")){ - $errorMessage = $res->messageId; - }else{ - $logMessage = $query; - $reload_file_list = true; - } - $this->closeDbLink($link); - break; - } - } - - $fields = array("origname","name", "default", "null", "size", "type", "flags", "pk", "index", "uniq"); - $rows = array(); - foreach ($httpVars as $k=>$val){ - $split = explode("_", $k); - if(count($split) == 3 && $split[0]=="field" && is_numeric($split[2]) && in_array($split[1], $fields)){ - if(!isSet($rows[intval($split[2])])) $rows[intval($split[2])] = array(); - $rows[intval($split[2])][$split[1]] = $val; - }else if(count($split) == 2 && $split[0] == "field" && in_array($split[1], $fields)){ - if(!isSet($rows[0])) $rows[0] = array(); - $rows[0][$split[1]] = $val; - } - } - if(isSet($current_table)){ - $qMessage = ''; - foreach ($rows as $row){ - $sizeString = ($row["size"]!=""?"(".$row["size"].")":""); - $defString = ($row["default"]!=""?" DEFAULT ".$row["default"]."":""); - $query = "ALTER TABLE $current_table CHANGE ".$row["origname"]." ".$row["name"]." ".$row["type"].$sizeString.$defString." ".$row["null"]; - $res = $this->execQuery(trim($query)); - if(is_a($res, "AJXP_Exception")){ - $errorMessage = $res->messageId; - $this->closeDbLink($link); - break; - }else{ - $qMessage .= $query; - $reload_file_list = true; - } - } - $logMessage = $qMessage; - }else if(isSet($new_table)){ - $fieldsDef = array(); - $pks = array(); - $indexes = array(); - $uniqs = array(); - foreach ($rows as $index=>$row){ - $fieldsDef[]= $this->makeColumnDef($row); - // Analyse keys - if($row["pk"] == "1")$pks[] = $row["name"]; - if($row["index"]=="1") $indexes[] = $row["name"]; - if($row["uniq"]=="1") $uniqs[] = $row["name"]; - - } - $fieldsDef = implode(",", $fieldsDef); - if(count($pks)){ - $fieldsDef.= ",PRIMARY KEY (".implode(",", $pks).")"; - } - if(count($indexes)){ - $fieldsDef.=",INDEX (".implode(",", $indexes).")"; - } - if(count($uniqs)){ - $fieldsDef.=",UNIQUE (".implode(",", $uniqs).")"; - } - $query = "CREATE TABLE $new_table ($fieldsDef)"; - $res = $this->execQuery((trim($query))); - if(is_a($res, "AJXP_Exception")){ - $errorMessage = $res->messageId; - }else{ - $logMessage = $query; - $reload_file_list = true; - $reload_current_node = true; - } - } - $this->closeDbLink($link); - break; - - //------------------------------------ - // SUPPRIMER / DELETE - //------------------------------------ - case "delete_table": - case "delete_record": - $dir = basename($dir); - $link = $this->createDbLink(); - if(trim($dir) == ""){ - // ROOT NODE => DROP TABLES - $tables = $selection->getFiles(); - $query = "DROP TABLE"; - foreach ($tables as $index => $tableName){ - $tables[$index] = basename($tableName); - } - $query.= " ".implode(",", $tables); - $res = $this->execQuery($query); - $reload_current_node = true; - }else{ - // TABLE NODE => DELETE RECORDS - $tableName = $dir; - $pks = $selection->getFiles(); - foreach ($pks as $key => $pkString){ - $parts = explode(".", $pkString); - array_pop($parts); // remove .pk extension - array_shift($parts); // remove record prefix - foreach ($parts as $index => $pkPart){ - $parts[$index] = str_replace("__", "='", $pkPart)."'"; - } - $pks[$key] = "(".implode(" AND ", $parts).")"; - } - $query = "DELETE FROM $tableName WHERE ". implode(" OR ", $pks); - $res = $this->execQuery($query); - } - //AJXP_Exception::errorToXml($res); - if(is_a($res, "AJXP_Exception")){ - $errorMessage = $res->messageId; - }else{ - $logMessage = $query; - $reload_file_list = true; - } - $this->closeDbLink($link); - break; - - //------------------------------------ - // RENOMMER / RENAME - //------------------------------------ - case "set_query": - $query = $httpVars["query"]; - $_SESSION["LAST_SQL_QUERY"] = $query; - print(""); - break; - - //------------------------------------ - // XML LISTING - //------------------------------------ - case "ls": - - if(!isSet($dir) || $dir == "/") $dir = ""; - $searchMode = $fileListMode = $completeMode = false; - if(isSet($mode)){ - if($mode == "search") $searchMode = true; - else if($mode == "file_list") $fileListMode = true; - else if($mode == "complete") $completeMode = true; - } - $link = $this->createDbLink(); - //AJXP_Exception::errorToXml($link); - if($dir == ""){ - AJXP_XMLWriter::header(); - $tables = $this->listTables(); - AJXP_XMLWriter::sendFilesListComponentConfig(''); - $icon = ($mode == "file_list"?"sql_images/mimes/ICON_SIZE/table_empty.png":"sql_images/mimes/ICON_SIZE/table_empty_tree.png"); - foreach ($tables as $tableName){ - $size = $this->getSize($tableName); - $count = $this->getCount($tableName); - print ""; - } - print ""; - AJXP_XMLWriter::close(); - }else{ - $tableName = basename($dir); - if(isSet($page))$currentPage = $page; - else $currentPage = 1; - $query = "SELECT * FROM $tableName"; - $searchQuery = false; - if($tableName == "ajxpmysqldriver_searchresults"){ - if(isSet($_SESSION["LAST_SQL_QUERY"])){ - $query = $_SESSION["LAST_SQL_QUERY"]; - $matches = array(); - if(preg_match("/SELECT [\S, ]* FROM (\S*).*/i", $query, $matches)!==false){ - $tableName = $matches[1]; - $searchQuery = true; - }else{ - break; - } - }else{ - break; - } - } - if(isSet($order_column)){ - $query .= " ORDER BY $order_column ".strtoupper($order_direction); - if(!isSet($_SESSION["AJXP_ORDER_DATA"])){ - $_SESSION["AJXP_ORDER_DATA"] = array(); - } - $_SESSION["AJXP_ORDER_DATA"][$this->repository->getUniqueId()."_".$tableName] = array("column" => $order_column, "dir" => $order_direction); - }else if(isSet($_SESSION["AJXP_ORDER_DATA"])){ - if(isSet($_SESSION["AJXP_ORDER_DATA"][$this->repository->getUniqueId()."_".$tableName])){ - $order_column = $_SESSION["AJXP_ORDER_DATA"][$this->repository->getUniqueId()."_".$tableName]["column"]; - $order_direction = $_SESSION["AJXP_ORDER_DATA"][$this->repository->getUniqueId()."_".$tableName]["dir"]; - $query .= " ORDER BY $order_column ".strtoupper($order_direction); - } - } - try { - $result = $this->showRecords($query, $tableName, $currentPage); - }catch (AJXP_Exception $ex){ - unset($_SESSION["LAST_SQL_QUERY"]); - throw $ex; - } - AJXP_XMLWriter::header(); - $blobCols = array(); - $columnsString = ''; - foreach ($result["COLUMNS"] as $col){ - $columnsString .= "cleanFlagString($col["FLAGS"])."\" field_pk=\"".(preg_match("/primary/", $col["FLAGS"])?"1":"0")."\" field_null=\"".(preg_match("/not_null/", $col["FLAGS"])?"NOT_NULL":"NULL")."\" sortType=\"".$this->sqlTypeToSortType($col["TYPE"])."\" field_default=\"".$col["DEFAULT"]."\"/>"; - if(stristr($col["TYPE"],"blob")!==false && ($col["FLAGS"]!="" && stristr($col["FLAGS"], "binary"))){ - $blobCols[]=$col["NAME"]; - } - } - - $columnsString .= ''; - AJXP_XMLWriter::sendFilesListComponentConfig($columnsString); - //print ''; - if($result["TOTAL_PAGES"] > 1){ - AJXP_XMLWriter::renderPaginationData($count, $currentPage,$result["TOTAL_PAGES"]); - } - foreach ($result["ROWS"] as $arbitIndex => $row){ - print '$value){ - if(in_array($key, $blobCols)){ - $sizeStr = " - NULL"; - if(strlen($value)) $sizeStr = " - ".AJXP_Utils::roundSize(strlen($value)); - print "$key=\"BLOB$sizeStr\" "; - }else{ - $value = str_replace("\"", "", $value); - $value = AJXP_Utils::xmlEntities($value); - print $key.'="'.SystemTextEncoding::toUTF8($value).'" '; - if($result["HAS_PK"]>0){ - if(in_array($key, $result["PK_FIELDS"])){ - $pkString .= $key."__".$value."."; - } - } - } - } - if($result["HAS_PK"] > 0){ - print 'filename="record.'.$pkString.'pk" '; - print 'is_file="1" ajxp_mime="pk"/>'; - }else{ - print 'filename="record_'.$arbitIndex.'.no_pk" '; - print 'is_file="1" ajxp_mime="row"/>'; - } - - } - AJXP_XMLWriter::close(); - } - $this->closeDbLink($link); - exit(1); - - break; - } - - if(isset($logMessage) || isset($errorMessage)) - { - $xmlBuffer .= AJXP_XMLWriter::sendMessage((isSet($logMessage)?$logMessage:null), (isSet($errorMessage)?$errorMessage:null), false); - } - - if(isset($requireAuth)) - { - $xmlBuffer .= AJXP_XMLWriter::requireAuth(false); - } - - if(( isset($reload_current_node) && $reload_current_node == "true") || (isset($reload_file_list)) ) - { - $xmlBuffer .= AJXP_XMLWriter::reloadDataNode("", "", false); - } - - return $xmlBuffer; - } - - function getSize($tablename){ - $repo = ConfService::getRepository(); - $dbname = $repo->getOption("DB_NAME"); - $like=""; - $total=""; - $t=0; - if($tablename !=""){ - $like=" like '$tablename'"; - } - $sql= "SHOW TABLE STATUS FROM `$dbname` $like"; - $result=$this->execQuery($sql); - if($result){ - - while($rec = mysql_fetch_array($result)){ - $t+=($rec['Data_length'] + $rec['Index_length']); - } - $total = AJXP_Utils::roundSize($t); - }else{ - $total="Unknown"; - } - return($total); - } - - function getCount($tableName){ - $sql = "SELECT count(*) FROM $tableName"; - $result = $this->execQuery($sql); - $t = 0; - if($result){ - while($res = mysql_fetch_array($result)){ - $t+=$res[0]; - } - } - return $t; - } - - function getColumnData($tableName, $columnName){ - $sql = "SHOW COLUMNS FROM $tableName LIKE '$columnName'"; - $res = $this->execQuery($sql); - if($res){ - return mysql_fetch_array($res); - // ["Field", "Type", "Null", "Key", "Default", "Extra"] => Type is like "enum('a', 'b', 'c')" - } - } - - function makeColumnDef($row, $prefix="", $suffix=""){ - $defString = ""; - if(isSet($row[$prefix."default".$suffix]) && trim($row[$prefix."default".$suffix]) != ""){ - $defString = " DEFAULT ".$row[$prefix."default".$suffix]; - } - $sizeString = ($row[$prefix."size".$suffix]!=""?"(".$row[$prefix."size".$suffix].")":""); - $fieldsDef = $row[$prefix."name".$suffix]." ".$row[$prefix."type".$suffix].$sizeString.$defString." ".$row[$prefix."null".$suffix]." ".$row[$prefix."flags".$suffix]; - return trim($fieldsDef); - } - - function cleanFlagString($flagString){ - $arr = explode(" ", $flagString); - $newFlags = array(); - foreach ($arr as $flag){ - if($flag == "primary_key" || $flag == "null" || $flag == "not_null"){ - continue; - } - $newFlags[] = $flag; - } - return implode(" ", $newFlags); - } - - function sqlTypeToSortType($fieldType){ - switch ($fieldType){ - case "int": - return "Number"; - case "string": - case "datetime": - case "timestamp": - return "String"; - case "blob": - return "NumberKo"; - default: - return "String"; - } - } - /* <--- add a slash at the beggining of this line to switch between the 2 functions - function listTables(){ - $repo = ConfService::getRepository(); - $result = mysql_list_tables($repo->getOption("DB_NAME")); - $numtab = mysql_num_rows ($result); - $allTables = array(); - for ($i =0; $i < $numtab; $i++) { - $table = trim(mysql_tablename($result, $i)); - $allTables[] = $table; - } - return $allTables; - } - /*/ - function listTables(){ - $repo = ConfService::getRepository(); - $result = mysql_query("SHOW TABLES FROM `".$repo->getOption("DB_NAME")."` LIKE '".$repo->getOption("DB_PTRN")."%'"); - $allTables = array(); - while ($row = mysql_fetch_row($result)) { - $allTables[] = $row[0]; - } - return $allTables; - } - //*/ - - function showRecords($query, $tablename, $currentPage=1, $rpp=50, $searchval='' ){ - - $repo = ConfService::getRepository(); - $dbname=$repo->getOption("DB_NAME"); - $result=$this->execQuery($query); - - $columns = array(); - $rows = array(); - - //if(is_a($result, "AJXP_Exception")) return $result; - - $num_rows = mysql_num_rows($result); - $pg=$currentPage-1; - if(isset($_POST['first'])){ - $pg=0; - }else if(isset($_POST['back'])){ - $pg=$pg-1; - }else if(isset($_POST['next'])){ - $pg++; - }else if(isset($_POST['last'])){ - $pgs = $num_rows/$rpp; - $pg=ceil($pgs)-1; - } - if($pg < 0 ){ - $pg=0; - } - if($pg > $num_rows/$rpp){ - $pg=ceil($num_rows/$rpp)-1; - } - $totalPages = ceil($num_rows/$rpp); - $beg = $pg * $rpp; - - $flds = mysql_num_fields($result); - $fields = @mysql_list_fields( $dbname, $tablename); - if(!$fields){ - throw new AJXP_Exception("Non matching fields for table '$tablename'"); - } - $z=0; - $x=0; - $pkfield=array(); - - // MAKE COLUMNS HEADER - for ($i = 0; $i < $flds; $i++) { - $c=$i+1; - $title=mysql_field_name($fields, $i); - $type=mysql_field_type($fields, $i); - $size=mysql_field_len($fields, $i); - $flagstring = mysql_field_flags ($fields, $i); - $colData = $this->getColumnData($tablename, $title); - $colDataType = $colData["Type"]; - if(preg_match("/(.*)\((.*)\)/", $colDataType, $matches)){ - $type = $matches[1]; - $size = $matches[2]; - } - $columns[] = array("NAME" => $title, "TYPE"=>$type, "LENGTH"=>$size, "FLAGS"=>$flagstring, "DEFAULT"=>$colData["Default"]); - - //Find the primary key - $flagstring = mysql_field_flags ($result, $i); - if(preg_match("/primary/",$flagstring )){ - $pk[$z] = $i; - $pkfield[$z]= mysql_field_name($fields, $i); - $z++; - } - } - $v=$flds+1; - - if($z > 0){ - $cpk=count($pk); - }else{ - $cpk=0; - } - - // MAKE ROWS RESULT - for ($s=$beg; $s < $beg + $rpp; $s++){ - if($s < $num_rows){ - if (!mysql_data_seek ($result, $s)) { - continue; - } - $row=mysql_fetch_array($result); - if(!isset($pk)){ - $pk=' '; - $pkfield= array(); - } - $values = array(); - for($col = 0; $col < $flds; $col ++) - { - $values[mysql_field_name($fields, $col)] = stripslashes($row[$col]); - } - $rows[] = $values; - } - } - - return array("COLUMNS" => $columns, "ROWS" => $rows, "HAS_PK"=>$cpk, "TOTAL_PAGES"=>$totalPages, "PK_FIELDS"=>$pkfield); - } - - - function execQuery($sql =''){ - $output=''; - if($sql !=''){ - //$sql=mysql_real_escape_string($sql); - $result= @mysql_query(stripslashes($sql)); - if($result){ - AJXP_Logger::logAction("exec", array($sql)); - return $result; - }else{ - throw new AJXP_Exception($sql.":".mysql_error()); - } - }else{ - throw new AJXP_Exception('Empty Query'); - } - } - - -} - -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * @package AjaXplorer_Plugins + * @subpackage Access + */ +class mysqlAccessDriver extends AbstractAccessDriver +{ + /** The user name */ + public $user; + /** The user password */ + public $password; + + public function initRepository() + { + $this->user = $this->repository->getOption("DB_USER"); + $this->password = $this->repository->getOption("DB_PASS"); + $link = $this->createDbLink(); + $this->closeDbLink($link); + } + + + public function createDbLink() + { + $link = FALSE; + //Connects to the MySQL Database. + $host = $this->repository->getOption("DB_HOST"); + $dbname = $this->repository->getOption("DB_NAME"); + $link = @mysql_connect($host, $this->user, $this->password); + if (!$link) { + throw new AJXP_Exception("Cannot connect to server!"); + } + if (!@mysql_select_db($dbname, $link)) { + throw new AJXP_Exception("Cannot find database!"); + } + return $link; + } + + public function closeDbLink($link) + { + if (!mysql_close($link)) { + throw new AJXP_Exception("Cannot close connection!"); + } + } + + public function switchAction($action, $httpVars, $fileVars) + { + $repo = ConfService::getRepository(); + if(!isSet($this->actions[$action])) return; + parent::accessPreprocess($action, $httpVars, $fileVars); + $xmlBuffer = ""; + foreach ($httpVars as $getName=>$getValue) { + $$getName = AJXP_Utils::securePath($getValue); + } + $selection = new UserSelection(); + $selection->initFromHttpVars($httpVars); + if (isSet($dir) && $action != "upload") { + $safeDir = $dir; + $dir = SystemTextEncoding::fromUTF8($dir); + } + // FILTER DIR PAGINATION ANCHOR + if (isSet($dir) && strstr($dir, "%23")!==false) { + $parts = explode("%23", $dir); + $dir = $parts[0]; + $page = $parts[1]; + } + if (isSet($dest)) { + $dest = SystemTextEncoding::fromUTF8($dest); + } + $mess = ConfService::getMessages(); + + switch ($action) { + + //------------------------------------ + // ONLINE EDIT + //------------------------------------ + case "edit_record"; + $isNew = false; + if(isSet($record_is_new) && $record_is_new == "true") $isNew = true; + $tableName = $_POST["table_name"]; + $pkName = $_POST["pk_name"]; + $query = ""; + $arrValues = array(); + foreach ($_POST as $key=>$value) { + if (substr($key, 0, strlen("ajxp_mysql_")) == "ajxp_mysql_") { + $newKey = substr($key, strlen("ajxp_mysql_")); + $arrValues[$newKey] = $value; + } + } + if ($isNew) { + $string = ""; + $index = 0; + foreach ($arrValues as $k=>$v) { + // CHECK IF AUTO KEY!!! + $string .= "'".addslashes(SystemTextEncoding::fromUTF8($v))."'"; + if($index < count($arrValues)-1) $string.=","; + $index++; + } + $query = "INSERT INTO $tableName VALUES ($string)"; + } else { + $string = ""; + $index = 0; + foreach ($arrValues as $k=>$v) { + if ($k == $pkName) { + $pkValue = $v; + } else { + $string .= $k."='".addslashes(SystemTextEncoding::fromUTF8($v))."'"; + if($indexcreateDbLink(); + $res = $this->execQuery($query); + $this->closeDbLink($link); + + if (is_a($res, "AJXP_Exception")) { + $errorMessage = $res->messageId; + } else { + $logMessage = $query; + $reload_file_list = true; + } + break; + + //------------------------------------ + // CHANGE COLUMNS OR CREATE TABLE + //------------------------------------ + case "edit_table": + $link = $this->createDbLink(); + if (isSet($httpVars["current_table"])) { + if (isSet($httpVars["delete_column"])) { + $query = "ALTER TABLE ".$httpVars["current_table"]." DROP COLUMN ".$httpVars["delete_column"]; + $res = $this->execQuery($query); + if (is_a($res, "AJXP_Exception")) { + $errorMessage = $res->messageId; + } else { + $logMessage = $query; + $reload_file_list = true; + } + $this->closeDbLink($link); + break; + } + if (isSet($httpVars["add_column"])) { + $defString = $this->makeColumnDef($httpVars, "add_field_"); + $query = "ALTER TABLE ".$httpVars["current_table"]." ADD COLUMN ($defString)"; + if (isSet($httpVars["add_field_pk"]) && $httpVars["add_field_pk"]=="1") { + $query.= ", ADD PRIMARY KEY (".$httpVars["add_field_name"].")"; + } + if (isSet($httpVars["add_field_index"]) && $httpVars["add_field_index"]=="1") { + $query.= ", ADD INDEX (".$httpVars["add_field_name"].")"; + } + if (isSet($httpVars["add_field_uniq"]) && $httpVars["add_field_uniq"]=="1") { + $query.= ", ADD UNIQUE (".$httpVars["add_field_name"].")"; + } + $res = $this->execQuery($query); + if (is_a($res, "AJXP_Exception")) { + $errorMessage = $res->messageId; + } else { + $logMessage = $query; + $reload_file_list = true; + } + $this->closeDbLink($link); + break; + } + } + + $fields = array("origname","name", "default", "null", "size", "type", "flags", "pk", "index", "uniq"); + $rows = array(); + foreach ($httpVars as $k=>$val) { + $split = explode("_", $k); + if (count($split) == 3 && $split[0]=="field" && is_numeric($split[2]) && in_array($split[1], $fields)) { + if(!isSet($rows[intval($split[2])])) $rows[intval($split[2])] = array(); + $rows[intval($split[2])][$split[1]] = $val; + } else if (count($split) == 2 && $split[0] == "field" && in_array($split[1], $fields)) { + if(!isSet($rows[0])) $rows[0] = array(); + $rows[0][$split[1]] = $val; + } + } + if (isSet($current_table)) { + $qMessage = ''; + foreach ($rows as $row) { + $sizeString = ($row["size"]!=""?"(".$row["size"].")":""); + $defString = ($row["default"]!=""?" DEFAULT ".$row["default"]."":""); + $query = "ALTER TABLE $current_table CHANGE ".$row["origname"]." ".$row["name"]." ".$row["type"].$sizeString.$defString." ".$row["null"]; + $res = $this->execQuery(trim($query)); + if (is_a($res, "AJXP_Exception")) { + $errorMessage = $res->messageId; + $this->closeDbLink($link); + break; + } else { + $qMessage .= $query; + $reload_file_list = true; + } + } + $logMessage = $qMessage; + } else if (isSet($new_table)) { + $fieldsDef = array(); + $pks = array(); + $indexes = array(); + $uniqs = array(); + foreach ($rows as $index=>$row) { + $fieldsDef[]= $this->makeColumnDef($row); + // Analyse keys + if($row["pk"] == "1")$pks[] = $row["name"]; + if($row["index"]=="1") $indexes[] = $row["name"]; + if($row["uniq"]=="1") $uniqs[] = $row["name"]; + + } + $fieldsDef = implode(",", $fieldsDef); + if (count($pks)) { + $fieldsDef.= ",PRIMARY KEY (".implode(",", $pks).")"; + } + if (count($indexes)) { + $fieldsDef.=",INDEX (".implode(",", $indexes).")"; + } + if (count($uniqs)) { + $fieldsDef.=",UNIQUE (".implode(",", $uniqs).")"; + } + $query = "CREATE TABLE $new_table ($fieldsDef)"; + $res = $this->execQuery((trim($query))); + if (is_a($res, "AJXP_Exception")) { + $errorMessage = $res->messageId; + } else { + $logMessage = $query; + $reload_file_list = true; + $reload_current_node = true; + } + } + $this->closeDbLink($link); + break; + + //------------------------------------ + // SUPPRIMER / DELETE + //------------------------------------ + case "delete_table": + case "delete_record": + $dir = basename($dir); + $link = $this->createDbLink(); + if (trim($dir) == "") { + // ROOT NODE => DROP TABLES + $tables = $selection->getFiles(); + $query = "DROP TABLE"; + foreach ($tables as $index => $tableName) { + $tables[$index] = basename($tableName); + } + $query.= " ".implode(",", $tables); + $res = $this->execQuery($query); + $reload_current_node = true; + } else { + // TABLE NODE => DELETE RECORDS + $tableName = $dir; + $pks = $selection->getFiles(); + foreach ($pks as $key => $pkString) { + $parts = explode(".", $pkString); + array_pop($parts); // remove .pk extension + array_shift($parts); // remove record prefix + foreach ($parts as $index => $pkPart) { + $parts[$index] = str_replace("__", "='", $pkPart)."'"; + } + $pks[$key] = "(".implode(" AND ", $parts).")"; + } + $query = "DELETE FROM $tableName WHERE ". implode(" OR ", $pks); + $res = $this->execQuery($query); + } + //AJXP_Exception::errorToXml($res); + if (is_a($res, "AJXP_Exception")) { + $errorMessage = $res->messageId; + } else { + $logMessage = $query; + $reload_file_list = true; + } + $this->closeDbLink($link); + break; + + //------------------------------------ + // RENOMMER / RENAME + //------------------------------------ + case "set_query": + $query = $httpVars["query"]; + $_SESSION["LAST_SQL_QUERY"] = $query; + print(""); + break; + + //------------------------------------ + // XML LISTING + //------------------------------------ + case "ls": + + if(!isSet($dir) || $dir == "/") $dir = ""; + $searchMode = $fileListMode = $completeMode = false; + if (isSet($mode)) { + if($mode == "search") $searchMode = true; + else if($mode == "file_list") $fileListMode = true; + else if($mode == "complete") $completeMode = true; + } + $link = $this->createDbLink(); + //AJXP_Exception::errorToXml($link); + if ($dir == "") { + AJXP_XMLWriter::header(); + $tables = $this->listTables(); + AJXP_XMLWriter::sendFilesListComponentConfig(''); + $icon = ($mode == "file_list"?"sql_images/mimes/ICON_SIZE/table_empty.png":"sql_images/mimes/ICON_SIZE/table_empty_tree.png"); + foreach ($tables as $tableName) { + $size = $this->getSize($tableName); + $count = $this->getCount($tableName); + print ""; + } + print ""; + AJXP_XMLWriter::close(); + } else { + $tableName = basename($dir); + if(isSet($page))$currentPage = $page; + else $currentPage = 1; + $query = "SELECT * FROM $tableName"; + $searchQuery = false; + if ($tableName == "ajxpmysqldriver_searchresults") { + if (isSet($_SESSION["LAST_SQL_QUERY"])) { + $query = $_SESSION["LAST_SQL_QUERY"]; + $matches = array(); + if (preg_match("/SELECT [\S, ]* FROM (\S*).*/i", $query, $matches)!==false) { + $tableName = $matches[1]; + $searchQuery = true; + } else { + break; + } + } else { + break; + } + } + if (isSet($order_column)) { + $query .= " ORDER BY $order_column ".strtoupper($order_direction); + if (!isSet($_SESSION["AJXP_ORDER_DATA"])) { + $_SESSION["AJXP_ORDER_DATA"] = array(); + } + $_SESSION["AJXP_ORDER_DATA"][$this->repository->getUniqueId()."_".$tableName] = array("column" => $order_column, "dir" => $order_direction); + } else if (isSet($_SESSION["AJXP_ORDER_DATA"])) { + if (isSet($_SESSION["AJXP_ORDER_DATA"][$this->repository->getUniqueId()."_".$tableName])) { + $order_column = $_SESSION["AJXP_ORDER_DATA"][$this->repository->getUniqueId()."_".$tableName]["column"]; + $order_direction = $_SESSION["AJXP_ORDER_DATA"][$this->repository->getUniqueId()."_".$tableName]["dir"]; + $query .= " ORDER BY $order_column ".strtoupper($order_direction); + } + } + try { + $result = $this->showRecords($query, $tableName, $currentPage); + } catch (AJXP_Exception $ex) { + unset($_SESSION["LAST_SQL_QUERY"]); + throw $ex; + } + AJXP_XMLWriter::header(); + $blobCols = array(); + $columnsString = ''; + foreach ($result["COLUMNS"] as $col) { + $columnsString .= "cleanFlagString($col["FLAGS"])."\" field_pk=\"".(preg_match("/primary/", $col["FLAGS"])?"1":"0")."\" field_null=\"".(preg_match("/not_null/", $col["FLAGS"])?"NOT_NULL":"NULL")."\" sortType=\"".$this->sqlTypeToSortType($col["TYPE"])."\" field_default=\"".$col["DEFAULT"]."\"/>"; + if (stristr($col["TYPE"],"blob")!==false && ($col["FLAGS"]!="" && stristr($col["FLAGS"], "binary"))) { + $blobCols[]=$col["NAME"]; + } + } + + $columnsString .= ''; + AJXP_XMLWriter::sendFilesListComponentConfig($columnsString); + //print ''; + if ($result["TOTAL_PAGES"] > 1) { + AJXP_XMLWriter::renderPaginationData($count, $currentPage,$result["TOTAL_PAGES"]); + } + foreach ($result["ROWS"] as $arbitIndex => $row) { + print '$value) { + if (in_array($key, $blobCols)) { + $sizeStr = " - NULL"; + if(strlen($value)) $sizeStr = " - ".AJXP_Utils::roundSize(strlen($value)); + print "$key=\"BLOB$sizeStr\" "; + } else { + $value = str_replace("\"", "", $value); + $value = AJXP_Utils::xmlEntities($value); + print $key.'="'.SystemTextEncoding::toUTF8($value).'" '; + if ($result["HAS_PK"]>0) { + if (in_array($key, $result["PK_FIELDS"])) { + $pkString .= $key."__".$value."."; + } + } + } + } + if ($result["HAS_PK"] > 0) { + print 'filename="record.'.$pkString.'pk" '; + print 'is_file="1" ajxp_mime="pk"/>'; + } else { + print 'filename="record_'.$arbitIndex.'.no_pk" '; + print 'is_file="1" ajxp_mime="row"/>'; + } + + } + AJXP_XMLWriter::close(); + } + $this->closeDbLink($link); + exit(1); + + break; + } + + if (isset($logMessage) || isset($errorMessage)) { + $xmlBuffer .= AJXP_XMLWriter::sendMessage((isSet($logMessage)?$logMessage:null), (isSet($errorMessage)?$errorMessage:null), false); + } + + if (isset($requireAuth)) { + $xmlBuffer .= AJXP_XMLWriter::requireAuth(false); + } + + if (( isset($reload_current_node) && $reload_current_node == "true") || (isset($reload_file_list)) ) { + $xmlBuffer .= AJXP_XMLWriter::reloadDataNode("", "", false); + } + + return $xmlBuffer; + } + + public function getSize($tablename) + { + $repo = ConfService::getRepository(); + $dbname = $repo->getOption("DB_NAME"); + $like=""; + $total=""; + $t=0; + if ($tablename !="") { + $like=" like '$tablename'"; + } + $sql= "SHOW TABLE STATUS FROM `$dbname` $like"; + $result=$this->execQuery($sql); + if ($result) { + + while ($rec = mysql_fetch_array($result)) { + $t+=($rec['Data_length'] + $rec['Index_length']); + } + $total = AJXP_Utils::roundSize($t); + } else { + $total="Unknown"; + } + return($total); + } + + public function getCount($tableName) + { + $sql = "SELECT count(*) FROM $tableName"; + $result = $this->execQuery($sql); + $t = 0; + if ($result) { + while ($res = mysql_fetch_array($result)) { + $t+=$res[0]; + } + } + return $t; + } + + public function getColumnData($tableName, $columnName) + { + $sql = "SHOW COLUMNS FROM $tableName LIKE '$columnName'"; + $res = $this->execQuery($sql); + if ($res) { + return mysql_fetch_array($res); + // ["Field", "Type", "Null", "Key", "Default", "Extra"] => Type is like "enum('a', 'b', 'c')" + } + } + + public function makeColumnDef($row, $prefix="", $suffix="") + { + $defString = ""; + if (isSet($row[$prefix."default".$suffix]) && trim($row[$prefix."default".$suffix]) != "") { + $defString = " DEFAULT ".$row[$prefix."default".$suffix]; + } + $sizeString = ($row[$prefix."size".$suffix]!=""?"(".$row[$prefix."size".$suffix].")":""); + $fieldsDef = $row[$prefix."name".$suffix]." ".$row[$prefix."type".$suffix].$sizeString.$defString." ".$row[$prefix."null".$suffix]." ".$row[$prefix."flags".$suffix]; + return trim($fieldsDef); + } + + public function cleanFlagString($flagString) + { + $arr = explode(" ", $flagString); + $newFlags = array(); + foreach ($arr as $flag) { + if ($flag == "primary_key" || $flag == "null" || $flag == "not_null") { + continue; + } + $newFlags[] = $flag; + } + return implode(" ", $newFlags); + } + + public function sqlTypeToSortType($fieldType) + { + switch ($fieldType) { + case "int": + return "Number"; + case "string": + case "datetime": + case "timestamp": + return "String"; + case "blob": + return "NumberKo"; + default: + return "String"; + } + } + /* <--- add a slash at the beggining of this line to switch between the 2 functions + public function listTables() + { + $repo = ConfService::getRepository(); + $result = mysql_list_tables($repo->getOption("DB_NAME")); + $numtab = mysql_num_rows ($result); + $allTables = array(); + for ($i =0; $i < $numtab; $i++) { + $table = trim(mysql_tablename($result, $i)); + $allTables[] = $table; + } + return $allTables; + } + /*/ + public function listTables() + { + $repo = ConfService::getRepository(); + $result = mysql_query("SHOW TABLES FROM `".$repo->getOption("DB_NAME")."` LIKE '".$repo->getOption("DB_PTRN")."%'"); + $allTables = array(); + while ($row = mysql_fetch_row($result)) { + $allTables[] = $row[0]; + } + return $allTables; + } + //*/ + + public function showRecords($query, $tablename, $currentPage=1, $rpp=50, $searchval='' ) + { + $repo = ConfService::getRepository(); + $dbname=$repo->getOption("DB_NAME"); + $result=$this->execQuery($query); + + $columns = array(); + $rows = array(); + + //if(is_a($result, "AJXP_Exception")) return $result; + + $num_rows = mysql_num_rows($result); + $pg=$currentPage-1; + if (isset($_POST['first'])) { + $pg=0; + } else if (isset($_POST['back'])) { + $pg=$pg-1; + } else if (isset($_POST['next'])) { + $pg++; + } else if (isset($_POST['last'])) { + $pgs = $num_rows/$rpp; + $pg=ceil($pgs)-1; + } + if ($pg < 0) { + $pg=0; + } + if ($pg > $num_rows/$rpp) { + $pg=ceil($num_rows/$rpp)-1; + } + $totalPages = ceil($num_rows/$rpp); + $beg = $pg * $rpp; + + $flds = mysql_num_fields($result); + $fields = @mysql_list_fields( $dbname, $tablename); + if (!$fields) { + throw new AJXP_Exception("Non matching fields for table '$tablename'"); + } + $z=0; + $x=0; + $pkfield=array(); + + // MAKE COLUMNS HEADER + for ($i = 0; $i < $flds; $i++) { + $c=$i+1; + $title=mysql_field_name($fields, $i); + $type=mysql_field_type($fields, $i); + $size=mysql_field_len($fields, $i); + $flagstring = mysql_field_flags ($fields, $i); + $colData = $this->getColumnData($tablename, $title); + $colDataType = $colData["Type"]; + if (preg_match("/(.*)\((.*)\)/", $colDataType, $matches)) { + $type = $matches[1]; + $size = $matches[2]; + } + $columns[] = array("NAME" => $title, "TYPE"=>$type, "LENGTH"=>$size, "FLAGS"=>$flagstring, "DEFAULT"=>$colData["Default"]); + + //Find the primary key + $flagstring = mysql_field_flags ($result, $i); + if (preg_match("/primary/",$flagstring )) { + $pk[$z] = $i; + $pkfield[$z]= mysql_field_name($fields, $i); + $z++; + } + } + $v=$flds+1; + + if ($z > 0) { + $cpk=count($pk); + } else { + $cpk=0; + } + + // MAKE ROWS RESULT + for ($s=$beg; $s < $beg + $rpp; $s++) { + if ($s < $num_rows) { + if (!mysql_data_seek ($result, $s)) { + continue; + } + $row=mysql_fetch_array($result); + if (!isset($pk)) { + $pk=' '; + $pkfield= array(); + } + $values = array(); + for ($col = 0; $col < $flds; $col ++) { + $values[mysql_field_name($fields, $col)] = stripslashes($row[$col]); + } + $rows[] = $values; + } + } + + return array("COLUMNS" => $columns, "ROWS" => $rows, "HAS_PK"=>$cpk, "TOTAL_PAGES"=>$totalPages, "PK_FIELDS"=>$pkfield); + } + + + public function execQuery($sql ='') + { + $output=''; + if ($sql !='') { + //$sql=mysql_real_escape_string($sql); + $result= @mysql_query(stripslashes($sql)); + if ($result) { + AJXP_Logger::logAction("exec", array($sql)); + return $result; + } else { + throw new AJXP_Exception($sql.":".mysql_error()); + } + } else { + throw new AJXP_Exception('Empty Query'); + } + } + + +} diff --git a/core/src/plugins/access.mysql/manifest.xml b/core/src/plugins/access.mysql/manifest.xml index 73f5243d55..77e07cd32d 100644 --- a/core/src/plugins/access.mysql/manifest.xml +++ b/core/src/plugins/access.mysql/manifest.xml @@ -1,56 +1,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #{current_folder} -
    #{folders_string} : #{filelist_folders_count}
    -
    #{files_string} : #{filelist_files_count}
    -
    #{totalsize_string} #{filelist_totalsize}
    - - ]]> -
    - - - - - - #{text} -
    #{files_string} : #{count}
    - - ]]> -
    -
    -
    -
    - -
    \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #{current_folder} +
    #{folders_string} : #{filelist_folders_count}
    +
    #{files_string} : #{filelist_files_count}
    +
    #{totalsize_string} #{filelist_totalsize}
    + + ]]> +
    + + + + + + #{text} +
    #{files_string} : #{count}
    + + ]]> +
    +
    +
    +
    + +
    diff --git a/core/src/plugins/access.mysql/mysqlActions.xml b/core/src/plugins/access.mysql/mysqlActions.xml index 320b26dfd1..4d4e4d5b45 100644 --- a/core/src/plugins/access.mysql/mysqlActions.xml +++ b/core/src/plugins/access.mysql/mysqlActions.xml @@ -1,288 +1,288 @@ - - - - - - - - - - - - - - 0){ - path = window.actionArguments[0]; - if(Object.isString(path)){path = new AjxpNode(path,false,getBaseName(path));} - }else{ - userSelection = ajaxplorer.getUserSelection(); - if(userSelection && userSelection.isUnique() && (userSelection.hasDir() || userSelection.hasMime(["zip"]))){ - path = userSelection.getUniqueNode(); - } - } - if(path){ - ajaxplorer.updateContextData(path); - } - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Field NameTypeSize or SetNULLDefaultOther FlagsPKIDXUNIQ
    - - -
    -
    -
    -
    - Step 1: Choose a number of fields - - - - - - - -
    Name of the table :
    Number of fields :
    -
    - - -
    -
    -
    - ]]>
    - -
    -
    - - - - - - - - - - - ]]> - - - - - - - - - - - - - - ]]> - - - - - - - - - - - - - - ]]> - - - -
    -
    + + + + + + + + + + + + + + 0){ + path = window.actionArguments[0]; + if(Object.isString(path)){path = new AjxpNode(path,false,getBaseName(path));} + }else{ + userSelection = ajaxplorer.getUserSelection(); + if(userSelection && userSelection.isUnique() && (userSelection.hasDir() || userSelection.hasMime(["zip"]))){ + path = userSelection.getUniqueNode(); + } + } + if(path){ + ajaxplorer.updateContextData(path); + } + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Field NameTypeSize or SetNULLDefaultOther FlagsPKIDXUNIQ
    + + +
    +
    +
    +
    + Step 1: Choose a number of fields + + + + + + + +
    Name of the table :
    Number of fields :
    +
    + + +
    +
    +
    + ]]>
    + +
    +
    + + + + + + + + + + + ]]> + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + + + ]]> + + + +
    +
    diff --git a/core/src/plugins/access.mysql/resources/i18n/conf/en.php b/core/src/plugins/access.mysql/resources/i18n/conf/en.php index f78282dc0b..e76def7886 100644 --- a/core/src/plugins/access.mysql/resources/i18n/conf/en.php +++ b/core/src/plugins/access.mysql/resources/i18n/conf/en.php @@ -33,4 +33,3 @@ "If not empty, only tables beginning with such a prefix will be displayed." => "If not empty, only tables beginning with such a prefix will be displayed.", "Repository Commons" => "Repository Commons", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.mysql/resources/i18n/conf/fr.php b/core/src/plugins/access.mysql/resources/i18n/conf/fr.php index 1ca870a7a1..ceaae805c9 100644 --- a/core/src/plugins/access.mysql/resources/i18n/conf/fr.php +++ b/core/src/plugins/access.mysql/resources/i18n/conf/fr.php @@ -33,4 +33,3 @@ "If not empty, only tables beginning with such a prefix will be displayed." => "Si non-vide, seules les tables commencant par ce préfixe seront affichées.", "Repository Commons" => "Options du dépôt", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.mysql/resources/i18n/conf/pt.php b/core/src/plugins/access.mysql/resources/i18n/conf/pt.php index 5f9769a1c7..35df985f7d 100644 --- a/core/src/plugins/access.mysql/resources/i18n/conf/pt.php +++ b/core/src/plugins/access.mysql/resources/i18n/conf/pt.php @@ -33,4 +33,3 @@ "If not empty, only tables beginning with such a prefix will be displayed." => "Caso não esteja vazio, apenas as tabelas com o prefixo serão mostradas.", "Repository Commons" => "Ficheiros de Repositório Comuns", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.mysql/resources/i18n/de.php b/core/src/plugins/access.mysql/resources/i18n/de.php index c5bc79bb15..3a0e68170f 100644 --- a/core/src/plugins/access.mysql/resources/i18n/de.php +++ b/core/src/plugins/access.mysql/resources/i18n/de.php @@ -1,27 +1,26 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess=array( -"1" => "Tabelle erstellen", -"2" => "SQL Abfrage hier eingeben", -"3" => "Suchen", -"4" => "Löschen" -); -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess=array( +"1" => "Tabelle erstellen", +"2" => "SQL Abfrage hier eingeben", +"3" => "Suchen", +"4" => "Löschen" +); diff --git a/core/src/plugins/access.mysql/resources/i18n/en.php b/core/src/plugins/access.mysql/resources/i18n/en.php index 3b7f8b047e..57cef26770 100644 --- a/core/src/plugins/access.mysql/resources/i18n/en.php +++ b/core/src/plugins/access.mysql/resources/i18n/en.php @@ -1,27 +1,26 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess=array( -"1" => "Create Table", -"2" => "Type your SQL query here", -"3" => "Search", -"4" => "Clear" -); -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess=array( +"1" => "Create Table", +"2" => "Type your SQL query here", +"3" => "Search", +"4" => "Clear" +); diff --git a/core/src/plugins/access.mysql/resources/i18n/es.php b/core/src/plugins/access.mysql/resources/i18n/es.php index b6da153d19..c1edb047c7 100644 --- a/core/src/plugins/access.mysql/resources/i18n/es.php +++ b/core/src/plugins/access.mysql/resources/i18n/es.php @@ -1,27 +1,26 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess=array( -"1" => "Crear Tabla", -"2" => "Escriba sy consulta SQL aquí", -"3" => "Consultar", -"4" => "Limpiar" -); -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess=array( +"1" => "Crear Tabla", +"2" => "Escriba sy consulta SQL aquí", +"3" => "Consultar", +"4" => "Limpiar" +); diff --git a/core/src/plugins/access.mysql/resources/i18n/fi.php b/core/src/plugins/access.mysql/resources/i18n/fi.php index 73e6852922..bf34d6798b 100644 --- a/core/src/plugins/access.mysql/resources/i18n/fi.php +++ b/core/src/plugins/access.mysql/resources/i18n/fi.php @@ -1,30 +1,29 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - // Finnish translation by Aleksi Postari -// aleksi (at) postari.net -// Last update: 07.09.2010 -$mess=array( -"1" => "Luo taulu", -"2" => "Syötä SQL lauseesi tähän", -"3" => "Hae", -"4" => "Tyhjennä" -); -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + // Finnish translation by Aleksi Postari +// aleksi (at) postari.net +// Last update: 07.09.2010 +$mess=array( +"1" => "Luo taulu", +"2" => "Syötä SQL lauseesi tähän", +"3" => "Hae", +"4" => "Tyhjennä" +); diff --git a/core/src/plugins/access.mysql/resources/i18n/fr.php b/core/src/plugins/access.mysql/resources/i18n/fr.php index c11cdbc1ce..3e4ee1948a 100644 --- a/core/src/plugins/access.mysql/resources/i18n/fr.php +++ b/core/src/plugins/access.mysql/resources/i18n/fr.php @@ -24,4 +24,3 @@ "3" => "Executer la requête", "4" => "Effacer" ); -?> diff --git a/core/src/plugins/access.mysql/resources/i18n/pt.php b/core/src/plugins/access.mysql/resources/i18n/pt.php index 6cc93b041b..297ae5470a 100644 --- a/core/src/plugins/access.mysql/resources/i18n/pt.php +++ b/core/src/plugins/access.mysql/resources/i18n/pt.php @@ -24,4 +24,3 @@ "3" => "Procurar", "4" => "Limpar" ); -?> diff --git a/core/src/plugins/access.mysql/resources/i18n/si.php b/core/src/plugins/access.mysql/resources/i18n/si.php index ebf54b2c32..2d4bd307d9 100644 --- a/core/src/plugins/access.mysql/resources/i18n/si.php +++ b/core/src/plugins/access.mysql/resources/i18n/si.php @@ -1,28 +1,27 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -// Slovenian translation: April 21 2011 by Vladimir Bohinc (vladimir.bohinc@gmail.com) -$mess=array( -"1" => "Ustvari tabelo", -"2" => "Vnos SQL poizvedbe", -"3" => "Najdi", -"4" => "Počisti" -); -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +// Slovenian translation: April 21 2011 by Vladimir Bohinc (vladimir.bohinc@gmail.com) +$mess=array( +"1" => "Ustvari tabelo", +"2" => "Vnos SQL poizvedbe", +"3" => "Najdi", +"4" => "Počisti" +); diff --git a/core/src/plugins/access.remote_fs/additionalActions.xml b/core/src/plugins/access.remote_fs/additionalActions.xml index d299eca2a6..3343796b85 100644 --- a/core/src/plugins/access.remote_fs/additionalActions.xml +++ b/core/src/plugins/access.remote_fs/additionalActions.xml @@ -1,15 +1,15 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/core/src/plugins/access.remote_fs/class.remote_fsAccessDriver.php b/core/src/plugins/access.remote_fs/class.remote_fsAccessDriver.php index 1c4a37b866..252cfc8673 100644 --- a/core/src/plugins/access.remote_fs/class.remote_fsAccessDriver.php +++ b/core/src/plugins/access.remote_fs/class.remote_fsAccessDriver.php @@ -25,33 +25,35 @@ * @package AjaXplorer_Plugins * @subpackage Access */ -class remote_fsAccessDriver extends AbstractAccessDriver +class remote_fsAccessDriver extends AbstractAccessDriver { - private $plugCapabilities = array(); - - function init($repository, $options = array()){ - $repoCapabilities = $repository->getOption("API_CAPABILITIES"); - if($repoCapabilities != ""){ - $this->plugCapabilities = explode(",", $repoCapabilities); - // Register one preprocessor per capability. - foreach ($this->plugCapabilities as $capability){ - $xml = ''; + private $plugCapabilities = array(); + + public function init($repository, $options = array()) + { + $repoCapabilities = $repository->getOption("API_CAPABILITIES"); + if ($repoCapabilities != "") { + $this->plugCapabilities = explode(",", $repoCapabilities); + // Register one preprocessor per capability. + foreach ($this->plugCapabilities as $capability) { + $xml = ''; $tmpDoc = new DOMDocument(); - $tmpDoc->loadXML($xml); - $newNode = $this->manifestDoc->importNode($tmpDoc->documentElement, true); - $this->xPath->query("registry_contributions/actions")->item(0)->appendChild($newNode); - } - } - parent::init($repository, $options); - } + $tmpDoc->loadXML($xml); + $newNode = $this->manifestDoc->importNode($tmpDoc->documentElement, true); + $this->xPath->query("registry_contributions/actions")->item(0)->appendChild($newNode); + } + } + parent::init($repository, $options); + } - function redirectActionsToMethod(&$contribNode, $arrayActions, $targetMethod){ + public function redirectActionsToMethod(&$contribNode, $arrayActions, $targetMethod) + { $actionXpath=new DOMXPath($contribNode->ownerDocument); - foreach($arrayActions as $index => $value){ + foreach ($arrayActions as $index => $value) { $arrayActions[$index] = 'action[@name="'.$value.'"]/processing/serverCallback'; } $procList = $actionXpath->query(implode(" | ", $arrayActions), $contribNode); - foreach($procList as $node){ + foreach ($procList as $node) { $node->setAttribute("methodName", $targetMethod); } } @@ -60,328 +62,334 @@ function redirectActionsToMethod(&$contribNode, $arrayActions, $targetMethod){ * Parse * @param DOMNode $contribNode */ - protected function parseSpecificContributions(&$contribNode){ + protected function parseSpecificContributions(&$contribNode) + { parent::parseSpecificContributions($contribNode); if($contribNode->nodeName != "actions") return ; $this->redirectActionsToMethod($contribNode, array("upload", "next_to_remote", "trigger_remote_copy"), "uploadActions"); } - function switchAction($action, $httpVars, $filesVars){ - $secureToken = ""; - $crtRep = ConfService::getRepository(); - $httpClient = $this->getRemoteConnexion($secureToken); - //$httpClient->setDebug(true); - $method = "get"; - if($action == "put_content") $method = "post"; - $httpVars["secure_token"] = $secureToken; - if($method == "get"){ - if($action == "download"){ - $httpClient->directForwarding = true; - } - $result = $httpClient->get($crtRep->getOption("URI"), $httpVars); - }else{ - $result = $httpClient->post($crtRep->getOption("URI"), $httpVars); - } - // check if session is expired - if(strpos($httpClient->getHeader("content-type"), "text/xml") !== false && strpos($httpClient->getContent(), "require_auth") != false){ - $httpClient = $this->getRemoteConnexion($secureToken, true); - $httpVars["secure_token"] = $secureToken; - $method = "get"; - if($method == "get"){ - if($action == "download"){ - $httpClient->directForwarding = true; - } - $result = $httpClient->get($crtRep->getOption("URI"), $httpVars); - $result = $httpClient->get($crtRep->getOption("URI"), $httpVars); - }else{ - $result = $httpClient->post($crtRep->getOption("URI"), $httpVars); - } - } + public function switchAction($action, $httpVars, $filesVars) + { + $secureToken = ""; + $crtRep = ConfService::getRepository(); + $httpClient = $this->getRemoteConnexion($secureToken); + //$httpClient->setDebug(true); + $method = "get"; + if($action == "put_content") $method = "post"; + $httpVars["secure_token"] = $secureToken; + if ($method == "get") { + if ($action == "download") { + $httpClient->directForwarding = true; + } + $result = $httpClient->get($crtRep->getOption("URI"), $httpVars); + } else { + $result = $httpClient->post($crtRep->getOption("URI"), $httpVars); + } + // check if session is expired + if (strpos($httpClient->getHeader("content-type"), "text/xml") !== false && strpos($httpClient->getContent(), "require_auth") != false) { + $httpClient = $this->getRemoteConnexion($secureToken, true); + $httpVars["secure_token"] = $secureToken; + $method = "get"; + if ($method == "get") { + if ($action == "download") { + $httpClient->directForwarding = true; + } + $result = $httpClient->get($crtRep->getOption("URI"), $httpVars); + $result = $httpClient->get($crtRep->getOption("URI"), $httpVars); + } else { + $result = $httpClient->post($crtRep->getOption("URI"), $httpVars); + } + } + + if ($result === false && isSet($httpClient->errormsg)) { + throw new Exception(SystemTextEncoding::toUTF8($httpClient->errormsg)); + } + + switch ($action) { + case "download": + session_write_close(); + exit(); + break; + case "get_content": + header("Content-type:text/plain"); + break; + case "stat": + header("Content-type:application/json"); + break; + default: + $contentType = $httpClient->getHeader("content-type"); + if (!isSet($contentType) || strlen($contentType) == 0) { + $contentType = "text/xml"; + } + header("Content-type: ".$contentType); + break; + } + print $httpClient->getContent(); + session_write_close(); + exit(); + } + + public function resetConnexionRepository($action, $httpVars, $params) + { + if ($action == "switch_repository") { + if (isSet($_SESSION["AJXP_REMOTE_SESSION"])) { + unset($_SESSION["AJXP_REMOTE_SESSION"]); + } + } + } + + public function uploadActions($action, $httpVars, $filesVars) + { + switch ($action) { + case "trigger_remote_copy": + if(!$this->hasFilesToCopy()) break; + $toCopy = $this->getFileNameToCopy(); + AJXP_Logger::debug("trigger_remote", $toCopy); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::triggerBgAction("next_to_remote", array(), "Copying file ".$toCopy." to remote server"); + AJXP_XMLWriter::close(); + exit(1); + break; + case "next_to_remote": + if(!$this->hasFilesToCopy()) break; + $fData = $this->getNextFileToCopy(); + $nextFile = ''; + if ($this->hasFilesToCopy()) { + $nextFile = $this->getFileNameToCopy(); + } + $crtRep = ConfService::getRepository(); + session_write_close(); + + $secureToken = ""; + $httpClient = $this->getRemoteConnexion($secureToken); + //$httpClient->setDebug(true); + $postData = array( + "get_action"=>"upload", + "dir"=>base64_encode($fData["destination"]), + "secure_token" => $secureToken + ); + + $httpClient->postFile($crtRep->getOption("URI")."?", $postData, "Filedata", $fData); + if (strpos($httpClient->getHeader("content-type"), "text/xml") !== false && strpos($httpClient->getContent(), "require_auth") != false) { + $httpClient = $this->getRemoteConnexion($secureToken, true); + $postData["secure_token"] = $secureToken; + $httpClient->postFile($crtRep->getOption("URI"), $postData, "Filedata", $fData); + } + unlink($fData["tmp_name"]); + $response = $httpClient->getContent(); + AJXP_XMLWriter::header(); + AJXP_Logger::debug("next_to_remote", $nextFile); + if (intval($response)>=400) { + AJXP_XMLWriter::sendMessage(null, "Error : ".intval($response)); + } else { + if ($nextFile!='') { + AJXP_XMLWriter::triggerBgAction("next_to_remote", array(), "Copying file ".SystemTextEncoding::toUTF8($nextFile)." to remote server"); + } else { + AJXP_XMLWriter::triggerBgAction("reload_node", array(), "Upload done, reloading client."); + } + } + AJXP_XMLWriter::close(); + exit(1); + break; + case "upload": + + $rep_source = AJXP_Utils::securePath("/".$httpVars['dir']); + AJXP_Logger::debug("Upload : rep_source ", array($rep_source)); + $logMessage = ""; + foreach ($filesVars as $boxName => $boxData) { + if(substr($boxName, 0, 9) != "userfile_") continue; + AJXP_Logger::debug("Upload : rep_source ", array($rep_source)); + $err = AJXP_Utils::parseFileDataErrors($boxData); + if ($err != null) { + $errorCode = $err[0]; + $errorMessage = $err[1]; + break; + } + $boxData["destination"] = $rep_source; + $destCopy = AJXP_XMLWriter::replaceAjxpXmlKeywords($this->repository->getOption("TMP_UPLOAD")); + AJXP_Logger::debug("Upload : tmp upload folder", array($destCopy)); + if (!is_dir($destCopy)) { + if (! @mkdir($destCopy)) { + AJXP_Logger::debug("Upload error : cannot create temporary folder", array($destCopy)); + $errorCode = 413; + $errorMessage = "Warning, cannot create folder for temporary copy."; + break; + } + } + if (!is_writeable($destCopy)) { + AJXP_Logger::debug("Upload error: cannot write into temporary folder"); + $errorCode = 414; + $errorMessage = "Warning, cannot write into temporary folder."; + break; + } + AJXP_Logger::debug("Upload : tmp upload folder", array($destCopy)); + if (isSet($boxData["input_upload"])) { + try { + $destName = tempnam($destCopy, ""); + AJXP_Logger::debug("Begining reading INPUT stream"); + $input = fopen("php://input", "r"); + $output = fopen($destName, "w"); + $sizeRead = 0; + while ($sizeRead < intval($boxData["size"])) { + $chunk = fread($input, 4096); + $sizeRead += strlen($chunk); + fwrite($output, $chunk, strlen($chunk)); + } + fclose($input); + fclose($output); + $boxData["tmp_name"] = $destName; + $this->storeFileToCopy($boxData); + AJXP_Logger::debug("End reading INPUT stream"); + } catch (Exception $e) { + $errorCode=411; + $errorMessage = $e->getMessage(); + break; + } + } else { + $destName = $destCopy."/".basename($boxData["tmp_name"]); + if ($destName == $boxData["tmp_name"]) $destName .= "1"; + if (move_uploaded_file($boxData["tmp_name"], $destName)) { + $boxData["tmp_name"] = $destName; + $this->storeFileToCopy($boxData); + } else { + $mess = ConfService::getMessages(); + $errorCode = 411; + $errorMessage="$mess[33] ".$boxData["name"]; + break; + } + } + } + if (isSet($errorMessage)) { + AJXP_Logger::debug("Return error $errorCode $errorMessage"); + return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $errorMessage)); + } else { + AJXP_Logger::debug("Return success"); + return array("SUCCESS" => true); + } + + session_write_close(); + break; + default: + break; + } + + } + + /** + * @return HttpClient + */ + public function getRemoteConnexion(&$remoteSecureToken, $refreshSessId=false, $repository = null) + { + require_once(AJXP_BIN_FOLDER."/class.HttpClient.php"); + if ($repository != null) { + $crtRep = $repository; + } else { + $crtRep = ConfService::getRepository(); + } + $httpClient = new HttpClient($crtRep->getOption("HOST")); + $httpClient->cookie_host = $crtRep->getOption("HOST"); + $httpClient->timeout = 10; + if (isSet($_SESSION["AJXP_REMOTE_SESSION"]) && is_array($_SESSION["AJXP_REMOTE_SESSION"])) { + $httpClient->setCookies($_SESSION["AJXP_REMOTE_SESSION"]); + } + + //$httpClient->setDebug(true); + if (!isSet($_SESSION["AJXP_REMOTE_SECURE_TOKEN"])) { + $httpClient->get($crtRep->getOption("URI")."?get_action=get_secure_token"); + $remoteSecureToken = $httpClient->getContent(); + $_SESSION["AJXP_REMOTE_SECURE_TOKEN"] = $remoteSecureToken; + } else { + $remoteSecureToken = $_SESSION["AJXP_REMOTE_SECURE_TOKEN"]; + } - if($result === false && isSet($httpClient->errormsg)){ - throw new Exception(SystemTextEncoding::toUTF8($httpClient->errormsg)); - } - - switch ($action){ - case "download": - session_write_close(); - exit(); - break; - case "get_content": - header("Content-type:text/plain"); - break; - case "stat": - header("Content-type:application/json"); - break; - default: - $contentType = $httpClient->getHeader("content-type"); - if(!isSet($contentType) || strlen($contentType) == 0){ - $contentType = "text/xml"; - } - header("Content-type: ".$contentType); - break; - } - print $httpClient->getContent(); - session_write_close(); - exit(); - } - - function resetConnexionRepository($action, $httpVars, $params){ - if($action == "switch_repository"){ - if(isSet($_SESSION["AJXP_REMOTE_SESSION"])){ - unset($_SESSION["AJXP_REMOTE_SESSION"]); - } - } - } - - function uploadActions($action, $httpVars, $filesVars){ - switch ($action){ - case "trigger_remote_copy": - if(!$this->hasFilesToCopy()) break; - $toCopy = $this->getFileNameToCopy(); - AJXP_Logger::debug("trigger_remote", $toCopy); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::triggerBgAction("next_to_remote", array(), "Copying file ".$toCopy." to remote server"); - AJXP_XMLWriter::close(); - exit(1); - break; - case "next_to_remote": - if(!$this->hasFilesToCopy()) break; - $fData = $this->getNextFileToCopy(); - $nextFile = ''; - if($this->hasFilesToCopy()){ - $nextFile = $this->getFileNameToCopy(); - } - $crtRep = ConfService::getRepository(); - session_write_close(); - - $secureToken = ""; - $httpClient = $this->getRemoteConnexion($secureToken); - //$httpClient->setDebug(true); - $postData = array( - "get_action"=>"upload", - "dir"=>base64_encode($fData["destination"]), - "secure_token" => $secureToken - ); - - $httpClient->postFile($crtRep->getOption("URI")."?", $postData, "Filedata", $fData); - if(strpos($httpClient->getHeader("content-type"), "text/xml") !== false && strpos($httpClient->getContent(), "require_auth") != false){ - $httpClient = $this->getRemoteConnexion($secureToken, true); - $postData["secure_token"] = $secureToken; - $httpClient->postFile($crtRep->getOption("URI"), $postData, "Filedata", $fData); - } - unlink($fData["tmp_name"]); - $response = $httpClient->getContent(); - AJXP_XMLWriter::header(); - AJXP_Logger::debug("next_to_remote", $nextFile); - if(intval($response)>=400){ - AJXP_XMLWriter::sendMessage(null, "Error : ".intval($response)); - }else{ - if($nextFile!=''){ - AJXP_XMLWriter::triggerBgAction("next_to_remote", array(), "Copying file ".SystemTextEncoding::toUTF8($nextFile)." to remote server"); - }else{ - AJXP_XMLWriter::triggerBgAction("reload_node", array(), "Upload done, reloading client."); - } - } - AJXP_XMLWriter::close(); - exit(1); - break; - case "upload": - - $rep_source = AJXP_Utils::securePath("/".$httpVars['dir']); - AJXP_Logger::debug("Upload : rep_source ", array($rep_source)); - $logMessage = ""; - foreach ($filesVars as $boxName => $boxData) - { - if(substr($boxName, 0, 9) != "userfile_") continue; - AJXP_Logger::debug("Upload : rep_source ", array($rep_source)); - $err = AJXP_Utils::parseFileDataErrors($boxData); - if($err != null) - { - $errorCode = $err[0]; - $errorMessage = $err[1]; - break; - } - $boxData["destination"] = $rep_source; - $destCopy = AJXP_XMLWriter::replaceAjxpXmlKeywords($this->repository->getOption("TMP_UPLOAD")); - AJXP_Logger::debug("Upload : tmp upload folder", array($destCopy)); - if(!is_dir($destCopy)){ - if(! @mkdir($destCopy)){ - AJXP_Logger::debug("Upload error : cannot create temporary folder", array($destCopy)); - $errorCode = 413; - $errorMessage = "Warning, cannot create folder for temporary copy."; - break; - } - } - if(!is_writeable($destCopy)){ - AJXP_Logger::debug("Upload error: cannot write into temporary folder"); - $errorCode = 414; - $errorMessage = "Warning, cannot write into temporary folder."; - break; - } - AJXP_Logger::debug("Upload : tmp upload folder", array($destCopy)); - if(isSet($boxData["input_upload"])){ - try{ - $destName = tempnam($destCopy, ""); - AJXP_Logger::debug("Begining reading INPUT stream"); - $input = fopen("php://input", "r"); - $output = fopen($destName, "w"); - $sizeRead = 0; - while($sizeRead < intval($boxData["size"])){ - $chunk = fread($input, 4096); - $sizeRead += strlen($chunk); - fwrite($output, $chunk, strlen($chunk)); - } - fclose($input); - fclose($output); - $boxData["tmp_name"] = $destName; - $this->storeFileToCopy($boxData); - AJXP_Logger::debug("End reading INPUT stream"); - }catch (Exception $e){ - $errorCode=411; - $errorMessage = $e->getMessage(); - break; - } - }else{ - $destName = $destCopy."/".basename($boxData["tmp_name"]); - if ($destName == $boxData["tmp_name"]) $destName .= "1"; - if(move_uploaded_file($boxData["tmp_name"], $destName)){ - $boxData["tmp_name"] = $destName; - $this->storeFileToCopy($boxData); - }else{ - $mess = ConfService::getMessages(); - $errorCode = 411; - $errorMessage="$mess[33] ".$boxData["name"]; - break; - } - } - } - if(isSet($errorMessage)){ - AJXP_Logger::debug("Return error $errorCode $errorMessage"); - return array("ERROR" => array("CODE" => $errorCode, "MESSAGE" => $errorMessage)); - }else{ - AJXP_Logger::debug("Return success"); - return array("SUCCESS" => true); - } + if (!$crtRep->getOption("USE_AUTH")) { + return $httpClient; + } + $uri = ""; + if ($crtRep->getOption("AUTH_URI") != "") { + $httpClient->setAuthorization($crtRep->getOption("AUTH_USER"), $crtRep->getOption("AUTH_PASS")); + $uri = $crtRep->getOption("AUTH_URI")."?secure_token=$remoteSecureToken"; + } + if (!isSet($_SESSION["AJXP_REMOTE_SESSION"]) || !is_array($_SESSION["AJXP_REMOTE_SESSION"]) || $refreshSessId) { + if ($uri == "") { + AJXP_Logger::debug("Remote_fs : relog necessary"); + // Retrieve a seed! + $httpClient->get($crtRep->getOption("URI")."?get_action=get_seed&secure_token=$remoteSecureToken"); + $seed = $httpClient->getContent(); + $cookies = $httpClient->getCookies(); + if (isSet($cookies["AjaXplorer"])) { + $_SESSION["AJXP_REMOTE_SESSION"] = $cookies; + } + $user = $crtRep->getOption("AUTH_USER"); + $pass = $crtRep->getOption("AUTH_PASS"); + $pass = md5(md5($pass).$seed); + $uri = $crtRep->getOption("URI")."?get_action=login&userid=".$user."&password=".$pass."&login_seed=$seed&secure_token=$remoteSecureToken"; + $httpClient->get($uri); + $content = $httpClient->getContent(); + $matches = array(); + if (preg_match_all('#.*?secure_token="(.*?)".*?#s', $content, $matches)) { + $remoteSecureToken = $matches[1][0]; + $_SESSION["AJXP_REMOTE_SECURE_TOKEN"] = $remoteSecureToken; + } + $httpClient->setHeadersOnly(false); + } else { + $httpClient->setHeadersOnly(true); + $httpClient->get($uri); + $httpClient->setHeadersOnly(false); + } + $cookies = $httpClient->getCookies(); + $_SESSION["AJXP_REMOTE_SESSION"] = $httpClient->getCookies(); + } else { + $httpClient->setCookies($_SESSION["AJXP_REMOTE_SESSION"]); + } + return $httpClient; + } - session_write_close(); - break; - default: - break; - } - - } - - /** - * @return HttpClient - */ - function getRemoteConnexion(&$remoteSecureToken, $refreshSessId=false, $repository = null){ - require_once(AJXP_BIN_FOLDER."/class.HttpClient.php"); - if($repository != null){ - $crtRep = $repository; - }else{ - $crtRep = ConfService::getRepository(); - } - $httpClient = new HttpClient($crtRep->getOption("HOST")); - $httpClient->cookie_host = $crtRep->getOption("HOST"); - $httpClient->timeout = 10; - if(isSet($_SESSION["AJXP_REMOTE_SESSION"]) && is_array($_SESSION["AJXP_REMOTE_SESSION"])){ - $httpClient->setCookies($_SESSION["AJXP_REMOTE_SESSION"]); - } - - //$httpClient->setDebug(true); - if(!isSet($_SESSION["AJXP_REMOTE_SECURE_TOKEN"])){ - $httpClient->get($crtRep->getOption("URI")."?get_action=get_secure_token"); - $remoteSecureToken = $httpClient->getContent(); - $_SESSION["AJXP_REMOTE_SECURE_TOKEN"] = $remoteSecureToken; - }else{ - $remoteSecureToken = $_SESSION["AJXP_REMOTE_SECURE_TOKEN"]; - } - - if(!$crtRep->getOption("USE_AUTH")){ - return $httpClient; - } - $uri = ""; - if($crtRep->getOption("AUTH_URI") != ""){ - $httpClient->setAuthorization($crtRep->getOption("AUTH_USER"), $crtRep->getOption("AUTH_PASS")); - $uri = $crtRep->getOption("AUTH_URI")."?secure_token=$remoteSecureToken"; - } - if(!isSet($_SESSION["AJXP_REMOTE_SESSION"]) || !is_array($_SESSION["AJXP_REMOTE_SESSION"]) || $refreshSessId){ - if($uri == ""){ - AJXP_Logger::debug("Remote_fs : relog necessary"); - // Retrieve a seed! - $httpClient->get($crtRep->getOption("URI")."?get_action=get_seed&secure_token=$remoteSecureToken"); - $seed = $httpClient->getContent(); - $cookies = $httpClient->getCookies(); - if(isSet($cookies["AjaXplorer"])){ - $_SESSION["AJXP_REMOTE_SESSION"] = $cookies; - } - $user = $crtRep->getOption("AUTH_USER"); - $pass = $crtRep->getOption("AUTH_PASS"); - $pass = md5(md5($pass).$seed); - $uri = $crtRep->getOption("URI")."?get_action=login&userid=".$user."&password=".$pass."&login_seed=$seed&secure_token=$remoteSecureToken"; - $httpClient->get($uri); - $content = $httpClient->getContent(); - $matches = array(); - if(preg_match_all('#.*?secure_token="(.*?)".*?#s', $content, $matches)){ - $remoteSecureToken = $matches[1][0]; - $_SESSION["AJXP_REMOTE_SECURE_TOKEN"] = $remoteSecureToken; - } - $httpClient->setHeadersOnly(false); - }else{ - $httpClient->setHeadersOnly(true); - $httpClient->get($uri); - $httpClient->setHeadersOnly(false); - } - $cookies = $httpClient->getCookies(); - $_SESSION["AJXP_REMOTE_SESSION"] = $httpClient->getCookies(); - }else{ - $httpClient->setCookies($_SESSION["AJXP_REMOTE_SESSION"]); - } - return $httpClient; - } - - public static function isWriteable($path, $type="dir"){ - return is_writable($path); - } - - function storeFileToCopy($fileData){ - $user = AuthService::getLoggedUser(); - $files = $user->getTemporaryData("tmp_upload"); - $files[] = $fileData; - AJXP_Logger::debug("Storing data", $fileData); - $user->saveTemporaryData("tmp_upload", $files); + public static function isWriteable($path, $type="dir") + { + return is_writable($path); + } + + public function storeFileToCopy($fileData) + { + $user = AuthService::getLoggedUser(); + $files = $user->getTemporaryData("tmp_upload"); + $files[] = $fileData; + AJXP_Logger::debug("Storing data", $fileData); + $user->saveTemporaryData("tmp_upload", $files); if(strpos($_SERVER["HTTP_USER_AGENT"], "ajaxplorer-ios-client") !== false || strpos($_SERVER["HTTP_USER_AGENT"], "Apache-HttpClient") !== false){ AJXP_Logger::logAction("Up from ".$_SERVER["HTTP_USER_AGENT"] ." - direct triger of next to remote"); $this->uploadActions("next_to_remote", array(), array()); } - } - - function getFileNameToCopy(){ - $user = AuthService::getLoggedUser(); - $files = $user->getTemporaryData("tmp_upload"); - return $files[0]["name"]; - } - - function getNextFileToCopy(){ - if(!$this->hasFilesToCopy()) return ""; - $user = AuthService::getLoggedUser(); - $files = $user->getTemporaryData("tmp_upload"); - $fData = $files[0]; - array_shift($files); - $user->saveTemporaryData("tmp_upload", $files); - return $fData; - } - - function hasFilesToCopy(){ - $user = AuthService::getLoggedUser(); - $files = $user->getTemporaryData("tmp_upload"); - return (count($files)?true:false); - } - -} + } + + public function getFileNameToCopy() + { + $user = AuthService::getLoggedUser(); + $files = $user->getTemporaryData("tmp_upload"); + return $files[0]["name"]; + } -?> + public function getNextFileToCopy() + { + if(!$this->hasFilesToCopy()) return ""; + $user = AuthService::getLoggedUser(); + $files = $user->getTemporaryData("tmp_upload"); + $fData = $files[0]; + array_shift($files); + $user->saveTemporaryData("tmp_upload", $files); + return $fData; + } + + public function hasFilesToCopy() + { + $user = AuthService::getLoggedUser(); + $files = $user->getTemporaryData("tmp_upload"); + return (count($files)?true:false); + } + +} diff --git a/core/src/plugins/access.remote_fs/class.remote_fsAccessWrapper.php b/core/src/plugins/access.remote_fs/class.remote_fsAccessWrapper.php index 23dceb4f88..2d42b6bf9b 100644 --- a/core/src/plugins/access.remote_fs/class.remote_fsAccessWrapper.php +++ b/core/src/plugins/access.remote_fs/class.remote_fsAccessWrapper.php @@ -25,242 +25,264 @@ * @package AjaXplorer_Plugins * @subpackage Access */ -class remote_fsAccessWrapper implements AjxpWrapper { - - // Instance vars $this-> - protected $host; - protected $port; - protected $secure; - protected $path; - protected $user; - protected $password; - protected $repositoryId; - protected $fp; - - protected $crtMode; - protected $crtParameters; - protected $postFileData; - - public static function getRealFSReference($path, $persistent = FALSE){ - $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()); - $tmpHandle = fopen($tmpFile, "wb"); - self::copyFileInStream($path, $tmpHandle); - fclose($tmpHandle); - if(!$persistent){ - register_shutdown_function(array("AJXP_Utils", "silentUnlink"), $tmpFile); - } - return $tmpFile; - } - - public static function isRemote(){ - return true; +class remote_fsAccessWrapper implements AjxpWrapper +{ + // Instance vars $this-> + protected $host; + protected $port; + protected $secure; + protected $path; + protected $user; + protected $password; + protected $repositoryId; + protected $fp; + + protected $crtMode; + protected $crtParameters; + protected $postFileData; + + public static function getRealFSReference($path, $persistent = FALSE) + { + $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()); + $tmpHandle = fopen($tmpFile, "wb"); + self::copyFileInStream($path, $tmpHandle); + fclose($tmpHandle); + if (!$persistent) { + register_shutdown_function(array("AJXP_Utils", "silentUnlink"), $tmpFile); + } + return $tmpFile; + } + + public static function isRemote() + { + return true; } - - public static function copyFileInStream($path, $stream){ - $fake = new remote_fsAccessWrapper(); - $parts = $fake->parseUrl($path); - $client = $fake->createHttpClient(); - $client->writeContentToStream($stream); - $client->get($fake->path."?get_action=get_content&file=".AJXP_Utils::securePath($parts["path"])); - $client->clearContentDestStream(); + + public static function copyFileInStream($path, $stream) + { + $fake = new remote_fsAccessWrapper(); + $parts = $fake->parseUrl($path); + $client = $fake->createHttpClient(); + $client->writeContentToStream($stream); + $client->get($fake->path."?get_action=get_content&file=".AJXP_Utils::securePath($parts["path"])); + $client->clearContentDestStream(); } - - public function stream_open($url, $mode, $options, &$context){ - if($mode == "w" || $mode == "rw"){ - $this->crtMode = 'write'; - $parts = $this->parseUrl($url); - $this->crtParameters = array( - "get_action"=>"put_content", - "encode" => "base64", - "file" => urldecode(AJXP_Utils::securePath($parts["path"])) - ); - $tmpFileBuffer = realpath(AJXP_Utils::getAjxpTmpDir()).md5(time()); - $this->postFileData = $tmpFileBuffer; - $this->fp = fopen($tmpFileBuffer, "w"); - }else{ - $this->crtMode = 'read'; - $this->fp = tmpfile(); - $this->copyFileInStream($url, $this->fp); - rewind($this->fp); - } - return ($this->fp !== false); - } - - public function stream_stat(){ - return fstat($this->fp); - } - - public function stream_seek($offset , $whence = SEEK_SET){ - fseek($this->fp, $offset, SEEK_SET); + + public function stream_open($url, $mode, $options, &$context) + { + if ($mode == "w" || $mode == "rw") { + $this->crtMode = 'write'; + $parts = $this->parseUrl($url); + $this->crtParameters = array( + "get_action"=>"put_content", + "encode" => "base64", + "file" => urldecode(AJXP_Utils::securePath($parts["path"])) + ); + $tmpFileBuffer = realpath(AJXP_Utils::getAjxpTmpDir()).md5(time()); + $this->postFileData = $tmpFileBuffer; + $this->fp = fopen($tmpFileBuffer, "w"); + } else { + $this->crtMode = 'read'; + $this->fp = tmpfile(); + $this->copyFileInStream($url, $this->fp); + rewind($this->fp); + } + return ($this->fp !== false); } - - public function stream_tell(){ - return ftell($this->fp); - } - - public function stream_read($count){ - return fread($this->fp, $count); + + public function stream_stat() + { + return fstat($this->fp); + } + + public function stream_seek($offset , $whence = SEEK_SET) + { + fseek($this->fp, $offset, SEEK_SET); + } + + public function stream_tell() + { + return ftell($this->fp); } - public function stream_write($data){ - fwrite($this->fp, $data, strlen($data)); + public function stream_read($count) + { + return fread($this->fp, $count); + } + + public function stream_write($data) + { + fwrite($this->fp, $data, strlen($data)); return strlen($data); } - public function stream_eof(){ - return feof($this->fp); + public function stream_eof() + { + return feof($this->fp); } - - public function stream_close(){ - if(isSet($this->fp) && $this->fp!=-1 && $this->fp!==false){ - fclose($this->fp); - } + + public function stream_close() + { + if (isSet($this->fp) && $this->fp!=-1 && $this->fp!==false) { + fclose($this->fp); + } } - - public function stream_flush(){ - if(isSet($this->fp) && $this->fp!=-1 && $this->fp!==false){ - if($this->crtMode == 'write'){ - rewind($this->fp); - AJXP_Logger::debug("Http_fput", array("target"=>$this->path)); - $link = $this->createHttpClient(); - $this->crtParameters["content"] = base64_encode(implode("", file($this->postFileData))); - $link->post($this->path, $this->crtParameters); - }else{ - fflush($this->fp); - } - } + + public function stream_flush() + { + if (isSet($this->fp) && $this->fp!=-1 && $this->fp!==false) { + if ($this->crtMode == 'write') { + rewind($this->fp); + AJXP_Logger::debug("Http_fput", array("target"=>$this->path)); + $link = $this->createHttpClient(); + $this->crtParameters["content"] = base64_encode(implode("", file($this->postFileData))); + $link->post($this->path, $this->crtParameters); + } else { + fflush($this->fp); + } + } } - public function url_stat($path, $flags){ - $parts = $this->parseUrl($path); - $client = $this->createHttpClient(); - $client->get($this->path."?get_action=stat&file=".AJXP_Utils::securePath($parts["path"])); - $json = $client->getContent(); - $decode = json_decode($json, true); - return $decode; + public function url_stat($path, $flags) + { + $parts = $this->parseUrl($path); + $client = $this->createHttpClient(); + $client->get($this->path."?get_action=stat&file=".AJXP_Utils::securePath($parts["path"])); + $json = $client->getContent(); + $decode = json_decode($json, true); + return $decode; } - + // NOT IMPLEMENTED - public static function changeMode($path, $chmodValue){ - } - - public function unlink($url){ + public static function changeMode($path, $chmodValue) + { + } + + public function unlink($url) + { + } + + public function rmdir($url, $options) + { + } + + public function mkdir($url, $mode, $options) + { } - - public function rmdir($url, $options){ + + public function rename($from, $to) + { } - - public function mkdir($url, $mode, $options){ + + + public function dir_opendir ($url , $options ) + { } - - public function rename($from, $to){ + + public function dir_closedir () + { } - - - public function dir_opendir ($url , $options ){ - } - - public function dir_closedir (){ - } - - public function dir_readdir (){ - } - - public function dir_rewinddir (){ - } - - - - protected function parseUrl($url){ - // URL MAY BE ajxp.ftp://username:password@host/path - $urlParts = parse_url($url); - $this->repositoryId = $urlParts["host"]; - $repository = ConfService::getRepositoryById($this->repositoryId); - // Get USER/PASS - // 1. Try from URL - if(isSet($urlParts["user"]) && isset($urlParts["pass"])){ - $this->user = $urlParts["user"]; - $this->password = $urlParts["pass"]; - } - // 2. Try from user wallet - if(!isSet($this->user) || $this->user==""){ - $loggedUser = AuthService::getLoggedUser(); - if($loggedUser != null){ - $wallet = $loggedUser->getPref("AJXP_WALLET"); - if(is_array($wallet) && isSet($wallet[$this->repositoryId]["AUTH_USER"])){ - $this->user = $wallet[$this->repositoryId]["AUTH_USER"]; - $this->password = $loggedUser->decodeUserPassword($wallet[$this->repositoryId]["AUTH_PASS"]); - } - } - } - // 3. Try from repository config - if(!isSet($this->user) || $this->user==""){ - $this->user = $repository->getOption("AUTH_USER"); - $this->password = $repository->getOption("AUTH_PASS"); - } - if(!isSet($this->user) || $this->user==""){ - throw new AJXP_Exception("Cannot find user/pass for Http access!"); - } - - $this->host = $repository->getOption("HOST"); - $this->path = $repository->getOption("URI"); - $this->auth_path = $repository->getOption("AUTH_URI"); - $this->use_auth = $repository->getOption("USE_AUTH"); - - $urlParts["path"] = urlencode($urlParts["path"]); - + + public function dir_readdir () + { + } + + public function dir_rewinddir () + { + } + + + + protected function parseUrl($url) + { + // URL MAY BE ajxp.ftp://username:password@host/path + $urlParts = parse_url($url); + $this->repositoryId = $urlParts["host"]; + $repository = ConfService::getRepositoryById($this->repositoryId); + // Get USER/PASS + // 1. Try from URL + if (isSet($urlParts["user"]) && isset($urlParts["pass"])) { + $this->user = $urlParts["user"]; + $this->password = $urlParts["pass"]; + } + // 2. Try from user wallet + if (!isSet($this->user) || $this->user=="") { + $loggedUser = AuthService::getLoggedUser(); + if ($loggedUser != null) { + $wallet = $loggedUser->getPref("AJXP_WALLET"); + if (is_array($wallet) && isSet($wallet[$this->repositoryId]["AUTH_USER"])) { + $this->user = $wallet[$this->repositoryId]["AUTH_USER"]; + $this->password = $loggedUser->decodeUserPassword($wallet[$this->repositoryId]["AUTH_PASS"]); + } + } + } + // 3. Try from repository config + if (!isSet($this->user) || $this->user=="") { + $this->user = $repository->getOption("AUTH_USER"); + $this->password = $repository->getOption("AUTH_PASS"); + } + if (!isSet($this->user) || $this->user=="") { + throw new AJXP_Exception("Cannot find user/pass for Http access!"); + } + + $this->host = $repository->getOption("HOST"); + $this->path = $repository->getOption("URI"); + $this->auth_path = $repository->getOption("AUTH_URI"); + $this->use_auth = $repository->getOption("USE_AUTH"); + + $urlParts["path"] = urlencode($urlParts["path"]); + return $urlParts; - } - - /** - * Initialize and return the HttpClient - * - * @return HttpClient - */ - protected function createHttpClient(){ - - require_once(AJXP_BIN_FOLDER."/class.HttpClient.php"); - $httpClient = new HttpClient($this->host); - $httpClient->cookie_host = $this->host; - $httpClient->timeout = 50; - AJXP_Logger::debug("Creating Http client", array()); - //$httpClient->setDebug(true); - if(!$this->use_auth){ - return $httpClient; - } - - $uri = ""; - if($this->auth_path != ""){ - $httpClient->setAuthorization($this->user, $this->password); - $uri = $this->auth_path; - } - if(!isSet($_SESSION["AJXP_REMOTE_SESSION"])){ - if($uri == ""){ - // Retrieve a seed! - $httpClient->get($this->path."?get_action=get_seed"); - $seed = $httpClient->getContent(); - $user = $this->user; - $pass = $this->password; - $pass = md5(md5($pass).$seed); - $uri = $this->path."?get_action=login&userid=".$user."&password=".$pass."&login_seed=$seed"; - } - $httpClient->setHeadersOnly(true); - $httpClient->get($uri); - $httpClient->setHeadersOnly(false); - $cookies = $httpClient->getCookies(); - if(isSet($cookies["AjaXplorer"])){ - $_SESSION["AJXP_REMOTE_SESSION"] = $cookies["AjaXplorer"]; - $remoteSessionId = $cookies["AjaXplorer"]; - } - }else{ - $remoteSessionId = $_SESSION["AJXP_REMOTE_SESSION"]; - $httpClient->setCookies(array("AjaXplorer"=>$remoteSessionId)); - } - AJXP_Logger::debug("Http Client created", array()); - return $httpClient; - } - - + } + + /** + * Initialize and return the HttpClient + * + * @return HttpClient + */ + protected function createHttpClient() + { + require_once(AJXP_BIN_FOLDER."/class.HttpClient.php"); + $httpClient = new HttpClient($this->host); + $httpClient->cookie_host = $this->host; + $httpClient->timeout = 50; + AJXP_Logger::debug("Creating Http client", array()); + //$httpClient->setDebug(true); + if (!$this->use_auth) { + return $httpClient; + } + + $uri = ""; + if ($this->auth_path != "") { + $httpClient->setAuthorization($this->user, $this->password); + $uri = $this->auth_path; + } + if (!isSet($_SESSION["AJXP_REMOTE_SESSION"])) { + if ($uri == "") { + // Retrieve a seed! + $httpClient->get($this->path."?get_action=get_seed"); + $seed = $httpClient->getContent(); + $user = $this->user; + $pass = $this->password; + $pass = md5(md5($pass).$seed); + $uri = $this->path."?get_action=login&userid=".$user."&password=".$pass."&login_seed=$seed"; + } + $httpClient->setHeadersOnly(true); + $httpClient->get($uri); + $httpClient->setHeadersOnly(false); + $cookies = $httpClient->getCookies(); + if (isSet($cookies["AjaXplorer"])) { + $_SESSION["AJXP_REMOTE_SESSION"] = $cookies["AjaXplorer"]; + $remoteSessionId = $cookies["AjaXplorer"]; + } + } else { + $remoteSessionId = $_SESSION["AJXP_REMOTE_SESSION"]; + $httpClient->setCookies(array("AjaXplorer"=>$remoteSessionId)); + } + AJXP_Logger::debug("Http Client created", array()); + return $httpClient; + } + + } -?> \ No newline at end of file diff --git a/core/src/plugins/access.remote_fs/i18n/conf/en.php b/core/src/plugins/access.remote_fs/i18n/conf/en.php index bfb4c366c6..64823dd10d 100644 --- a/core/src/plugins/access.remote_fs/i18n/conf/en.php +++ b/core/src/plugins/access.remote_fs/i18n/conf/en.php @@ -38,4 +38,3 @@ "Api Capabilities" => "Api Capabilities", "AjaXplorer plugins actions supported by remote server, thus forwarded directly instead of executed locally." => "AjaXplorer plugins actions supported by remote server, thus forwarded directly instead of executed locally.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.remote_fs/i18n/conf/fr.php b/core/src/plugins/access.remote_fs/i18n/conf/fr.php index d79fe05b65..6fc9c10864 100644 --- a/core/src/plugins/access.remote_fs/i18n/conf/fr.php +++ b/core/src/plugins/access.remote_fs/i18n/conf/fr.php @@ -38,4 +38,3 @@ "Api Capabilities" => "Capacités de l'Api", "AjaXplorer plugins actions supported by remote server, thus forwarded directly instead of executed locally." => "Liste d'actions de plugins supportées directement par le serveur et qui seront forwardées directement au serveur distant.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.remote_fs/i18n/conf/pt.php b/core/src/plugins/access.remote_fs/i18n/conf/pt.php index da3f82351d..ea8659cc0f 100644 --- a/core/src/plugins/access.remote_fs/i18n/conf/pt.php +++ b/core/src/plugins/access.remote_fs/i18n/conf/pt.php @@ -38,4 +38,3 @@ "Api Capabilities" => "Capacidades da API", "AjaXplorer plugins actions supported by remote server, thus forwarded directly instead of executed locally." => "As acções dos plugins AjaXplorer suportadas pelo servidor remoto, sendo estas redireccionadas directamente para o servidor remoto em vez de tratadas localmente.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.remote_fs/manifest.xml b/core/src/plugins/access.remote_fs/manifest.xml index 3c44d41523..58b7a07d7a 100644 --- a/core/src/plugins/access.remote_fs/manifest.xml +++ b/core/src/plugins/access.remote_fs/manifest.xml @@ -12,7 +12,7 @@ - + @@ -27,8 +27,8 @@ - - + + @@ -44,6 +44,6 @@ - + - \ No newline at end of file + diff --git a/core/src/plugins/access.s3/class.s3AccessDriver.php b/core/src/plugins/access.s3/class.s3AccessDriver.php index 6fb9729b6d..e3eb10a934 100755 --- a/core/src/plugins/access.s3/class.s3AccessDriver.php +++ b/core/src/plugins/access.s3/class.s3AccessDriver.php @@ -1,105 +1,108 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * AJXP_Plugin to access a webdav enabled server - * @package AjaXplorer_Plugins - * @subpackage Access - */ -class s3AccessDriver extends fsAccessDriver -{ - /** - * @var Repository - */ - public $repository; - public $driverConf; - protected $wrapperClassName; - protected $urlBase; - - public function performChecks(){ - // Check CURL, OPENSSL & AWS LIBRARY - if(!extension_loaded("curl")) throw new Exception("Cannot find php_curl extension!"); - if(!extension_loaded("openssl")) throw new Exception("Cannot find openssl extension!"); - if(!file_exists($this->getBaseDir()."/aws-sdk/sdk.class.php")) throw new Exception("Cannot find AWS PHP SDK. Make sure it is installed in the aws-sdk folder."); - } - - - function initRepository(){ - - require_once($this->getBaseDir()."/aS3StreamWrapper/lib/wrapper/aS3StreamWrapper.class.php"); - if(!in_array("s3", stream_get_wrappers())){ - $wrapper = new aS3StreamWrapper(); - $wrapper->register(array('protocol' => 's3', - 'acl' => AmazonS3::ACL_OWNER_FULL_CONTROL, - 'key' => $this->repository->getOption("API_KEY"), - 'secretKey' => $this->repository->getOption("SECRET_KEY"), - 'region' => $this->repository->getOption("REGION"))); - } - - if(is_array($this->pluginConf)){ - $this->driverConf = $this->pluginConf; - }else{ - $this->driverConf = array(); - } - - $path = $this->repository->getOption("PATH"); - $recycle = $this->repository->getOption("RECYCLE_BIN"); - ConfService::setConf("PROBE_REAL_SIZE", false); - $wrapperData = $this->detectStreamWrapper(true); - $this->wrapperClassName = $wrapperData["classname"]; - $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); - if($recycle != ""){ - RecycleBinManager::init($this->urlBase, "/".$recycle); - } - } - - /** - * Parse - * @param DOMNode $contribNode - */ - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($contribNode->nodeName != "actions") return ; - $this->disableArchiveBrowsingContributions($contribNode); - } - - function isWriteable($dir, $type="dir"){ - return true; - } - - function loadNodeInfo(&$node, $parentNode = false, $details = false){ - parent::loadNodeInfo($node, $parentNode, $details); - if(!$node->isLeaf()){ - $node->setLabel(rtrim($node->getLabel(), "/")); - } - } - - function filesystemFileSize($filePath){ - $bytesize = filesize($filePath); - return $bytesize; - } - -} - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * AJXP_Plugin to access a webdav enabled server + * @package AjaXplorer_Plugins + * @subpackage Access + */ +class s3AccessDriver extends fsAccessDriver +{ + /** + * @var Repository + */ + public $repository; + public $driverConf; + protected $wrapperClassName; + protected $urlBase; + + public function performChecks() + { + // Check CURL, OPENSSL & AWS LIBRARY + if(!extension_loaded("curl")) throw new Exception("Cannot find php_curl extension!"); + if(!extension_loaded("openssl")) throw new Exception("Cannot find openssl extension!"); + if(!file_exists($this->getBaseDir()."/aws-sdk/sdk.class.php")) throw new Exception("Cannot find AWS PHP SDK. Make sure it is installed in the aws-sdk folder."); + } + + + public function initRepository() + { + require_once($this->getBaseDir()."/aS3StreamWrapper/lib/wrapper/aS3StreamWrapper.class.php"); + if (!in_array("s3", stream_get_wrappers())) { + $wrapper = new aS3StreamWrapper(); + $wrapper->register(array('protocol' => 's3', + 'acl' => AmazonS3::ACL_OWNER_FULL_CONTROL, + 'key' => $this->repository->getOption("API_KEY"), + 'secretKey' => $this->repository->getOption("SECRET_KEY"), + 'region' => $this->repository->getOption("REGION"))); + } + + if (is_array($this->pluginConf)) { + $this->driverConf = $this->pluginConf; + } else { + $this->driverConf = array(); + } + + $path = $this->repository->getOption("PATH"); + $recycle = $this->repository->getOption("RECYCLE_BIN"); + ConfService::setConf("PROBE_REAL_SIZE", false); + $wrapperData = $this->detectStreamWrapper(true); + $this->wrapperClassName = $wrapperData["classname"]; + $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); + if ($recycle != "") { + RecycleBinManager::init($this->urlBase, "/".$recycle); + } + } + + /** + * Parse + * @param DOMNode $contribNode + */ + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if($contribNode->nodeName != "actions") return ; + $this->disableArchiveBrowsingContributions($contribNode); + } + + public function isWriteable($dir, $type="dir") + { + return true; + } + + public function loadNodeInfo(&$node, $parentNode = false, $details = false) + { + parent::loadNodeInfo($node, $parentNode, $details); + if (!$node->isLeaf()) { + $node->setLabel(rtrim($node->getLabel(), "/")); + } + } + + public function filesystemFileSize($filePath) + { + $bytesize = filesize($filePath); + return $bytesize; + } + +} diff --git a/core/src/plugins/access.s3/class.s3AccessWrapper.php b/core/src/plugins/access.s3/class.s3AccessWrapper.php index adeef0bfe2..91b35ad7c8 100755 --- a/core/src/plugins/access.s3/class.s3AccessWrapper.php +++ b/core/src/plugins/access.s3/class.s3AccessWrapper.php @@ -28,22 +28,23 @@ * @package AjaXplorer_Plugins * @subpackage Access */ -class s3AccessWrapper extends fsAccessWrapper { - +class s3AccessWrapper extends fsAccessWrapper +{ public static $lastException; /** - * Initialize the stream from the given path. + * Initialize the stream from the given path. * Concretely, transform ajxp.webdav:// into webdav:// * * @param string $path * @return mixed Real path or -1 if currentListing contains the listing : original path converted to real path */ - protected static function initPath($path, $streamType, $storeOpenContext = false, $skipZip = false){ - $url = parse_url($path); - $repoId = $url["host"]; - $repoObject = ConfService::getRepositoryById($repoId); - if(!isSet($repoObject)) { + protected static function initPath($path, $streamType, $storeOpenContext = false, $skipZip = false) + { + $url = parse_url($path); + $repoId = $url["host"]; + $repoObject = ConfService::getRepositoryById($repoId); + if (!isSet($repoObject)) { $e = new Exception("Cannot find repository with id ".$repoId); self::$lastException = $e; throw $e; @@ -52,12 +53,12 @@ protected static function initPath($path, $streamType, $storeOpenContext = false $p = "s3://".$baseContainer.str_replace("//", "/", $url["path"]); return $p; } - + /** * Opens the stream * Diff with parent class : do not "securePath", as it removes double slash * - * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" + * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" * @param String $mode * @param unknown_type $options * @param unknown_type $opened_path @@ -65,19 +66,19 @@ protected static function initPath($path, $streamType, $storeOpenContext = false */ public function stream_open($path, $mode, $options, &$context) { - try{ - $this->realPath = $this->initPath($path, "file"); - }catch (Exception $e){ - AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); - return false; - } - if($this->realPath == -1){ - $this->fp = -1; - return true; - }else{ - $this->fp = fopen($this->realPath, $mode, $options); - return ($this->fp !== false); - } + try { + $this->realPath = $this->initPath($path, "file"); + } catch (Exception $e) { + AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); + return false; + } + if ($this->realPath == -1) { + $this->fp = -1; + return true; + } else { + $this->fp = fopen($this->realPath, $mode, $options); + return ($this->fp !== false); + } } /** @@ -88,96 +89,103 @@ public function stream_open($path, $mode, $options, &$context) * @param unknown_type $flags * @return unknown */ - public function url_stat($path, $flags){ - // File and zip case + public function url_stat($path, $flags) + { + // File and zip case // AJXP_Logger::debug("Stating $path"); - $stat = @stat($this->initPath($path, "file")); + $stat = @stat($this->initPath($path, "file")); if($stat == null) return null; - if($stat["mode"] == 0666){ + if ($stat["mode"] == 0666) { $stat[2] = $stat["mode"] |= 0100000; // S_ISREG } $parsed = parse_url($path); - if($stat["mtime"] == $stat["ctime"] && $stat["ctime"] == $stat["atime"] && $stat["atime"] == 0 && $parsed["path"] != "/") { + if ($stat["mtime"] == $stat["ctime"] && $stat["ctime"] == $stat["atime"] && $stat["atime"] == 0 && $parsed["path"] != "/") { //AJXP_Logger::debug("Nullifying stats"); return null; } return $stat; - // Non existing file - return null; + // Non existing file + return null; } - + /** * Opens a handle to the dir - * Fix PEAR by being sure it ends up with "/", to avoid + * Fix PEAR by being sure it ends up with "/", to avoid * adding the current dir to the children list. * * @param unknown_type $path * @param unknown_type $options * @return unknown */ - public function dir_opendir ($path , $options ){ - $this->realPath = $this->initPath($path, "dir", true); - if($this->realPath[strlen($this->realPath)-1] != "/"){ - $this->realPath.="/"; - } - if(is_string($this->realPath)){ - $this->dH = @opendir($this->realPath); - }else if($this->realPath == -1){ - $this->dH = -1; - } - return $this->dH !== false; - } - - - // DUPBLICATE STATIC FUNCTIONS TO BE SURE - // NOT TO MESS WITH self:: CALLS - - public static function removeTmpFile($tmpDir, $tmpFile){ - if(is_file($tmpFile)) unlink($tmpFile); - if(is_dir($tmpDir)) rmdir($tmpDir); - } - - protected static function closeWrapper(){ - if(self::$crtZip != null) { - self::$crtZip = null; - self::$currentListing = null; - self::$currentListingKeys = null; - self::$currentListingIndex = null; - self::$currentFileKey = null; - } - } - - public static function getRealFSReference($path, $persistent = false){ + public function dir_opendir ($path , $options ) + { + $this->realPath = $this->initPath($path, "dir", true); + if ($this->realPath[strlen($this->realPath)-1] != "/") { + $this->realPath.="/"; + } + if (is_string($this->realPath)) { + $this->dH = @opendir($this->realPath); + } else if ($this->realPath == -1) { + $this->dH = -1; + } + return $this->dH !== false; + } + + + // DUPBLICATE STATIC FUNCTIONS TO BE SURE + // NOT TO MESS WITH self:: CALLS + + public static function removeTmpFile($tmpDir, $tmpFile) + { + if(is_file($tmpFile)) unlink($tmpFile); + if(is_dir($tmpDir)) rmdir($tmpDir); + } + + protected static function closeWrapper() + { + if (self::$crtZip != null) { + self::$crtZip = null; + self::$currentListing = null; + self::$currentListingKeys = null; + self::$currentListingIndex = null; + self::$currentFileKey = null; + } + } + + public static function getRealFSReference($path, $persistent = false) + { $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()).".".pathinfo($path, PATHINFO_EXTENSION); - $tmpHandle = fopen($tmpFile, "wb"); - self::copyFileInStream($path, $tmpHandle); - fclose($tmpHandle); - if(!$persistent){ - register_shutdown_function(array("AJXP_Utils", "silentUnlink"), $tmpFile); - } - return $tmpFile; - } - - - public static function isRemote(){ - return true; + $tmpHandle = fopen($tmpFile, "wb"); + self::copyFileInStream($path, $tmpHandle); + fclose($tmpHandle); + if (!$persistent) { + register_shutdown_function(array("AJXP_Utils", "silentUnlink"), $tmpFile); + } + return $tmpFile; + } + + + public static function isRemote() + { + return true; } - - public static function copyFileInStream($path, $stream){ + + public static function copyFileInStream($path, $stream) + { AJXP_Logger::debug("Should load ".$path); - $fp = fopen($path, "r"); - while (!feof($fp)) { - $data = fread($fp, 4096); - fwrite($stream, $data, strlen($data)); - } - fclose($fp); - } - - public static function changeMode($path, $chmodValue){ + $fp = fopen($path, "r"); + while (!feof($fp)) { + $data = fread($fp, 4096); + fwrite($stream, $data, strlen($data)); + } + fclose($fp); + } + + public static function changeMode($path, $chmodValue) + { // DO NOTHING! - //$realPath = self::initPath($path, "file"); - //chmod($realPath, $chmodValue); - } + //$realPath = self::initPath($path, "file"); + //chmod($realPath, $chmodValue); + } } -?> \ No newline at end of file diff --git a/core/src/plugins/access.s3/i18n/conf/en.php b/core/src/plugins/access.s3/i18n/conf/en.php index 112f72a4ec..684de4183a 100755 --- a/core/src/plugins/access.s3/i18n/conf/en.php +++ b/core/src/plugins/access.s3/i18n/conf/en.php @@ -29,4 +29,4 @@ "S3 storage region" => "S3 storage region", "Container" => "Bucket", "Root container in the S3 storage" => "S3 bucket" -); \ No newline at end of file +); diff --git a/core/src/plugins/access.s3/i18n/conf/fr.php b/core/src/plugins/access.s3/i18n/conf/fr.php index 0cf4e3d0db..f0b321dfb0 100755 --- a/core/src/plugins/access.s3/i18n/conf/fr.php +++ b/core/src/plugins/access.s3/i18n/conf/fr.php @@ -29,4 +29,4 @@ "S3 storage region" => "Région du stockage S3", "Container" => "Container", "Root container in the S3 storage" => "Container S3 sans lequel sont stockées les données" -); \ No newline at end of file +); diff --git a/core/src/plugins/access.s3/i18n/conf/pt.php b/core/src/plugins/access.s3/i18n/conf/pt.php index 0702fbf62d..af1ae05c9a 100644 --- a/core/src/plugins/access.s3/i18n/conf/pt.php +++ b/core/src/plugins/access.s3/i18n/conf/pt.php @@ -29,4 +29,4 @@ "S3 storage region" => "Região de Armazenamento S3", "Container" => "Contentor", "Root container in the S3 storage" => "Contentor S3" -); \ No newline at end of file +); diff --git a/core/src/plugins/access.s3/manifest.xml b/core/src/plugins/access.s3/manifest.xml index 9f280faa03..4600844ebc 100755 --- a/core/src/plugins/access.s3/manifest.xml +++ b/core/src/plugins/access.s3/manifest.xml @@ -23,4 +23,4 @@ - \ No newline at end of file + diff --git a/core/src/plugins/access.sftp/class.sftpAccessDriver.php b/core/src/plugins/access.sftp/class.sftpAccessDriver.php index dcb1fe123e..473c9f3223 100644 --- a/core/src/plugins/access.sftp/class.sftpAccessDriver.php +++ b/core/src/plugins/access.sftp/class.sftpAccessDriver.php @@ -1,294 +1,276 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * AJXP_Plugin to access an ftp server over SSH - * @package AjaXplorer_Plugins - * @subpackage Access - */ -class sftpAccessDriver extends fsAccessDriver -{ - /** - * @var Repository - */ - public $repository; - public $driverConf; - protected $wrapperClassName; - protected $urlBase; - - function initRepository(){ - if(is_array($this->pluginConf)){ - $this->driverConf = $this->pluginConf; - }else{ - $this->driverConf = array(); - } - - if(!function_exists('ssh2_connect')){ - throw new Exception("You must have the php ssh2 extension active!"); - } - ConfService::setConf("PROBE_REAL_SIZE", false); - $path = $this->repository->getOption("PATH"); - $recycle = $this->repository->getOption("RECYCLE_BIN"); - $wrapperData = $this->detectStreamWrapper(true); - $this->wrapperClassName = $wrapperData["classname"]; - $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); - restore_error_handler(); - if(!file_exists($this->urlBase)){ - if($this->repository->getOption("CREATE")){ - $test = @mkdir($this->urlBase); - if(!$test){ - throw new AJXP_Exception("Cannot create path ($path) for your repository! Please check the configuration."); - } - }else{ - throw new AJXP_Exception("Cannot find base path ($path) for your repository! Please check the configuration!"); - } - } - if($recycle != ""){ - RecycleBinManager::init($this->urlBase, "/".$recycle); - } - } - - /** - * Parse - * @param DOMNode $contribNode - */ - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($contribNode->nodeName != "actions") return ; - $this->disableArchiveBrowsingContributions($contribNode); - } - - - /** - * We have to override the standard copyOrMoveFile, as feof() does - * not seem to work with ssh2.ftp stream... - * Maybe something to search hear http://www.mail-archive.com/php-general@lists.php.net/msg169992.html? - * - * @param string $destDir - * @param string $srcFile - * @param array $error - * @param array $success - * @param boolean $move - */ - function copyOrMoveFile($destDir, $srcFile, &$error, &$success, $move = false) - { - $mess = ConfService::getMessages(); - $destFile = $this->urlBase.$destDir."/".basename($srcFile); - $realSrcFile = $this->urlBase.$srcFile; - if(!file_exists($realSrcFile)) - { - $error[] = $mess[100].$srcFile; - return ; - } - if(dirname($realSrcFile)==dirname($destFile)) - { - if($move){ - $error[] = $mess[101]; - return ; - }else{ - $base = basename($srcFile); - $i = 1; - if(is_file($realSrcFile)){ - $dotPos = strrpos($base, "."); - if($dotPos>-1){ - $radic = substr($base, 0, $dotPos); - $ext = substr($base, $dotPos); - } - } - // auto rename file - $i = 1; - $newName = $base; - while (file_exists($this->urlBase.$destDir."/".$newName)) { - $suffix = "-$i"; - if(isSet($radic)) $newName = $radic . $suffix . $ext; - else $newName = $base.$suffix; - $i++; - } - $destFile = $this->urlBase.$destDir."/".$newName; - } - } - if(!is_file($realSrcFile)) - { - $errors = array(); - $succFiles = array(); - if($move){ - if(file_exists($destFile)) $this->deldir($destFile); - $res = rename($realSrcFile, $destFile); - }else{ - $dirRes = $this->dircopy($realSrcFile, $destFile, $errors, $succFiles); - } - if(count($errors) || (isSet($res) && $res!==true)) - { - $error[] = $mess[114]; - return ; - } - } - else - { - if($move){ - AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($realSrcFile))); - if(file_exists($destFile)) unlink($destFile); - rename($realSrcFile, $destFile); - AJXP_Controller::applyHook("node.change", array(new AJXP_Node($realSrcFile), new AJXP_Node($destFile), false)); - }else{ - try{ - // BEGIN OVERRIDING - list($connection, $remote_base_path) = sftpAccessWrapper::getSshConnection($realSrcFile); - $remoteSrc = $remote_base_path.$srcFile; - $remoteDest = $remote_base_path.$destDir; - AJXP_Logger::debug("SSH2 CP", array("cmd" => 'cp '.$remoteSrc.' '.$remoteDest)); - ssh2_exec($connection, 'cp '.$remoteSrc.' '.$remoteDest); - AJXP_Controller::applyHook("node.change", array(new AJXP_Node($realSrcFile), new AJXP_Node($destFile), true)); - // END OVERRIDING - }catch (Exception $e){ - $error[] = $e->getMessage(); - return ; - } - } - } - - if($move) - { - // Now delete original - // $this->deldir($realSrcFile); // both file and dir - $messagePart = $mess[74]." ".SystemTextEncoding::toUTF8($destDir); - if(RecycleBinManager::recycleEnabled() && $destDir == RecycleBinManager::getRelativeRecycle()) - { - RecycleBinManager::fileToRecycle($srcFile); - $messagePart = $mess[123]." ".$mess[122]; - } - if(isset($dirRes)) - { - $success[] = $mess[117]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$messagePart." (".SystemTextEncoding::toUTF8($dirRes)." ".$mess[116].") "; - } - else - { - $success[] = $mess[34]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$messagePart; - } - } - else - { - if(RecycleBinManager::recycleEnabled() && $destDir == "/".$this->repository->getOption("RECYCLE_BIN")) - { - RecycleBinManager::fileToRecycle($srcFile); - } - if(isSet($dirRes)) - { - $success[] = $mess[117]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$mess[73]." ".SystemTextEncoding::toUTF8($destDir)." (".SystemTextEncoding::toUTF8($dirRes)." ".$mess[116].")"; - } - else - { - $success[] = $mess[34]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$mess[73]." ".SystemTextEncoding::toUTF8($destDir); - } - } - - } - - function filesystemFileSize($filePath){ - $bytesize = filesize($filePath); - if($bytesize < 0){ - $bytesize = sprintf("%u", $bytesize); - } - return $bytesize; - } - - /** - * @param $src - * @param $dest - * @param $basedir - * @return zipfile - */ - function makeZip ($src, $dest, $basedir) - { - @set_time_limit(60); - require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); - $filePaths = array(); - - $uniqid = uniqid(); - $uniqfolder = '/tmp/ajaxplorer-zip-'.$uniqid; - mkdir($uniqfolder); - - foreach ($src as $item){ - $basedir = trim(dirname($item)); - $basename = basename($item); - $uniqpath = $uniqfolder.'/'.$basename; - $this->full_copy($this->urlBase.$item, $uniqpath); - $filePaths[] = array(PCLZIP_ATT_FILE_NAME => $uniqpath, - PCLZIP_ATT_FILE_NEW_SHORT_NAME => $basename); - } - AJXP_Logger::debug("Pathes", $filePaths); - AJXP_Logger::debug("Basedir", array($basedir)); - $archive = new PclZip($dest); - $vList = $archive->create($filePaths, PCLZIP_OPT_REMOVE_PATH, $uniqfolder, PCLZIP_OPT_NO_COMPRESSION); - $this->recursiveRmdir($uniqfolder); - if(!$vList){ - throw new Exception("Zip creation error : ($dest) ".$archive->errorInfo(true)); - } - return $vList; - } - - function full_copy( $source, $destination ) { - if ( is_dir( $source ) ) { - @mkdir( $destination ); - $directory = dir( $source ); - while ( FALSE !== ( $readdirectory = $directory->read() ) ) { - if ( $readdirectory == '.' || $readdirectory == '..' ) { - continue; - } - $PathDir = $source . '/' . $readdirectory; - if ( is_dir( $PathDir ) ) { - $this->full_copy( $PathDir, $destination . '/' . $readdirectory ); - continue; - } - copy( $PathDir, $destination . '/' . $readdirectory ); - } - - $directory->close(); - }else { - copy( $source, $destination ); - } - } - - function recursiveRmdir($path) - { - if (is_dir($path)) - { - $path = rtrim($path, '/'); - $subdir = dir($path); - while (($file = $subdir->read()) !== false) - { - if ($file != '.' && $file != '..') - { - (!is_link("$path/$file") && is_dir("$path/$file")) ? $this->recursiveRmdir("$path/$file") : unlink("$path/$file"); - } - } - $subdir->close(); - rmdir($path); - return true; - } - return false; - } - -} - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * AJXP_Plugin to access an ftp server over SSH + * @package AjaXplorer_Plugins + * @subpackage Access + */ +class sftpAccessDriver extends fsAccessDriver +{ + /** + * @var Repository + */ + public $repository; + public $driverConf; + protected $wrapperClassName; + protected $urlBase; + + public function initRepository() + { + if (is_array($this->pluginConf)) { + $this->driverConf = $this->pluginConf; + } else { + $this->driverConf = array(); + } + + if (!function_exists('ssh2_connect')) { + throw new Exception("You must have the php ssh2 extension active!"); + } + ConfService::setConf("PROBE_REAL_SIZE", false); + $path = $this->repository->getOption("PATH"); + $recycle = $this->repository->getOption("RECYCLE_BIN"); + $wrapperData = $this->detectStreamWrapper(true); + $this->wrapperClassName = $wrapperData["classname"]; + $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); + restore_error_handler(); + if (!file_exists($this->urlBase)) { + if ($this->repository->getOption("CREATE")) { + $test = @mkdir($this->urlBase); + if (!$test) { + throw new AJXP_Exception("Cannot create path ($path) for your repository! Please check the configuration."); + } + } else { + throw new AJXP_Exception("Cannot find base path ($path) for your repository! Please check the configuration!"); + } + } + if ($recycle != "") { + RecycleBinManager::init($this->urlBase, "/".$recycle); + } + } + + /** + * Parse + * @param DOMNode $contribNode + */ + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if($contribNode->nodeName != "actions") return ; + $this->disableArchiveBrowsingContributions($contribNode); + } + + + /** + * We have to override the standard copyOrMoveFile, as feof() does + * not seem to work with ssh2.ftp stream... + * Maybe something to search hear http://www.mail-archive.com/php-general@lists.php.net/msg169992.html? + * + * @param string $destDir + * @param string $srcFile + * @param array $error + * @param array $success + * @param boolean $move + */ + public function copyOrMoveFile($destDir, $srcFile, &$error, &$success, $move = false) + { + $mess = ConfService::getMessages(); + $destFile = $this->urlBase.$destDir."/".basename($srcFile); + $realSrcFile = $this->urlBase.$srcFile; + if (!file_exists($realSrcFile)) { + $error[] = $mess[100].$srcFile; + return ; + } + if (dirname($realSrcFile)==dirname($destFile)) { + if ($move) { + $error[] = $mess[101]; + return ; + } else { + $base = basename($srcFile); + $i = 1; + if (is_file($realSrcFile)) { + $dotPos = strrpos($base, "."); + if ($dotPos>-1) { + $radic = substr($base, 0, $dotPos); + $ext = substr($base, $dotPos); + } + } + // auto rename file + $i = 1; + $newName = $base; + while (file_exists($this->urlBase.$destDir."/".$newName)) { + $suffix = "-$i"; + if(isSet($radic)) $newName = $radic . $suffix . $ext; + else $newName = $base.$suffix; + $i++; + } + $destFile = $this->urlBase.$destDir."/".$newName; + } + } + if (!is_file($realSrcFile)) { + $errors = array(); + $succFiles = array(); + if ($move) { + if(file_exists($destFile)) $this->deldir($destFile); + $res = rename($realSrcFile, $destFile); + } else { + $dirRes = $this->dircopy($realSrcFile, $destFile, $errors, $succFiles); + } + if (count($errors) || (isSet($res) && $res!==true)) { + $error[] = $mess[114]; + return ; + } + } else { + if ($move) { + AJXP_Controller::applyHook("node.before_path_change", array(new AJXP_Node($realSrcFile))); + if(file_exists($destFile)) unlink($destFile); + rename($realSrcFile, $destFile); + AJXP_Controller::applyHook("node.change", array(new AJXP_Node($realSrcFile), new AJXP_Node($destFile), false)); + } else { + try { + // BEGIN OVERRIDING + list($connection, $remote_base_path) = sftpAccessWrapper::getSshConnection($realSrcFile); + $remoteSrc = $remote_base_path.$srcFile; + $remoteDest = $remote_base_path.$destDir; + AJXP_Logger::debug("SSH2 CP", array("cmd" => 'cp '.$remoteSrc.' '.$remoteDest)); + ssh2_exec($connection, 'cp '.$remoteSrc.' '.$remoteDest); + AJXP_Controller::applyHook("node.change", array(new AJXP_Node($realSrcFile), new AJXP_Node($destFile), true)); + // END OVERRIDING + } catch (Exception $e) { + $error[] = $e->getMessage(); + return ; + } + } + } + + if ($move) { + // Now delete original + // $this->deldir($realSrcFile); // both file and dir + $messagePart = $mess[74]." ".SystemTextEncoding::toUTF8($destDir); + if (RecycleBinManager::recycleEnabled() && $destDir == RecycleBinManager::getRelativeRecycle()) { + RecycleBinManager::fileToRecycle($srcFile); + $messagePart = $mess[123]." ".$mess[122]; + } + if (isset($dirRes)) { + $success[] = $mess[117]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$messagePart." (".SystemTextEncoding::toUTF8($dirRes)." ".$mess[116].") "; + } else { + $success[] = $mess[34]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$messagePart; + } + } else { + if (RecycleBinManager::recycleEnabled() && $destDir == "/".$this->repository->getOption("RECYCLE_BIN")) { + RecycleBinManager::fileToRecycle($srcFile); + } + if (isSet($dirRes)) { + $success[] = $mess[117]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$mess[73]." ".SystemTextEncoding::toUTF8($destDir)." (".SystemTextEncoding::toUTF8($dirRes)." ".$mess[116].")"; + } else { + $success[] = $mess[34]." ".SystemTextEncoding::toUTF8(basename($srcFile))." ".$mess[73]." ".SystemTextEncoding::toUTF8($destDir); + } + } + + } + + public function filesystemFileSize($filePath) + { + $bytesize = filesize($filePath); + if ($bytesize < 0) { + $bytesize = sprintf("%u", $bytesize); + } + return $bytesize; + } + + /** + * @param $src + * @param $dest + * @param $basedir + * @return zipfile + */ + public function makeZip ($src, $dest, $basedir) + { + @set_time_limit(60); + require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); + $filePaths = array(); + + $uniqid = uniqid(); + $uniqfolder = '/tmp/ajaxplorer-zip-'.$uniqid; + mkdir($uniqfolder); + + foreach ($src as $item) { + $basedir = trim(dirname($item)); + $basename = basename($item); + $uniqpath = $uniqfolder.'/'.$basename; + $this->full_copy($this->urlBase.$item, $uniqpath); + $filePaths[] = array(PCLZIP_ATT_FILE_NAME => $uniqpath, + PCLZIP_ATT_FILE_NEW_SHORT_NAME => $basename); + } + AJXP_Logger::debug("Pathes", $filePaths); + AJXP_Logger::debug("Basedir", array($basedir)); + $archive = new PclZip($dest); + $vList = $archive->create($filePaths, PCLZIP_OPT_REMOVE_PATH, $uniqfolder, PCLZIP_OPT_NO_COMPRESSION); + $this->recursiveRmdir($uniqfolder); + if (!$vList) { + throw new Exception("Zip creation error : ($dest) ".$archive->errorInfo(true)); + } + return $vList; + } + + public function full_copy( $source, $destination ) + { + if ( is_dir( $source ) ) { + @mkdir( $destination ); + $directory = dir( $source ); + while ( FALSE !== ( $readdirectory = $directory->read() ) ) { + if ($readdirectory == '.' || $readdirectory == '..') { + continue; + } + $PathDir = $source . '/' . $readdirectory; + if ( is_dir( $PathDir ) ) { + $this->full_copy( $PathDir, $destination . '/' . $readdirectory ); + continue; + } + copy( $PathDir, $destination . '/' . $readdirectory ); + } + + $directory->close(); + } else { + copy( $source, $destination ); + } + } + + public function recursiveRmdir($path) + { + if (is_dir($path)) { + $path = rtrim($path, '/'); + $subdir = dir($path); + while (($file = $subdir->read()) !== false) { + if ($file != '.' && $file != '..') { + (!is_link("$path/$file") && is_dir("$path/$file")) ? $this->recursiveRmdir("$path/$file") : unlink("$path/$file"); + } + } + $subdir->close(); + rmdir($path); + return true; + } + return false; + } + +} diff --git a/core/src/plugins/access.sftp/class.sftpAccessWrapper.php b/core/src/plugins/access.sftp/class.sftpAccessWrapper.php index bcf3bc8573..1a963a8138 100644 --- a/core/src/plugins/access.sftp/class.sftpAccessWrapper.php +++ b/core/src/plugins/access.sftp/class.sftpAccessWrapper.php @@ -31,26 +31,30 @@ * @param String $message * @param String $language */ -function disconnectedSftp($code, $message, $language){ - AJXP_Logger::logAction("SSH2.FTP.disconnected"); - throw new Exception('SSH2.FTP : disconnected'.$message, $code); +function disconnectedSftp($code, $message, $language) +{ + AJXP_Logger::logAction("SSH2.FTP.disconnected"); + throw new Exception('SSH2.FTP : disconnected'.$message, $code); } -function ignoreSftp($message){ - AJXP_Logger::logAction("SSH2.FTP.ignore"); - throw new Exception('SSH2.FTP : ignore'.$message); +function ignoreSftp($message) +{ + AJXP_Logger::logAction("SSH2.FTP.ignore"); + throw new Exception('SSH2.FTP : ignore'.$message); } -function debugSftp($message, $language, $always_display){ - AJXP_Logger::logAction("SSH2.FTP.debug"); - throw new Exception('SSH2.FTP : debug'.$message); +function debugSftp($message, $language, $always_display) +{ + AJXP_Logger::logAction("SSH2.FTP.debug"); + throw new Exception('SSH2.FTP : debug'.$message); } -function macerrorSftp($packet){ - AJXP_Logger::logAction("SSH2.FTP.macerror"); - throw new Exception('SSH2.FTP : macerror'.$packet); +function macerrorSftp($packet) +{ + AJXP_Logger::logAction("SSH2.FTP.macerror"); + throw new Exception('SSH2.FTP : macerror'.$packet); } - + /** @@ -58,70 +62,72 @@ function macerrorSftp($packet){ * @package AjaXplorer_Plugins * @subpackage Access */ -class sftpAccessWrapper extends fsAccessWrapper { +class sftpAccessWrapper extends fsAccessWrapper +{ + public static $sftpResource; - static $sftpResource; - /** - * Initialize the stream from the given path. + * Initialize the stream from the given path. * Concretely, transform ajxp.webdav:// into webdav:// * * @param string $path * @return mixed Real path or -1 if currentListing contains the listing : original path converted to real path */ - protected static function initPath($path, $streamType="", $sftpResource = false, $skipZip = false){ - $url = parse_url($path); - $repoId = $url["host"]; - $repoObject = ConfService::getRepositoryById($repoId); - if(!isSet($repoObject)) throw new Exception("Cannot find repository with id ".$repoId); - $path = $url["path"]; - // MAKE SURE THERE ARE NO // OR PROBLEMS LIKE THAT... - $basePath = $repoObject->getOption("PATH"); - if($basePath[strlen($basePath)-1] == "/"){ - $basePath = substr($basePath, 0, -1); - } - if($basePath[0] != "/"){ - $basePath = "/$basePath"; - } - $path = AJXP_Utils::securePath($path); - if($path[0] == "/"){ - $path = substr($path, 1); - } - // SHOULD RETURN ssh2.sftp://Resource #23/server/path/folder/path - return "ssh2.sftp://".self::getSftpResource($repoObject).$basePath."/".$path; - } - + protected static function initPath($path, $streamType="", $sftpResource = false, $skipZip = false) + { + $url = parse_url($path); + $repoId = $url["host"]; + $repoObject = ConfService::getRepositoryById($repoId); + if(!isSet($repoObject)) throw new Exception("Cannot find repository with id ".$repoId); + $path = $url["path"]; + // MAKE SURE THERE ARE NO // OR PROBLEMS LIKE THAT... + $basePath = $repoObject->getOption("PATH"); + if ($basePath[strlen($basePath)-1] == "/") { + $basePath = substr($basePath, 0, -1); + } + if ($basePath[0] != "/") { + $basePath = "/$basePath"; + } + $path = AJXP_Utils::securePath($path); + if ($path[0] == "/") { + $path = substr($path, 1); + } + // SHOULD RETURN ssh2.sftp://Resource #23/server/path/folder/path + return "ssh2.sftp://".self::getSftpResource($repoObject).$basePath."/".$path; + } + /** * Get ssh2 connection * * @param Repository $repoObject * @return Resource */ - protected static function getSftpResource($repoObject){ - if(isSet(self::$sftpResource)){ - return self::$sftpResource; - } - $callbacks = array('disconnect' => "disconnectedSftp", - 'ignore' => "ignoreSftp", - 'debug' => "debugSftp", - 'macerror' => "macerrorSftp"); - $remote_serv = $repoObject->getOption("SERV"); - $remote_port = $repoObject->getOption("PORT"); - $credentials = AJXP_Safe::tryLoadingCredentialsFromSources(array(), $repoObject); - $remote_user = $credentials["user"]; - $remote_pass = $credentials["password"]; - - $connection = ssh2_connect($remote_serv, intval($remote_port), array(), $callbacks); - ssh2_auth_password($connection, $remote_user, $remote_pass); - self::$sftpResource = ssh2_sftp($connection); - return self::$sftpResource; + protected static function getSftpResource($repoObject) + { + if (isSet(self::$sftpResource)) { + return self::$sftpResource; + } + $callbacks = array('disconnect' => "disconnectedSftp", + 'ignore' => "ignoreSftp", + 'debug' => "debugSftp", + 'macerror' => "macerrorSftp"); + $remote_serv = $repoObject->getOption("SERV"); + $remote_port = $repoObject->getOption("PORT"); + $credentials = AJXP_Safe::tryLoadingCredentialsFromSources(array(), $repoObject); + $remote_user = $credentials["user"]; + $remote_pass = $credentials["password"]; + + $connection = ssh2_connect($remote_serv, intval($remote_port), array(), $callbacks); + ssh2_auth_password($connection, $remote_user, $remote_pass); + self::$sftpResource = ssh2_sftp($connection); + return self::$sftpResource; } - + /** * Opens the stream * Diff with parent class : do not "securePath", as it removes double slash * - * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" + * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" * @param String $mode * @param array $options * @param array $context @@ -129,178 +135,186 @@ protected static function getSftpResource($repoObject){ */ public function stream_open($path, $mode, $options, &$context) { - try{ - $this->realPath = $this->initPath($path); - }catch (Exception $e){ - AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); - return false; - } + try { + $this->realPath = $this->initPath($path); + } catch (Exception $e) { + AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); + return false; + } $this->fp = fopen($this->realPath, $mode, $options); return ($this->fp !== false); } - + /** - * Stats the given path. + * Stats the given path. * * @param string $path * @param mixed $flags * @return array */ - public function url_stat($path, $flags){ - $realPath = self::initPath($path); - $stat = @stat($realPath); - $parts = parse_url($path); - $repoObject = ConfService::getRepositoryById($parts["host"]); + public function url_stat($path, $flags) + { + $realPath = self::initPath($path); + $stat = @stat($realPath); + $parts = parse_url($path); + $repoObject = ConfService::getRepositoryById($parts["host"]); - AbstractAccessDriver::fixPermissions($stat, $repoObject, array($this, "detectRemoteUserId")); + AbstractAccessDriver::fixPermissions($stat, $repoObject, array($this, "detectRemoteUserId")); - return $stat; + return $stat; } - - public function detectRemoteUserId($repository){ - list($connection, $remote_base_path) = self::getSshConnection("/", $repository); - $stream = ssh2_exec($connection, "id"); - if($stream !== false){ - stream_set_blocking($stream, true); - $output = stream_get_contents($stream); - fclose($stream); - - if(trim($output != "")){ - $res = sscanf($output, "uid=%i(%s) gid=%i(%s) groups=%i(%s)"); - preg_match_all("/(\w*)=(\w*)\((\w*)\)/", $output, $matches); - if(count($matches[0]) == 3){ - $uid = $matches[2][0]; - $gid = $matches[2][1]; - /* - $groups = $matches[2][2]; - $uName = $matches[3][0]; - $gName = $matches[3][1]; - $groupsName = $matches[3][2]; - */ - return array($uid, $gid); - } - } - } - return array(null,null); + + public function detectRemoteUserId($repository) + { + list($connection, $remote_base_path) = self::getSshConnection("/", $repository); + $stream = ssh2_exec($connection, "id"); + if ($stream !== false) { + stream_set_blocking($stream, true); + $output = stream_get_contents($stream); + fclose($stream); + + if (trim($output != "")) { + $res = sscanf($output, "uid=%i(%s) gid=%i(%s) groups=%i(%s)"); + preg_match_all("/(\w*)=(\w*)\((\w*)\)/", $output, $matches); + if (count($matches[0]) == 3) { + $uid = $matches[2][0]; + $gid = $matches[2][1]; + /* + $groups = $matches[2][2]; + $uName = $matches[3][0]; + $gName = $matches[3][1]; + $groupsName = $matches[3][2]; + */ + return array($uid, $gid); + } + } + } + return array(null,null); } - + /** * Opens a handle to the dir - * Fix PEAR by being sure it ends up with "/", to avoid + * Fix PEAR by being sure it ends up with "/", to avoid * adding the current dir to the children list. * * @param String $path * @param array $options * @return resource */ - public function dir_opendir ($path , $options ){ - $this->realPath = $this->initPath($path, true); - $this->dH = @opendir($this->realPath); - return $this->dH !== false; - } + public function dir_opendir ($path , $options ) + { + $this->realPath = $this->initPath($path, true); + $this->dH = @opendir($this->realPath); + return $this->dH !== false; + } + + + // DUPBLICATE STATIC FUNCTIONS TO BE SURE + // NOT TO MESS WITH self:: CALLS + /** + * Remove a temporary file + * + * @param String $tmpDir + * @param String $tmpFile + */ + public static function removeTmpFile($tmpDir, $tmpFile) + { + if(is_file($tmpFile)) unlink($tmpFile); + if(is_dir($tmpDir)) rmdir($tmpDir); + } + + /** + * Implementation of AjxpStream + * + * @param String $path + * @return string + */ + public static function getRealFSReference($path, $persistent = false) + { + if ($persistent) { + $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()); + $tmpHandle = fopen($tmpFile, "wb"); + self::copyFileInStream($path, $tmpHandle); + fclose($tmpHandle); + return $tmpFile; + } else { + return self::initPath($path); + } + } + + public static function isRemote() + { + return true; + } - - // DUPBLICATE STATIC FUNCTIONS TO BE SURE - // NOT TO MESS WITH self:: CALLS - /** - * Remove a temporary file - * - * @param String $tmpDir - * @param String $tmpFile - */ - public static function removeTmpFile($tmpDir, $tmpFile){ - if(is_file($tmpFile)) unlink($tmpFile); - if(is_dir($tmpDir)) rmdir($tmpDir); - } + /** + * Override parent function, testing feof() does not seem to work. + * We may have performance problems on big files here. + * + * @param String $path + * @param Stream $stream + */ + public static function copyFileInStream($path, $stream) + { + $src = fopen(self::initPath($path), "rb"); + while ($content = fread($src, 5120)) { + fputs($stream, $content, strlen($content)); + if(strlen($content) == 0) break; + } + fclose($src); + } - /** - * Implementation of AjxpStream - * - * @param String $path - * @return string - */ - public static function getRealFSReference($path, $persistent = false){ - if($persistent){ - $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()); - $tmpHandle = fopen($tmpFile, "wb"); - self::copyFileInStream($path, $tmpHandle); - fclose($tmpHandle); - return $tmpFile; - }else{ - return self::initPath($path); - } - } - public static function isRemote(){ - return true; + public function unlink($path) + { + // Male sur to return true on success. + $this->realPath = $this->initPath($path, "file", false, true); + @unlink($this->realPath); + if (is_file($this->realPath)) { + return false; + } else { + return true; + } + } + + /** + * Specific case for chmod : not supported natively by ssh2.sftp protocole + * we have to recreate an ssh2 connexion. + * + * @param string $path + * @param long $chmodValue + */ + public static function changeMode($path, $chmodValue) + { + $url = parse_url($path); + list($connection, $remote_base_path) = self::getSshConnection($path); + //var_dump('chmod '.decoct($chmodValue).' '.$remote_base_path.$url['path']); + ssh2_exec($connection,'chmod '.decoct($chmodValue).' '.$remote_base_path.$url['path']); } - - /** - * Override parent function, testing feof() does not seem to work. - * We may have performance problems on big files here. - * - * @param String $path - * @param Stream $stream - */ - public static function copyFileInStream($path, $stream){ - - $src = fopen(self::initPath($path), "rb"); - while ($content = fread($src, 5120)) { - fputs($stream, $content, strlen($content)); - if(strlen($content) == 0) break; - } - fclose($src); - } - - - public function unlink($path){ - // Male sur to return true on success. - $this->realPath = $this->initPath($path, "file", false, true); - @unlink($this->realPath); - if(is_file($this->realPath)){ - return false; - }else{ - return true; - } + + public static function getSshConnection($path, $repoObject = null) + { + if ($repoObject != null) { + $url = array(); + } else { + $url = parse_url($path); + $repoId = $url["host"]; + $repoObject = ConfService::getRepositoryById($repoId); + } + $remote_serv = $repoObject->getOption("SERV"); + $remote_port = $repoObject->getOption("PORT"); + $credentials = AJXP_Safe::tryLoadingCredentialsFromSources($url, $repoObject); + $remote_user = $credentials["user"]; + $remote_pass = $credentials["password"]; + $remote_base_path = $repoObject->getOption("PATH"); + + $callbacks = array('disconnect' => "disconnectedSftp", + 'ignore' => "ignoreSftp", + 'debug' => "debugSftp", + 'macerror' => "macerrorSftp"); + $connection = ssh2_connect($remote_serv, intval($remote_port), array(), $callbacks); + ssh2_auth_password($connection, $remote_user, $remote_pass); + return array($connection, $remote_base_path); } - - /** - * Specific case for chmod : not supported natively by ssh2.sftp protocole - * we have to recreate an ssh2 connexion. - * - * @param string $path - * @param long $chmodValue - */ - public static function changeMode($path, $chmodValue){ - $url = parse_url($path); - list($connection, $remote_base_path) = self::getSshConnection($path); - //var_dump('chmod '.decoct($chmodValue).' '.$remote_base_path.$url['path']); - ssh2_exec($connection,'chmod '.decoct($chmodValue).' '.$remote_base_path.$url['path']); - } - - public static function getSshConnection($path, $repoObject = null){ - if($repoObject != null){ - $url = array(); - }else{ - $url = parse_url($path); - $repoId = $url["host"]; - $repoObject = ConfService::getRepositoryById($repoId); - } - $remote_serv = $repoObject->getOption("SERV"); - $remote_port = $repoObject->getOption("PORT"); - $credentials = AJXP_Safe::tryLoadingCredentialsFromSources($url, $repoObject); - $remote_user = $credentials["user"]; - $remote_pass = $credentials["password"]; - $remote_base_path = $repoObject->getOption("PATH"); - - $callbacks = array('disconnect' => "disconnectedSftp", - 'ignore' => "ignoreSftp", - 'debug' => "debugSftp", - 'macerror' => "macerrorSftp"); - $connection = ssh2_connect($remote_serv, intval($remote_port), array(), $callbacks); - ssh2_auth_password($connection, $remote_user, $remote_pass); - return array($connection, $remote_base_path); - } - + } -?> \ No newline at end of file diff --git a/core/src/plugins/access.sftp/i18n/conf/en.php b/core/src/plugins/access.sftp/i18n/conf/en.php index b7414e80cb..d59d864acb 100644 --- a/core/src/plugins/access.sftp/i18n/conf/en.php +++ b/core/src/plugins/access.sftp/i18n/conf/en.php @@ -30,4 +30,3 @@ "Fix Permissions" => "Fix Permissions", "How to handle remote permissions to be used by PHP as local permissions. See manual." => "How to handle remote permissions to be used by PHP as local permissions. See manual.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.sftp/i18n/conf/fr.php b/core/src/plugins/access.sftp/i18n/conf/fr.php index 4a450a481b..26e433707e 100644 --- a/core/src/plugins/access.sftp/i18n/conf/fr.php +++ b/core/src/plugins/access.sftp/i18n/conf/fr.php @@ -30,4 +30,3 @@ "Fix Permissions" => "Correction des permissions", "How to handle remote permissions to be used by PHP as local permissions. See manual." => "Gestion des permissions entre le serveur local et le serveur distant.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.sftp/i18n/conf/pt.php b/core/src/plugins/access.sftp/i18n/conf/pt.php index 682313e43f..ab95c7b20e 100644 --- a/core/src/plugins/access.sftp/i18n/conf/pt.php +++ b/core/src/plugins/access.sftp/i18n/conf/pt.php @@ -30,4 +30,3 @@ "Fix Permissions" => "Corrigir Permissões", "How to handle remote permissions to be used by PHP as local permissions. See manual." => "Como interpretar as permissões no servidor remoto a serem usadas pelo PHP como sendo locais. Leia a documentação para mais informações.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.sftp/manifest.xml b/core/src/plugins/access.sftp/manifest.xml index 57d71e1f79..7efcb8d257 100644 --- a/core/src/plugins/access.sftp/manifest.xml +++ b/core/src/plugins/access.sftp/manifest.xml @@ -29,7 +29,7 @@ - + @@ -37,6 +37,6 @@
    - + diff --git a/core/src/plugins/access.sftp_psl/SFTPPSL_StreamWrapper.php b/core/src/plugins/access.sftp_psl/SFTPPSL_StreamWrapper.php index 7a12584cd9..0a3315cf8e 100644 --- a/core/src/plugins/access.sftp_psl/SFTPPSL_StreamWrapper.php +++ b/core/src/plugins/access.sftp_psl/SFTPPSL_StreamWrapper.php @@ -112,729 +112,719 @@ * @package Net_SFTP_StreamWrapper * @link http://www.php.net/manual/en/class.streamwrapper.php */ -class SFTPPSL_StreamWrapper{ - - /** - * SFTP Object - * - * @var Net_SFTP - * @access private - */ - private $sftp; - - /** - * SFTP Path - * - * @var String - * @access private - */ - private $path; - - /** - * Pointer Offset - * - * @var Integer - * @access private - */ - private $position; - - /** - * Context resource - * - * @var Resource - * @access public - */ - var $context; - - /** - * Mode - * - * SUPPORTED: r, r+, w, w+, a, a+, c, c+ - * NOT SUPPORTED: x, x+ - * - * @var String - * @access private - */ - private $mode; - - /** - * SFTP Connection Instances - * - * Rather than re-create the connection we re-use instances if possible - * - * @var array - * @access private - */ - private static $instances; - - /** - * Directory Listing - * - * @var array - * @access private - */ - private $dir_entries; - - /** - * This method is called in response to closedir() - * - * Closes a directory handle - * - * Alias of stream_close() - * - * @return bool - * @access public - */ - function dir_closedir() - { - $this->stream_close(); - - $this->dir_entries = FALSE; - - return TRUE; - } - - /** - * This method is called in response to opendir() - * - * Opens up a directory handle to be used in subsequent closedir(), readdir(), and rewinddir() calls - * - * NOTES: - * It loads the entire directory contents into memory. - * The only $options is "whether or not to enforce safe_mode (0x04)". Since safe mode was deprecated in 5.3 and removed in 5.4 we are going - * to ignore it - * - * @param String $path - * @param Integer $options - * @return bool - * @access public - */ - function dir_opendir($path, $options) - { - if ( $this->stream_open($path, NULL, NULL, $opened_path) ) { - $this->dir_entries = $this->sftp->nlist($this->path); - return TRUE; - } - else { - return FALSE; - } - } - - /** - * This method is called in response to readdir() - * - * Reads entry from directory - * - * NOTE: In this method, Pointer Offset is an index of the array returned by Net_SFTP::nlist() - * - * @return string - * @access public - */ - function dir_readdir() - { - if ($this->dir_entries === false) { - return FALSE; - } - - if ( isset($this->dir_entries[$this->position]) ) { - $filename = $this->dir_entries[$this->position]; - - $this->position += 1; - - return $filename; - } - else { - return FALSE; - } - } - - /** - * This method is called in response to rewinddir() - * - * Resets the directory pointer to the beginning of the directory - * - * @return bool - * @access public - */ - function dir_rewinddir() - { - $this->position = 0; - - return TRUE; - } - - /** - * Attempts to create the directory specified by the path - * - * Makes a directory - * - * NOTE: Only valid option is STREAM_MKDIR_RECURSIVE ( http://www.php.net/manual/en/function.mkdir.php ) - * - * @param String $path - * @param Integer $mode - * @param Integer $options - * @return bool - * @access public - */ - function mkdir($path, $mode, $options) - { - $connection = $this->stream_open($path, NULL, NULL, $opened_path); - if ($connection === false) { - return FALSE; - } - - if ( $options === STREAM_MKDIR_RECURSIVE ) { - $mkdir = $this->sftp->mkdir($this->path, $mode, true); - } - else { - $mkdir = $this->sftp->mkdir($this->path, $mode, false); - } - - $this->stream_close(); - - return $mkdir; - } - - /** - * Attempts to rename path_from to path_to - * - * Attempts to rename oldname to newname, moving it between directories if necessary. - * If newname exists, it will be overwritten. - * - * @param String $path_from - * @param String $path_to - * @return bool - * @access public - */ - function rename($path_from, $path_to) - { - $path1 = parse_url($path_from); - $path2 = parse_url($path_to); - unset($path1['path'], $path2['path']); - if ($path1 != $path2) { - return FALSE; - } - unset($path1, $path2); - - $connection = $this->stream_open($path_from, NULL, NULL, $opened_path); - if ($connection === false) { - return FALSE; - } - - $path_to = parse_url($path_to, PHP_URL_PATH); - - // "It is an error if there already exists a file with the name specified by newpath." - // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.5 - if (!$this->sftp->rename($this->path, $path_to)) { - if ($this->sftp->stat($path_to)) { - $del = $this->sftp->delete($path_to, true); - $rename = $this->sftp->rename($this->path, $path_to); - - $this->stream_close(); - return $del && $rename; - } - } - - $this->stream_close(); - return TRUE; - } - - /** - * Attempts to remove the directory named by the path - * - * Removes a directory - * - * NOTE: rmdir() does not have a $recursive parameter as mkdir() does ( http://www.php.net/manual/en/streamwrapper.rmdir.php ) - * - * @param String $path - * @param Integer $options - * @return bool - * @access public - */ - function rmdir($path, $options) - { - $connection = $this->stream_open($path, NULL, NULL, $opened_path); - if ($connection === false) { - return FALSE; - } - - $rmdir = $this->sftp->rmdir($this->path); - - $this->stream_close(); - - return $rmdir; - } - - /** - * This method is called in response to stream_select() - * - * Retrieves the underlaying resource - * - * @param Integer $cast_as - * @return resource - * @access public - */ - function stream_cast($cast_as) - { - return $this->sftp->fsock; - } - - /** - * This method is called in response to fclose() - * - * Closes SFTP connection - * - * @return void - * @access public - */ - function stream_close() - { - // We do not really close connections because - // connections are assigned to a class static variable, so the Net_SFTP object will persist - // even after the stream object has been destroyed. But even without that, it's probably - // unnecessary as it'd be garbage collected out anyway. - // http://www.frostjedi.com/phpbb3/viewtopic.php?f=46&t=167493&sid=3161a478bd0bb359f6cefc956d6ac488&start=15#p391181 - - //$this->sftp->disconnect(); - - $this->position = 0; - } - - /** - * This method is called in response to feof() - * - * Tests for end-of-file on a file pointer - * - * @return bool - * @access public - */ - function stream_eof() - { - $filesize = $this->sftp->size($this->path); - - if ($this->position >= $filesize) { - return TRUE; - } else { - return FALSE; - } - } - - /** - * This method is called in response to fflush() - * - * NOTE: Always returns true because Net_SFTP doesn't cache stuff before writing - * - * @return bool - * @access public - */ - function stream_flush() - { - return TRUE; - } - - /** - * Advisory file locking - * - * Not Implemented - * - * @param Integer $operation - * @return Boolean - * @access public - */ - function stream_lock($operation) - { - return FALSE; - } - - /** - * This method is called to set metadata on the stream. It is called when one of the following functions is called on a stream URL: - * - touch() - * - chmod() - * - chown() - * - chgrp() - * - * Changes stream options - * - * @param String $path - * @param Integer $option - * @param mixed $var - * @return bool - * @access public - */ - function stream_metadata($path, $option, $var) - { - $connection = $this->stream_open($path, NULL, NULL, $opened_path); - if ($connection === false) { - return FALSE; - } - - switch ($option) { - case 1: // PHP_STREAM_META_TOUCH - $touch = $this->sftp->touch($this->path, $var[1], $var[0]); - - $this->stream_close(); - return $touch; - - case 2: // PHP_STREAM_META_OWNER_NAME - $this->stream_close(); - return FALSE; - - case 3: // PHP_STREAM_META_OWNER - $chown = $this->sftp->chown($this->path, $var); - - $this->stream_close(); - return $chown; - - case 4: // PHP_STREAM_META_GROUP_NAME - $this->stream_close(); - return FALSE; - - case 5: // PHP_STREAM_META_GROUP - $chgrp = $this->sftp->chgrp($this->path, $var); - - $this->stream_close(); - return $chgrp; - - case 6: // PHP_STREAM_META_ACCESS - $chmod = $this->sftp->chmod($var, $this->path); - - $this->stream_close(); - return $chmod; - - default: - $this->stream_close(); - return FALSE; - } - } - - /** - * This method is called immediately after the wrapper is initialized - * - * Connects to an SFTP server - * - * NOTE: This method is not get called by default for the following functions: - * dir_opendir(), mkdir(), rename(), rmdir(), stream_metadata(), unlink() and url_stat() - * So I implemented a call to stream_open() at the beginning of the functions and stream_close() at the end - * - * The wrapper will also reuse open connections - * - * @param String $path - * @param String $mode - * @param Integer $options - * @param String &$opened_path - * @return bool - * @access public - */ - function stream_open($path, $mode, $options, &$opened_path) - { - $url = parse_url($path); - - $host = $url["host"]; - $port = $url["port"]; - $user = $url["user"]; - $pass = $url["pass"]; - - $this->path = $url["path"]; - - $connection_uuid = md5( $host.$port.$user ); // Generate a unique ID for the current connection - - if ( isset(self::$instances[$connection_uuid]) ) - { - // Get previously established connection - $this->sftp = self::$instances[$connection_uuid]; - } - else - { - //$context = stream_context_get_options($this->context); - - if (!isset($user) || !isset($pass)) { - return FALSE; - } - - // Connection - $sftp = new Net_SFTP($host, isset($port) ? $port : 22); - if (!$sftp->login($user, $pass)) { - return FALSE; - } - - // Store connection instance - self::$instances[$connection_uuid] = $sftp; - - // Get current connection - $this->sftp = $sftp; - } - - $filesize = $this->sftp->size($this->path); - - if (isset($mode)) { - $this->mode = preg_replace('#[bt]$#', '', $mode); - } - else { - $this->mode = 'r'; - } - - switch ($this->mode[0]) { - case 'r': - $this->position = 0; - break; - case 'w': - $this->position = 0; - if ($filesize === FALSE) { - $this->sftp->touch( $this->path ); - } - else { - $this->sftp->truncate( $this->path, 0 ); - } - break; - case 'a': - if ($filesize === FALSE) { - $this->position = 0; - $this->sftp->touch( $this->path ); - } - else { - $this->position = $filesize; - } - break; - case 'c': - $this->position = 0; - if ($filesize === FALSE) { - $this->sftp->touch( $this->path ); - } - break; - - default: - return FALSE; - } - - if ($options == STREAM_USE_PATH) { - $opened_path = $this->sftp->pwd(); - } - - return TRUE; - } - - /** - * This method is called in response to fread() and fgets() - * - * Reads from stream - * - * @param Integer $count - * @return mixed - * @access public - */ - function stream_read($count) - { - switch ($this->mode) { - case 'w': - case 'a': - case 'x': - case 'x+': - case 'c': - return FALSE; - } - - $chunk = $this->sftp->get( $this->path, FALSE, $this->position, $count ); - - $this->position += strlen($chunk); - - return $chunk; - } - - /** - * This method is called in response to fseek() - * - * Seeks to specific location in a stream - * - * @param Integer $offset - * @param Integer $whence = SEEK_SET - * @return bool - * @access public - */ - function stream_seek($offset, $whence) - { - $filesize = $this->sftp->size($this->path); - - switch ($whence) { - case SEEK_SET: +class SFTPPSL_StreamWrapper +{ + /** + * SFTP Object + * + * @var Net_SFTP + * @access private + */ + private $sftp; + + /** + * SFTP Path + * + * @var String + * @access private + */ + private $path; + + /** + * Pointer Offset + * + * @var Integer + * @access private + */ + private $position; + + /** + * Context resource + * + * @var Resource + * @access public + */ + public $context; + + /** + * Mode + * + * SUPPORTED: r, r+, w, w+, a, a+, c, c+ + * NOT SUPPORTED: x, x+ + * + * @var String + * @access private + */ + private $mode; + + /** + * SFTP Connection Instances + * + * Rather than re-create the connection we re-use instances if possible + * + * @var array + * @access private + */ + private static $instances; + + /** + * Directory Listing + * + * @var array + * @access private + */ + private $dir_entries; + + /** + * This method is called in response to closedir() + * + * Closes a directory handle + * + * Alias of stream_close() + * + * @return bool + * @access public + */ + public function dir_closedir() + { + $this->stream_close(); + + $this->dir_entries = FALSE; + + return TRUE; + } + + /** + * This method is called in response to opendir() + * + * Opens up a directory handle to be used in subsequent closedir(), readdir(), and rewinddir() calls + * + * NOTES: + * It loads the entire directory contents into memory. + * The only $options is "whether or not to enforce safe_mode (0x04)". Since safe mode was deprecated in 5.3 and removed in 5.4 we are going + * to ignore it + * + * @param String $path + * @param Integer $options + * @return bool + * @access public + */ + public function dir_opendir($path, $options) + { + if ( $this->stream_open($path, NULL, NULL, $opened_path) ) { + $this->dir_entries = $this->sftp->nlist($this->path); + return TRUE; + } else { + return FALSE; + } + } + + /** + * This method is called in response to readdir() + * + * Reads entry from directory + * + * NOTE: In this method, Pointer Offset is an index of the array returned by Net_SFTP::nlist() + * + * @return string + * @access public + */ + public function dir_readdir() + { + if ($this->dir_entries === false) { + return FALSE; + } + + if ( isset($this->dir_entries[$this->position]) ) { + $filename = $this->dir_entries[$this->position]; + + $this->position += 1; + + return $filename; + } else { + return FALSE; + } + } + + /** + * This method is called in response to rewinddir() + * + * Resets the directory pointer to the beginning of the directory + * + * @return bool + * @access public + */ + public function dir_rewinddir() + { + $this->position = 0; + + return TRUE; + } + + /** + * Attempts to create the directory specified by the path + * + * Makes a directory + * + * NOTE: Only valid option is STREAM_MKDIR_RECURSIVE ( http://www.php.net/manual/en/function.mkdir.php ) + * + * @param String $path + * @param Integer $mode + * @param Integer $options + * @return bool + * @access public + */ + public function mkdir($path, $mode, $options) + { + $connection = $this->stream_open($path, NULL, NULL, $opened_path); + if ($connection === false) { + return FALSE; + } + + if ($options === STREAM_MKDIR_RECURSIVE) { + $mkdir = $this->sftp->mkdir($this->path, $mode, true); + } else { + $mkdir = $this->sftp->mkdir($this->path, $mode, false); + } + + $this->stream_close(); + + return $mkdir; + } + + /** + * Attempts to rename path_from to path_to + * + * Attempts to rename oldname to newname, moving it between directories if necessary. + * If newname exists, it will be overwritten. + * + * @param String $path_from + * @param String $path_to + * @return bool + * @access public + */ + public function rename($path_from, $path_to) + { + $path1 = parse_url($path_from); + $path2 = parse_url($path_to); + unset($path1['path'], $path2['path']); + if ($path1 != $path2) { + return FALSE; + } + unset($path1, $path2); + + $connection = $this->stream_open($path_from, NULL, NULL, $opened_path); + if ($connection === false) { + return FALSE; + } + + $path_to = parse_url($path_to, PHP_URL_PATH); + + // "It is an error if there already exists a file with the name specified by newpath." + // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.5 + if (!$this->sftp->rename($this->path, $path_to)) { + if ($this->sftp->stat($path_to)) { + $del = $this->sftp->delete($path_to, true); + $rename = $this->sftp->rename($this->path, $path_to); + + $this->stream_close(); + return $del && $rename; + } + } + + $this->stream_close(); + return TRUE; + } + + /** + * Attempts to remove the directory named by the path + * + * Removes a directory + * + * NOTE: rmdir() does not have a $recursive parameter as mkdir() does ( http://www.php.net/manual/en/streamwrapper.rmdir.php ) + * + * @param String $path + * @param Integer $options + * @return bool + * @access public + */ + public function rmdir($path, $options) + { + $connection = $this->stream_open($path, NULL, NULL, $opened_path); + if ($connection === false) { + return FALSE; + } + + $rmdir = $this->sftp->rmdir($this->path); + + $this->stream_close(); + + return $rmdir; + } + + /** + * This method is called in response to stream_select() + * + * Retrieves the underlaying resource + * + * @param Integer $cast_as + * @return resource + * @access public + */ + public function stream_cast($cast_as) + { + return $this->sftp->fsock; + } + + /** + * This method is called in response to fclose() + * + * Closes SFTP connection + * + * @return void + * @access public + */ + public function stream_close() + { + // We do not really close connections because + // connections are assigned to a class static variable, so the Net_SFTP object will persist + // even after the stream object has been destroyed. But even without that, it's probably + // unnecessary as it'd be garbage collected out anyway. + // http://www.frostjedi.com/phpbb3/viewtopic.php?f=46&t=167493&sid=3161a478bd0bb359f6cefc956d6ac488&start=15#p391181 + + //$this->sftp->disconnect(); + + $this->position = 0; + } + + /** + * This method is called in response to feof() + * + * Tests for end-of-file on a file pointer + * + * @return bool + * @access public + */ + public function stream_eof() + { + $filesize = $this->sftp->size($this->path); + + if ($this->position >= $filesize) { + return TRUE; + } else { + return FALSE; + } + } + + /** + * This method is called in response to fflush() + * + * NOTE: Always returns true because Net_SFTP doesn't cache stuff before writing + * + * @return bool + * @access public + */ + public function stream_flush() + { + return TRUE; + } + + /** + * Advisory file locking + * + * Not Implemented + * + * @param Integer $operation + * @return Boolean + * @access public + */ + public function stream_lock($operation) + { + return FALSE; + } + + /** + * This method is called to set metadata on the stream. It is called when one of the following functions is called on a stream URL: + * - touch() + * - chmod() + * - chown() + * - chgrp() + * + * Changes stream options + * + * @param String $path + * @param Integer $option + * @param mixed $var + * @return bool + * @access public + */ + public function stream_metadata($path, $option, $var) + { + $connection = $this->stream_open($path, NULL, NULL, $opened_path); + if ($connection === false) { + return FALSE; + } + + switch ($option) { + case 1: // PHP_STREAM_META_TOUCH + $touch = $this->sftp->touch($this->path, $var[1], $var[0]); + + $this->stream_close(); + return $touch; + + case 2: // PHP_STREAM_META_OWNER_NAME + $this->stream_close(); + return FALSE; + + case 3: // PHP_STREAM_META_OWNER + $chown = $this->sftp->chown($this->path, $var); + + $this->stream_close(); + return $chown; + + case 4: // PHP_STREAM_META_GROUP_NAME + $this->stream_close(); + return FALSE; + + case 5: // PHP_STREAM_META_GROUP + $chgrp = $this->sftp->chgrp($this->path, $var); + + $this->stream_close(); + return $chgrp; + + case 6: // PHP_STREAM_META_ACCESS + $chmod = $this->sftp->chmod($var, $this->path); + + $this->stream_close(); + return $chmod; + + default: + $this->stream_close(); + return FALSE; + } + } + + /** + * This method is called immediately after the wrapper is initialized + * + * Connects to an SFTP server + * + * NOTE: This method is not get called by default for the following functions: + * dir_opendir(), mkdir(), rename(), rmdir(), stream_metadata(), unlink() and url_stat() + * So I implemented a call to stream_open() at the beginning of the functions and stream_close() at the end + * + * The wrapper will also reuse open connections + * + * @param String $path + * @param String $mode + * @param Integer $options + * @param String &$opened_path + * @return bool + * @access public + */ + public function stream_open($path, $mode, $options, &$opened_path) + { + $url = parse_url($path); + + $host = $url["host"]; + $port = $url["port"]; + $user = $url["user"]; + $pass = $url["pass"]; + + $this->path = $url["path"]; + + $connection_uuid = md5( $host.$port.$user ); // Generate a unique ID for the current connection + + if ( isset(self::$instances[$connection_uuid]) ) { + // Get previously established connection + $this->sftp = self::$instances[$connection_uuid]; + } else { + //$context = stream_context_get_options($this->context); + + if (!isset($user) || !isset($pass)) { + return FALSE; + } + + // Connection + $sftp = new Net_SFTP($host, isset($port) ? $port : 22); + if (!$sftp->login($user, $pass)) { + return FALSE; + } + + // Store connection instance + self::$instances[$connection_uuid] = $sftp; + + // Get current connection + $this->sftp = $sftp; + } + + $filesize = $this->sftp->size($this->path); + + if (isset($mode)) { + $this->mode = preg_replace('#[bt]$#', '', $mode); + } else { + $this->mode = 'r'; + } + + switch ($this->mode[0]) { + case 'r': + $this->position = 0; + break; + case 'w': + $this->position = 0; + if ($filesize === FALSE) { + $this->sftp->touch( $this->path ); + } else { + $this->sftp->truncate( $this->path, 0 ); + } + break; + case 'a': + if ($filesize === FALSE) { + $this->position = 0; + $this->sftp->touch( $this->path ); + } else { + $this->position = $filesize; + } + break; + case 'c': + $this->position = 0; + if ($filesize === FALSE) { + $this->sftp->touch( $this->path ); + } + break; + + default: + return FALSE; + } + + if ($options == STREAM_USE_PATH) { + $opened_path = $this->sftp->pwd(); + } + + return TRUE; + } + + /** + * This method is called in response to fread() and fgets() + * + * Reads from stream + * + * @param Integer $count + * @return mixed + * @access public + */ + public function stream_read($count) + { + switch ($this->mode) { + case 'w': + case 'a': + case 'x': + case 'x+': + case 'c': + return FALSE; + } + + $chunk = $this->sftp->get( $this->path, FALSE, $this->position, $count ); + + $this->position += strlen($chunk); + + return $chunk; + } + + /** + * This method is called in response to fseek() + * + * Seeks to specific location in a stream + * + * @param Integer $offset + * @param Integer $whence = SEEK_SET + * @return bool + * @access public + */ + public function stream_seek($offset, $whence) + { + $filesize = $this->sftp->size($this->path); + + switch ($whence) { + case SEEK_SET: if ($offset >= $filesize || $offset < 0) { return FALSE; } break; - case SEEK_CUR: - $offset += $this->position; - break; - - case SEEK_END: - $offset += $filesize; - break; - - default: - return FALSE; - } - - $this->position = $offset; - return TRUE; - } - - /** - * This method is called to set options on the stream - * - * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush() isn't. - * The other two aren't supported because of limitations in Net_SFTP. - * - * @param Integer $option - * @param Integer $arg1 - * @param Integer $arg2 - * @return Boolean - * @access public - */ - function stream_set_option($option, $arg1, $arg2) - { - return FALSE; - } - - /** - * This method is called in response to fstat() - * - * Retrieves information about a file resource - * - * @return mixed - * @access public - */ - function stream_stat() - { - $stat = $this->sftp->stat($this->path); - - if( !empty($stat) ) { - // mode fix - $stat['mode'] = $stat['permissions']; - unset($stat['permissions']); - - return $stat; - } else { - return FALSE; - } - } - - /** - * This method is called in response to fseek() to determine the current position - * - * Retrieves the current position of a stream - * - * @return Integer - * @access public - */ - function stream_tell() - { - return $this->position; - } - - /** - * Will respond to truncation, e.g., through ftruncate() - * - * Truncates a stream - * - * NOTE: - * If $new_size is larger than the file then the file is extended with null bytes. - * If $new_size is smaller than the file then the file is truncated to that size. - * - * ( http://www.php.net/manual/en/function.ftruncate.php ) - * - * @param Integer $new_size - * @return bool - * @access public - */ - function stream_truncate($new_size) - { - return $this->sftp->truncate( $this->path, $new_size ); - } - - /** - * This method is called in response to fwrite() - * - * Writes to stream - * - * @param String $data - * @return mixed - * @access public - */ - function stream_write($data) - { - switch ($this->mode) { - case 'r': - case 'x': - case 'x+': - return FALSE; - } - - $this->sftp->put($this->path, $data, NET_SFTP_STRING, $this->position); - - $this->position += strlen($data); - - return strlen($data); - } - - /** - * Deletes filename specified by the path - * - * Deletes a file - * - * @param String $path - * @return bool - * @access public - */ - function unlink($path) - { - $connection = $this->stream_open($path, NULL, NULL, $opened_path); - if ($connection === false) { - return FALSE; - } - - $del = $this->sftp->delete($this->path); - - $this->stream_close(); - - return $del; - } - - /** - * This method is called in response to all stat() related functions - * - * Retrieves information about a file - * - * @see SFTP_StreamWrapper::stream_stat() - * @param String $path - * @param Integer $flags - * @return mixed - * @access public - */ - function url_stat($path, $flags) - { - $connection = $this->stream_open($path, NULL, NULL, $opened_path); - if ($connection === false) { - return FALSE; - } - - if ( $flags === STREAM_URL_STAT_LINK ) { - $stat = $this->sftp->lstat($this->path); - } - else { - $stat = $this->sftp->stat($this->path); - } - - $this->stream_close(); - - if( !empty($stat) ) { - // mode fix - $stat['mode'] = $stat['permissions']; - unset($stat['permissions']); - - return $stat; - } else { - return FALSE; - } - } + case SEEK_CUR: + $offset += $this->position; + break; + + case SEEK_END: + $offset += $filesize; + break; + + default: + return FALSE; + } + + $this->position = $offset; + return TRUE; + } + + /** + * This method is called to set options on the stream + * + * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush() isn't. + * The other two aren't supported because of limitations in Net_SFTP. + * + * @param Integer $option + * @param Integer $arg1 + * @param Integer $arg2 + * @return Boolean + * @access public + */ + public function stream_set_option($option, $arg1, $arg2) + { + return FALSE; + } + + /** + * This method is called in response to fstat() + * + * Retrieves information about a file resource + * + * @return mixed + * @access public + */ + public function stream_stat() + { + $stat = $this->sftp->stat($this->path); + + if ( !empty($stat) ) { + // mode fix + $stat['mode'] = $stat['permissions']; + unset($stat['permissions']); + + return $stat; + } else { + return FALSE; + } + } + + /** + * This method is called in response to fseek() to determine the current position + * + * Retrieves the current position of a stream + * + * @return Integer + * @access public + */ + public function stream_tell() + { + return $this->position; + } + + /** + * Will respond to truncation, e.g., through ftruncate() + * + * Truncates a stream + * + * NOTE: + * If $new_size is larger than the file then the file is extended with null bytes. + * If $new_size is smaller than the file then the file is truncated to that size. + * + * ( http://www.php.net/manual/en/function.ftruncate.php ) + * + * @param Integer $new_size + * @return bool + * @access public + */ + public function stream_truncate($new_size) + { + return $this->sftp->truncate( $this->path, $new_size ); + } + + /** + * This method is called in response to fwrite() + * + * Writes to stream + * + * @param String $data + * @return mixed + * @access public + */ + public function stream_write($data) + { + switch ($this->mode) { + case 'r': + case 'x': + case 'x+': + return FALSE; + } + + $this->sftp->put($this->path, $data, NET_SFTP_STRING, $this->position); + + $this->position += strlen($data); + + return strlen($data); + } + + /** + * Deletes filename specified by the path + * + * Deletes a file + * + * @param String $path + * @return bool + * @access public + */ + public function unlink($path) + { + $connection = $this->stream_open($path, NULL, NULL, $opened_path); + if ($connection === false) { + return FALSE; + } + + $del = $this->sftp->delete($this->path); + + $this->stream_close(); + + return $del; + } + + /** + * This method is called in response to all stat() related functions + * + * Retrieves information about a file + * + * @see SFTP_StreamWrapper::stream_stat() + * @param String $path + * @param Integer $flags + * @return mixed + * @access public + */ + public function url_stat($path, $flags) + { + $connection = $this->stream_open($path, NULL, NULL, $opened_path); + if ($connection === false) { + return FALSE; + } + + if ($flags === STREAM_URL_STAT_LINK) { + $stat = $this->sftp->lstat($this->path); + } else { + $stat = $this->sftp->stat($this->path); + } + + $this->stream_close(); + + if ( !empty($stat) ) { + // mode fix + $stat['mode'] = $stat['permissions']; + unset($stat['permissions']); + + return $stat; + } else { + return FALSE; + } + } } @@ -842,6 +832,4 @@ function url_stat($path, $flags) * Register "sftp://" protocol */ stream_wrapper_register('sftp', 'SFTPPSL_StreamWrapper') - or die ('Failed to register protocol'); - -?> \ No newline at end of file + or die ('Failed to register protocol'); diff --git a/core/src/plugins/access.sftp_psl/class.sftpPSLAccessDriver.php b/core/src/plugins/access.sftp_psl/class.sftpPSLAccessDriver.php index f5133ea383..5416136252 100644 --- a/core/src/plugins/access.sftp_psl/class.sftpPSLAccessDriver.php +++ b/core/src/plugins/access.sftp_psl/class.sftpPSLAccessDriver.php @@ -34,143 +34,143 @@ class sftpPSLAccessDriver extends fsAccessDriver { - /** - * @var Repository - */ - public $repository; - public $driverConf; - protected $wrapperClassName; - protected $urlBase; - - /** - * initRepository - */ - function initRepository() { - if(is_array($this->pluginConf)){ - $this->driverConf = $this->pluginConf; - }else{ - $this->driverConf = array(); - } - - ConfService::setConf("PROBE_REAL_SIZE", false); - - require_once($this->getBaseDir()."/SFTPPSL_StreamWrapper.php"); - - $create = $this->repository->getOption("CREATE"); - $path = $this->repository->getOption("PATH"); - - $wrapperData = $this->detectStreamWrapper(true); - $this->wrapperClassName = $wrapperData["classname"]; - $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); + /** + * @var Repository + */ + public $repository; + public $driverConf; + protected $wrapperClassName; + protected $urlBase; + + /** + * initRepository + */ + public function initRepository() + { + if (is_array($this->pluginConf)) { + $this->driverConf = $this->pluginConf; + } else { + $this->driverConf = array(); + } + + ConfService::setConf("PROBE_REAL_SIZE", false); + + require_once($this->getBaseDir()."/SFTPPSL_StreamWrapper.php"); + + $create = $this->repository->getOption("CREATE"); + $path = $this->repository->getOption("PATH"); + + $wrapperData = $this->detectStreamWrapper(true); + $this->wrapperClassName = $wrapperData["classname"]; + $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); // print "lol"; - } - - function detectStreamWrapper($register = false) { - if($register){ - require_once($this->getBaseDir()."/SFTPPSL_StreamWrapper.php"); - } - return parent::detectStreamWrapper($register); - } - - /** - * Parse - * @param DOMNode $contribNode - */ - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($contribNode->nodeName != "actions") return ; - $this->disableArchiveBrowsingContributions($contribNode); - } - - function filesystemFileSize($filePath){ - $bytesize = filesize($filePath); - if($bytesize < 0){ - $bytesize = sprintf("%u", $bytesize); - } - return $bytesize; - } - - /** - * @param $src - * @param $dest - * @param $basedir - * @return zipfile - */ - function makeZip ($src, $dest, $basedir) - { - @set_time_limit(60); - require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); - $filePaths = array(); - - $uniqid = uniqid(); - $uniqfolder = '/tmp/ajaxplorer-zip-'.$uniqid; - mkdir($uniqfolder); - - foreach ($src as $item){ - $basedir = trim(dirname($item)); - $basename = basename($item); - $uniqpath = $uniqfolder.'/'.$basename; - $this->full_copy($this->urlBase.$item, $uniqpath); - $filePaths[] = array(PCLZIP_ATT_FILE_NAME => $uniqpath, - PCLZIP_ATT_FILE_NEW_SHORT_NAME => $basename); - } - AJXP_Logger::debug("Pathes", $filePaths); - AJXP_Logger::debug("Basedir", array($basedir)); - $archive = new PclZip($dest); - $vList = $archive->create($filePaths, PCLZIP_OPT_REMOVE_PATH, $uniqfolder, PCLZIP_OPT_NO_COMPRESSION); - $this->recursiveRmdir($uniqfolder); - if(!$vList){ - throw new Exception("Zip creation error : ($dest) ".$archive->errorInfo(true)); - } - return $vList; - } - - function full_copy( $source, $destination ) { - if ( is_dir( $source ) ) { - @mkdir( $destination ); - $directory = dir( $source ); - while ( FALSE !== ( $readdirectory = $directory->read() ) ) { - if ( $readdirectory == '.' || $readdirectory == '..' ) { - continue; - } - $PathDir = $source . '/' . $readdirectory; - if ( is_dir( $PathDir ) ) { - $this->full_copy( $PathDir, $destination . '/' . $readdirectory ); - continue; - } - copy( $PathDir, $destination . '/' . $readdirectory ); - } - - $directory->close(); - }else { - copy( $source, $destination ); - } - } - - function recursiveRmdir($path) - { - if (is_dir($path)) - { - $path = rtrim($path, '/'); - $subdir = dir($path); - while (($file = $subdir->read()) !== false) - { - if ($file != '.' && $file != '..') - { - (!is_link("$path/$file") && is_dir("$path/$file")) ? $this->recursiveRmdir("$path/$file") : unlink("$path/$file"); - } - } - $subdir->close(); - rmdir($path); - return true; - } - return false; - } - - function isWriteable($dir, $type="dir") - { - return is_writable($dir); - } + } + + public function detectStreamWrapper($register = false) + { + if ($register) { + require_once($this->getBaseDir()."/SFTPPSL_StreamWrapper.php"); + } + return parent::detectStreamWrapper($register); + } + + /** + * Parse + * @param DOMNode $contribNode + */ + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if($contribNode->nodeName != "actions") return ; + $this->disableArchiveBrowsingContributions($contribNode); + } + + public function filesystemFileSize($filePath) + { + $bytesize = filesize($filePath); + if ($bytesize < 0) { + $bytesize = sprintf("%u", $bytesize); + } + return $bytesize; + } + + /** + * @param $src + * @param $dest + * @param $basedir + * @return zipfile + */ + public function makeZip ($src, $dest, $basedir) + { + @set_time_limit(60); + require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); + $filePaths = array(); + + $uniqid = uniqid(); + $uniqfolder = '/tmp/ajaxplorer-zip-'.$uniqid; + mkdir($uniqfolder); + + foreach ($src as $item) { + $basedir = trim(dirname($item)); + $basename = basename($item); + $uniqpath = $uniqfolder.'/'.$basename; + $this->full_copy($this->urlBase.$item, $uniqpath); + $filePaths[] = array(PCLZIP_ATT_FILE_NAME => $uniqpath, + PCLZIP_ATT_FILE_NEW_SHORT_NAME => $basename); + } + AJXP_Logger::debug("Pathes", $filePaths); + AJXP_Logger::debug("Basedir", array($basedir)); + $archive = new PclZip($dest); + $vList = $archive->create($filePaths, PCLZIP_OPT_REMOVE_PATH, $uniqfolder, PCLZIP_OPT_NO_COMPRESSION); + $this->recursiveRmdir($uniqfolder); + if (!$vList) { + throw new Exception("Zip creation error : ($dest) ".$archive->errorInfo(true)); + } + return $vList; + } + + public function full_copy( $source, $destination ) + { + if ( is_dir( $source ) ) { + @mkdir( $destination ); + $directory = dir( $source ); + while ( FALSE !== ( $readdirectory = $directory->read() ) ) { + if ($readdirectory == '.' || $readdirectory == '..') { + continue; + } + $PathDir = $source . '/' . $readdirectory; + if ( is_dir( $PathDir ) ) { + $this->full_copy( $PathDir, $destination . '/' . $readdirectory ); + continue; + } + copy( $PathDir, $destination . '/' . $readdirectory ); + } + + $directory->close(); + } else { + copy( $source, $destination ); + } + } + + public function recursiveRmdir($path) + { + if (is_dir($path)) { + $path = rtrim($path, '/'); + $subdir = dir($path); + while (($file = $subdir->read()) !== false) { + if ($file != '.' && $file != '..') { + (!is_link("$path/$file") && is_dir("$path/$file")) ? $this->recursiveRmdir("$path/$file") : unlink("$path/$file"); + } + } + $subdir->close(); + rmdir($path); + return true; + } + return false; + } + + public function isWriteable($dir, $type="dir") + { + return is_writable($dir); + } } - -?> \ No newline at end of file diff --git a/core/src/plugins/access.sftp_psl/class.sftpPSLAccessWrapper.php b/core/src/plugins/access.sftp_psl/class.sftpPSLAccessWrapper.php index d53b504fb2..130be3acb5 100644 --- a/core/src/plugins/access.sftp_psl/class.sftpPSLAccessWrapper.php +++ b/core/src/plugins/access.sftp_psl/class.sftpPSLAccessWrapper.php @@ -1,229 +1,237 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ -defined('AJXP_EXEC') or die( 'Access not allowed' ); - -require_once(AJXP_INSTALL_PATH."/plugins/access.fs/class.fsAccessWrapper.php"); -require_once(AJXP_INSTALL_PATH."/plugins/access.sftp_psl/phpseclib/SSH2.php"); - -/** - * AJXP_Plugin to access a remote server using SSH File Transfer Protocol (SFTP) with phpseclib ( http://phpseclib.sourceforge.net/ ) - * - * @author warhawk3407 - * @author Charles du Jeu - * @version Release: 1.0.1 - */ -class sftpPSLAccessWrapper extends fsAccessWrapper -{ - - public static function isRemote(){ - return true; - } - - /** - * Initialize the stream from the given path. - */ - protected static function initPath($path, $streamType = '', $storeOpenContext = false, $skipZip = true){ - $url = parse_url($path); - $repoId = $url["host"]; - $path = $url["path"]; - - $repoObject = ConfService::getRepositoryById($repoId); - - if(!isSet($repoObject)) throw new Exception("Cannot find repository with id ".$repoId); - - $basePath = $repoObject->getOption("PATH"); - $host = $repoObject->getOption("SFTP_HOST"); - $port = $repoObject->getOption("SFTP_PORT"); - - $credentials = AJXP_Safe::tryLoadingCredentialsFromSources($url, $repoObject); - $user = $credentials["user"]; - $pass = $credentials["password"]; - - if($basePath[strlen($basePath)-1] == "/"){ - $basePath = substr($basePath, 0, -1); - } - - if($basePath[0] != "/"){ - $basePath = "/$basePath"; - } - - $path = AJXP_Utils::securePath($path); - - if($path[0] == "/"){ - $path = substr($path, 1); - } - - return "sftp://".$user.':'.$pass.'@'.$host.':'.$port.$basePath."/".$path; // http://username:password@hostname:port/path/file.ext - } - - /** - * Implementation of AjxpStream - * - * @param String $path - * @return string - */ - public static function getRealFSReference($path, $persistent = false){ - if($persistent){ - $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()); - $tmpHandle = fopen($tmpFile, "wb"); - self::copyFileInStream($path, $tmpHandle); - fclose($tmpHandle); - return $tmpFile; - }else{ - return self::initPath($path); - } - } - - /** - * Opens the stream - * Diff with parent class : do not "securePath", as it removes double slash - * - * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" - * @param String $mode - * @param unknown_type $options - * @param unknown_type $opened_path - * @return unknown - */ - public function stream_open($path, $mode, $options, &$context) - { - try{ - $this->realPath = $this->initPath($path); - }catch (Exception $e){ - AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); - return false; - } - if($this->realPath == -1){ - $this->fp = -1; - return true; - }else{ - $this->fp = fopen($this->realPath, $mode, $options); - return ($this->fp !== false); - } - } - - /** - * Opens a handle to the dir - * Fix PEAR by being sure it ends up with "/", to avoid - * adding the current dir to the children list. - * - * @param unknown_type $path - * @param unknown_type $options - * @return unknown - */ - public function dir_opendir ($path , $options ){ - $this->realPath = $this->initPath($path); - if($this->realPath[strlen($this->realPath)-1] != "/"){ - $this->realPath.="/"; - } - if(is_string($this->realPath)){ - $this->dH = opendir($this->realPath); - }else if($this->realPath == -1){ - $this->dH = -1; - } - return $this->dH !== false; - } - - public function unlink($path){ - $this->realPath = $this->initPath($path, "file", false, true); - @unlink($this->realPath); - if(is_file($this->realPath)){ - return false; - }else{ - return true; - } - } - - /** - * Stats the given path. - * - * @param string $path - * @param mixed $flags - * @return array - */ - public function url_stat($path, $flags){ - $realPath = self::initPath($path); - $stat = @stat($realPath); - $parts = parse_url($path); - $repoObject = ConfService::getRepositoryById($parts["host"]); - - AbstractAccessDriver::fixPermissions($stat, $repoObject, array($this, "detectRemoteUserId")); - - return $stat; - } - - public function detectRemoteUserId($repoObject){ - $host = $repoObject->getOption("SFTP_HOST"); - $port = $repoObject->getOption("SFTP_PORT"); - - $credentials = AJXP_Safe::tryLoadingCredentialsFromSources(NULL, $repoObject); - $user = $credentials["user"]; - $pass = $credentials["password"]; - - $ssh2 = new Net_SSH2($host, $port); - if ($ssh2->login($user, $pass)) { - $output = $ssh2->exec( 'id' ); - - if(trim($output != "")){ - $res = sscanf($output, "uid=%i(%s) gid=%i(%s) groups=%i(%s)"); - preg_match_all("/(\w*)=(\w*)\((\w*)\)/", $output, $matches); - if(count($matches[0]) == 3){ - $uid = $matches[2][0]; - $gid = $matches[2][1]; - - return array($uid, $gid); - } - } - - $ssh2->disconnect(); - } - return array(null,null); - } - - /** - * Override parent function. - * We may have performance problems on big files here. - * - * @param String $path - * @param Stream $stream - */ - public static function copyFileInStream($path, $stream){ - - $src = fopen(self::initPath($path), "rb"); - while ($content = fread($src, 5120)) { - fputs($stream, $content, strlen($content)); - if(strlen($content) == 0) break; - } - fclose($src); - } - - /** - * Remove a temporary file - * - * @param String $tmpDir - * @param String $tmpFile - */ - public static function removeTmpFile($tmpDir, $tmpFile){ - if(is_file($tmpFile)) unlink($tmpFile); - if(is_dir($tmpDir)) rmdir($tmpDir); - } - -} + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ +defined('AJXP_EXEC') or die( 'Access not allowed' ); + +require_once(AJXP_INSTALL_PATH."/plugins/access.fs/class.fsAccessWrapper.php"); +require_once(AJXP_INSTALL_PATH."/plugins/access.sftp_psl/phpseclib/SSH2.php"); + +/** + * AJXP_Plugin to access a remote server using SSH File Transfer Protocol (SFTP) with phpseclib ( http://phpseclib.sourceforge.net/ ) + * + * @author warhawk3407 + * @author Charles du Jeu + * @version Release: 1.0.1 + */ +class sftpPSLAccessWrapper extends fsAccessWrapper +{ + + public static function isRemote() + { + return true; + } + + /** + * Initialize the stream from the given path. + */ + protected static function initPath($path, $streamType = '', $storeOpenContext = false, $skipZip = true) + { + $url = parse_url($path); + $repoId = $url["host"]; + $path = $url["path"]; + + $repoObject = ConfService::getRepositoryById($repoId); + + if(!isSet($repoObject)) throw new Exception("Cannot find repository with id ".$repoId); + + $basePath = $repoObject->getOption("PATH"); + $host = $repoObject->getOption("SFTP_HOST"); + $port = $repoObject->getOption("SFTP_PORT"); + + $credentials = AJXP_Safe::tryLoadingCredentialsFromSources($url, $repoObject); + $user = $credentials["user"]; + $pass = $credentials["password"]; + + if ($basePath[strlen($basePath)-1] == "/") { + $basePath = substr($basePath, 0, -1); + } + + if ($basePath[0] != "/") { + $basePath = "/$basePath"; + } + + $path = AJXP_Utils::securePath($path); + + if ($path[0] == "/") { + $path = substr($path, 1); + } + + return "sftp://".$user.':'.$pass.'@'.$host.':'.$port.$basePath."/".$path; // http://username:password@hostname:port/path/file.ext + } + + /** + * Implementation of AjxpStream + * + * @param String $path + * @return string + */ + public static function getRealFSReference($path, $persistent = false) + { + if ($persistent) { + $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()); + $tmpHandle = fopen($tmpFile, "wb"); + self::copyFileInStream($path, $tmpHandle); + fclose($tmpHandle); + return $tmpFile; + } else { + return self::initPath($path); + } + } + + /** + * Opens the stream + * Diff with parent class : do not "securePath", as it removes double slash + * + * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" + * @param String $mode + * @param unknown_type $options + * @param unknown_type $opened_path + * @return unknown + */ + public function stream_open($path, $mode, $options, &$context) + { + try { + $this->realPath = $this->initPath($path); + } catch (Exception $e) { + AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); + return false; + } + if ($this->realPath == -1) { + $this->fp = -1; + return true; + } else { + $this->fp = fopen($this->realPath, $mode, $options); + return ($this->fp !== false); + } + } + + /** + * Opens a handle to the dir + * Fix PEAR by being sure it ends up with "/", to avoid + * adding the current dir to the children list. + * + * @param unknown_type $path + * @param unknown_type $options + * @return unknown + */ + public function dir_opendir ($path , $options ) + { + $this->realPath = $this->initPath($path); + if ($this->realPath[strlen($this->realPath)-1] != "/") { + $this->realPath.="/"; + } + if (is_string($this->realPath)) { + $this->dH = opendir($this->realPath); + } else if ($this->realPath == -1) { + $this->dH = -1; + } + return $this->dH !== false; + } + + public function unlink($path) + { + $this->realPath = $this->initPath($path, "file", false, true); + @unlink($this->realPath); + if (is_file($this->realPath)) { + return false; + } else { + return true; + } + } + + /** + * Stats the given path. + * + * @param string $path + * @param mixed $flags + * @return array + */ + public function url_stat($path, $flags) + { + $realPath = self::initPath($path); + $stat = @stat($realPath); + $parts = parse_url($path); + $repoObject = ConfService::getRepositoryById($parts["host"]); + + AbstractAccessDriver::fixPermissions($stat, $repoObject, array($this, "detectRemoteUserId")); + + return $stat; + } + + public function detectRemoteUserId($repoObject) + { + $host = $repoObject->getOption("SFTP_HOST"); + $port = $repoObject->getOption("SFTP_PORT"); + + $credentials = AJXP_Safe::tryLoadingCredentialsFromSources(NULL, $repoObject); + $user = $credentials["user"]; + $pass = $credentials["password"]; + + $ssh2 = new Net_SSH2($host, $port); + if ($ssh2->login($user, $pass)) { + $output = $ssh2->exec( 'id' ); + + if (trim($output != "")) { + $res = sscanf($output, "uid=%i(%s) gid=%i(%s) groups=%i(%s)"); + preg_match_all("/(\w*)=(\w*)\((\w*)\)/", $output, $matches); + if (count($matches[0]) == 3) { + $uid = $matches[2][0]; + $gid = $matches[2][1]; + + return array($uid, $gid); + } + } + + $ssh2->disconnect(); + } + return array(null,null); + } + + /** + * Override parent function. + * We may have performance problems on big files here. + * + * @param String $path + * @param Stream $stream + */ + public static function copyFileInStream($path, $stream) + { + $src = fopen(self::initPath($path), "rb"); + while ($content = fread($src, 5120)) { + fputs($stream, $content, strlen($content)); + if(strlen($content) == 0) break; + } + fclose($src); + } + + /** + * Remove a temporary file + * + * @param String $tmpDir + * @param String $tmpFile + */ + public static function removeTmpFile($tmpDir, $tmpFile) + { + if(is_file($tmpFile)) unlink($tmpFile); + if(is_dir($tmpDir)) rmdir($tmpDir); + } + +} diff --git a/core/src/plugins/access.sftp_psl/i18n/conf/en.php b/core/src/plugins/access.sftp_psl/i18n/conf/en.php index f9af017916..cc1bc060c5 100644 --- a/core/src/plugins/access.sftp_psl/i18n/conf/en.php +++ b/core/src/plugins/access.sftp_psl/i18n/conf/en.php @@ -1,33 +1,32 @@ - -* This file is part of AjaXplorer. -* -* AjaXplorer is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* AjaXplorer is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with AjaXplorer. If not, see . -* -* The latest code can be found at . -*/ -$mess=array( -"SSH File Transfer Protocol (SFTP)" => "SSH File Transfer Protocol (SFTP)", -"The SSH File Transfer Protocol is a network protocol that provides file access, file transfer, and file management functionalities over SSH2." => "The SSH File Transfer Protocol is a network protocol that provides file access, file transfer, and file management functionalities over SSH2.", -"Host" => "Host", -"SFTP Host to connect to" => "SFTP Host to connect to", -"Port" => "Port", -"SFTP Host port" => "SFTP Host port", -"Path" => "Path", -"Real path to the root folder on the server" => "Real path to the root folder on the server", -"Fix Permissions" => "Fix Permissions", -"How to handle remote permissions to be used by PHP as local permissions. See manual." => "How to handle remote permissions to be used by PHP as local permissions. See manual." -); -?> \ No newline at end of file + +* This file is part of AjaXplorer. +* +* AjaXplorer is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* AjaXplorer is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with AjaXplorer. If not, see . +* +* The latest code can be found at . +*/ +$mess=array( +"SSH File Transfer Protocol (SFTP)" => "SSH File Transfer Protocol (SFTP)", +"The SSH File Transfer Protocol is a network protocol that provides file access, file transfer, and file management functionalities over SSH2." => "The SSH File Transfer Protocol is a network protocol that provides file access, file transfer, and file management functionalities over SSH2.", +"Host" => "Host", +"SFTP Host to connect to" => "SFTP Host to connect to", +"Port" => "Port", +"SFTP Host port" => "SFTP Host port", +"Path" => "Path", +"Real path to the root folder on the server" => "Real path to the root folder on the server", +"Fix Permissions" => "Fix Permissions", +"How to handle remote permissions to be used by PHP as local permissions. See manual." => "How to handle remote permissions to be used by PHP as local permissions. See manual." +); diff --git a/core/src/plugins/access.sftp_psl/i18n/conf/fr.php b/core/src/plugins/access.sftp_psl/i18n/conf/fr.php index 8594b976d0..eb3ac3b4bb 100644 --- a/core/src/plugins/access.sftp_psl/i18n/conf/fr.php +++ b/core/src/plugins/access.sftp_psl/i18n/conf/fr.php @@ -1,33 +1,32 @@ - -* This file is part of AjaXplorer. -* -* AjaXplorer is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* AjaXplorer is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with AjaXplorer. If not, see . -* -* The latest code can be found at . -*/ -$mess=array( -"SSH File Transfer Protocol (SFTP)" => "SSH File Transfer Protocol (SFTP)", -"The SSH File Transfer Protocol is a network protocol that provides file access, file transfer, and file management functionalities over SSH2." => "SFTP est un protocole de communication fonctionnant au-dessus du protocole SSH (SSH2) pour transférer et gérer des fichiers à distance.", -"Host" => "Host", -"SFTP Host to connect to" => "Le nom d'Hôte SFTP", -"Port" => "Port", -"SFTP Host port" => "Port de l'Hôte SFTP", -"Path" => "Path", -"Real path to the root folder on the server" => "Real path to the root folder on the server", -"Fix Permissions" => "Correction des permissions", -"How to handle remote permissions to be used by PHP as local permissions. See manual." => "Gestion des permissions entre le serveur local et le serveur distant." -); -?> \ No newline at end of file + +* This file is part of AjaXplorer. +* +* AjaXplorer is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* AjaXplorer is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with AjaXplorer. If not, see . +* +* The latest code can be found at . +*/ +$mess=array( +"SSH File Transfer Protocol (SFTP)" => "SSH File Transfer Protocol (SFTP)", +"The SSH File Transfer Protocol is a network protocol that provides file access, file transfer, and file management functionalities over SSH2." => "SFTP est un protocole de communication fonctionnant au-dessus du protocole SSH (SSH2) pour transférer et gérer des fichiers à distance.", +"Host" => "Host", +"SFTP Host to connect to" => "Le nom d'Hôte SFTP", +"Port" => "Port", +"SFTP Host port" => "Port de l'Hôte SFTP", +"Path" => "Path", +"Real path to the root folder on the server" => "Real path to the root folder on the server", +"Fix Permissions" => "Correction des permissions", +"How to handle remote permissions to be used by PHP as local permissions. See manual." => "Gestion des permissions entre le serveur local et le serveur distant." +); diff --git a/core/src/plugins/access.sftp_psl/manifest.xml b/core/src/plugins/access.sftp_psl/manifest.xml index 5a27ac8323..21a8e2bfc6 100644 --- a/core/src/plugins/access.sftp_psl/manifest.xml +++ b/core/src/plugins/access.sftp_psl/manifest.xml @@ -1,65 +1,65 @@ - - - - - - Rou Nik - http://ajaxplorer.info/plugins/access/sftp_psl - 0.8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + Rou Nik + http://ajaxplorer.info/plugins/access/sftp_psl + 0.8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/src/plugins/access.smb/class.smbAccessDriver.php b/core/src/plugins/access.smb/class.smbAccessDriver.php index 596e3a80b3..af26a8f281 100644 --- a/core/src/plugins/access.smb/class.smbAccessDriver.php +++ b/core/src/plugins/access.smb/class.smbAccessDriver.php @@ -1,118 +1,119 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * AJXP_Plugin to access a samba server - * @package AjaXplorer_Plugins - * @subpackage Access - */ -class smbAccessDriver extends fsAccessDriver -{ - /** - * @var Repository - */ - public $repository; - public $driverConf; - protected $wrapperClassName; - protected $urlBase; - - function initRepository(){ - - if(is_array($this->pluginConf)){ - $this->driverConf = $this->pluginConf; - }else{ - $this->driverConf = array(); - } - $smbclientPath = $this->driverConf["SMBCLIENT"]; - define ('SMB4PHP_SMBCLIENT', $smbclientPath); - - require_once($this->getBaseDir()."/smb.php"); - - - $create = $this->repository->getOption("CREATE"); - $recycle = $this->repository->getOption("RECYCLE_BIN"); - - $wrapperData = $this->detectStreamWrapper(true); - $this->wrapperClassName = $wrapperData["classname"]; - $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); - } - - function detectStreamWrapper($register = false){ - if($register){ - require_once($this->getBaseDir()."/smb.php"); - } - return parent::detectStreamWrapper($register); - } - - /** - * Parse - * @param DOMNode $contribNode - */ - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($contribNode->nodeName != "actions" || (isSet($this->pluginConf["SMB_ENABLE_ZIP"]) && $this->pluginConf["SMB_ENABLE_ZIP"] == true)) { - return ; - } - $this->disableArchiveBrowsingContributions($contribNode); - } - - function makeZip ($src, $dest, $basedir) - { - @set_time_limit(0); - require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); - $filePaths = array(); - foreach ($src as $item){ - $realFile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $this->urlBase.(($item[0] == "/")? "" : "/").AJXP_Utils::securePath($item)); - $basedir = trim(dirname($realFile))."/"; - $filePaths[] = array(PCLZIP_ATT_FILE_NAME => $realFile, - PCLZIP_ATT_FILE_NEW_SHORT_NAME => basename($item)); - } - AJXP_Logger::debug("Pathes", $filePaths); - AJXP_Logger::debug("Basedir", array($basedir)); - self::$filteringDriverInstance = $this; - $archive = new PclZip($dest); - $vList = $archive->create($filePaths, PCLZIP_OPT_REMOVE_PATH, $basedir, PCLZIP_OPT_NO_COMPRESSION, PCLZIP_OPT_ADD_TEMP_FILE_ON); - if(!$vList){ - throw new Exception("Zip creation error : ($dest) ".$archive->errorInfo(true)); - } - self::$filteringDriverInstance = null; - return $vList; - } - - function filesystemFileSize($filePath){ - $bytesize = filesize($filePath); - if($bytesize < 0){ - $bytesize = sprintf("%u", $bytesize); - } - return $bytesize; - } - - public function isWriteable($dir, $type="dir") - { - if(substr_count($dir, '/') == 3 && $dir[strlen($dir) - 1] == '/') $rc = true; - else $rc = is_writable($dir); - return $rc; - } -} - -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * AJXP_Plugin to access a samba server + * @package AjaXplorer_Plugins + * @subpackage Access + */ +class smbAccessDriver extends fsAccessDriver +{ + /** + * @var Repository + */ + public $repository; + public $driverConf; + protected $wrapperClassName; + protected $urlBase; + + public function initRepository() + { + if (is_array($this->pluginConf)) { + $this->driverConf = $this->pluginConf; + } else { + $this->driverConf = array(); + } + $smbclientPath = $this->driverConf["SMBCLIENT"]; + define ('SMB4PHP_SMBCLIENT', $smbclientPath); + + require_once($this->getBaseDir()."/smb.php"); + + + $create = $this->repository->getOption("CREATE"); + $recycle = $this->repository->getOption("RECYCLE_BIN"); + + $wrapperData = $this->detectStreamWrapper(true); + $this->wrapperClassName = $wrapperData["classname"]; + $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); + } + + public function detectStreamWrapper($register = false) + { + if ($register) { + require_once($this->getBaseDir()."/smb.php"); + } + return parent::detectStreamWrapper($register); + } + + /** + * Parse + * @param DOMNode $contribNode + */ + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if ($contribNode->nodeName != "actions" || (isSet($this->pluginConf["SMB_ENABLE_ZIP"]) && $this->pluginConf["SMB_ENABLE_ZIP"] == true)) { + return ; + } + $this->disableArchiveBrowsingContributions($contribNode); + } + + public function makeZip ($src, $dest, $basedir) + { + @set_time_limit(0); + require_once(AJXP_BIN_FOLDER."/pclzip.lib.php"); + $filePaths = array(); + foreach ($src as $item) { + $realFile = call_user_func(array($this->wrapperClassName, "getRealFSReference"), $this->urlBase.(($item[0] == "/")? "" : "/").AJXP_Utils::securePath($item)); + $basedir = trim(dirname($realFile))."/"; + $filePaths[] = array(PCLZIP_ATT_FILE_NAME => $realFile, + PCLZIP_ATT_FILE_NEW_SHORT_NAME => basename($item)); + } + AJXP_Logger::debug("Pathes", $filePaths); + AJXP_Logger::debug("Basedir", array($basedir)); + self::$filteringDriverInstance = $this; + $archive = new PclZip($dest); + $vList = $archive->create($filePaths, PCLZIP_OPT_REMOVE_PATH, $basedir, PCLZIP_OPT_NO_COMPRESSION, PCLZIP_OPT_ADD_TEMP_FILE_ON); + if (!$vList) { + throw new Exception("Zip creation error : ($dest) ".$archive->errorInfo(true)); + } + self::$filteringDriverInstance = null; + return $vList; + } + + public function filesystemFileSize($filePath) + { + $bytesize = filesize($filePath); + if ($bytesize < 0) { + $bytesize = sprintf("%u", $bytesize); + } + return $bytesize; + } + + public function isWriteable($dir, $type="dir") + { + if(substr_count($dir, '/') == 3 && $dir[strlen($dir) - 1] == '/') $rc = true; + else $rc = is_writable($dir); + return $rc; + } +} diff --git a/core/src/plugins/access.smb/class.smbAccessWrapper.php b/core/src/plugins/access.smb/class.smbAccessWrapper.php index d3cd3c49a8..dd2da83597 100644 --- a/core/src/plugins/access.smb/class.smbAccessWrapper.php +++ b/core/src/plugins/access.smb/class.smbAccessWrapper.php @@ -28,50 +28,51 @@ * @package AjaXplorer_Plugins * @subpackage Access */ -class smbAccessWrapper extends fsAccessWrapper { - +class smbAccessWrapper extends fsAccessWrapper +{ /** - * Initialize the stream from the given path. + * Initialize the stream from the given path. * Concretely, transform ajxp.smb:// into smb:// * * @param string $path * @return mixed Real path or -1 if currentListing contains the listing : original path converted to real path */ - protected static function initPath($path, $streamType, $storeOpenContext = false, $skipZip = false){ - $url = parse_url($path); - $repoId = $url["host"]; - $repoObject = ConfService::getRepositoryById($repoId); - if(!isSet($repoObject)) throw new Exception("Cannot find repository with id ".$repoId); - $path = $url["path"]; - // Fix if the host is defined as //MY_HOST/path/to/folder - $host = str_replace("//", "", $repoObject->getOption("HOST")); - $credentials = ""; - $safeCreds = AJXP_Safe::tryLoadingCredentialsFromSources($url, $repoObject); - if($safeCreds["user"] != "" && $safeCreds["password"] != ""){ - $login = $safeCreds["user"]; - $pass = $safeCreds["password"]; - $_SESSION["AJXP_SESSION_REMOTE_PASS"] = $pass; - $credentials = "$login:$pass@"; - $domain = $repoObject->getOption("DOMAIN"); - if($domain != "") $credentials = $domain."/".$credentials; - } - $basePath = $repoObject->getOption("PATH"); - $fullPath = "smb://".$credentials.$host."/";//.$basePath."/".$path; - if ($basePath!="") { + protected static function initPath($path, $streamType, $storeOpenContext = false, $skipZip = false) + { + $url = parse_url($path); + $repoId = $url["host"]; + $repoObject = ConfService::getRepositoryById($repoId); + if(!isSet($repoObject)) throw new Exception("Cannot find repository with id ".$repoId); + $path = $url["path"]; + // Fix if the host is defined as //MY_HOST/path/to/folder + $host = str_replace("//", "", $repoObject->getOption("HOST")); + $credentials = ""; + $safeCreds = AJXP_Safe::tryLoadingCredentialsFromSources($url, $repoObject); + if ($safeCreds["user"] != "" && $safeCreds["password"] != "") { + $login = $safeCreds["user"]; + $pass = $safeCreds["password"]; + $_SESSION["AJXP_SESSION_REMOTE_PASS"] = $pass; + $credentials = "$login:$pass@"; + $domain = $repoObject->getOption("DOMAIN"); + if($domain != "") $credentials = $domain."/".$credentials; + } + $basePath = $repoObject->getOption("PATH"); + $fullPath = "smb://".$credentials.$host."/";//.$basePath."/".$path; + if ($basePath!="") { $fullPath.=trim($basePath, "/\\" ); - } - if ($path!="") { + } + if ($path!="") { $fullPath.= (($path[0] == "/")? "" : "/").$path; - } - - return $fullPath; - } - + } + + return $fullPath; + } + /** * Opens the stream * Diff with parent class : do not "securePath", as it removes double slash * - * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" + * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" * @param String $mode * @param unknown_type $options * @param unknown_type $opened_path @@ -79,92 +80,98 @@ protected static function initPath($path, $streamType, $storeOpenContext = false */ public function stream_open($path, $mode, $options, &$context) { - try{ - $this->realPath = $this->initPath($path, "file"); - }catch (Exception $e){ - AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); - return false; - } - if($this->realPath == -1){ - $this->fp = -1; - return true; - }else{ - $this->fp = fopen($this->realPath, $mode, $options); - //AJXP_Logger::debug("I opened an smb stream."); - return ($this->fp !== false); - } + try { + $this->realPath = $this->initPath($path, "file"); + } catch (Exception $e) { + AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); + return false; + } + if ($this->realPath == -1) { + $this->fp = -1; + return true; + } else { + $this->fp = fopen($this->realPath, $mode, $options); + //AJXP_Logger::debug("I opened an smb stream."); + return ($this->fp !== false); + } } - + /** * Opens a handle to the dir - * Fix PEAR by being sure it ends up with "/", to avoid + * Fix PEAR by being sure it ends up with "/", to avoid * adding the current dir to the children list. * * @param unknown_type $path * @param unknown_type $options * @return unknown */ - public function dir_opendir ($path , $options ){ - $this->realPath = $this->initPath($path, "dir", true); - if($this->realPath[strlen($this->realPath)-1] != "/"){ - $this->realPath.="/"; - } - if(is_string($this->realPath)){ - $this->dH = opendir($this->realPath); - }else if($this->realPath == -1){ - $this->dH = -1; - } - return $this->dH !== false; - } + public function dir_opendir ($path , $options ) + { + $this->realPath = $this->initPath($path, "dir", true); + if ($this->realPath[strlen($this->realPath)-1] != "/") { + $this->realPath.="/"; + } + if (is_string($this->realPath)) { + $this->dH = opendir($this->realPath); + } else if ($this->realPath == -1) { + $this->dH = -1; + } + return $this->dH !== false; + } + + + // DUPBLICATE STATIC FUNCTIONS TO BE SURE + // NOT TO MESS WITH self:: CALLS + + public static function removeTmpFile($tmpDir, $tmpFile) + { + if(is_file($tmpFile)) unlink($tmpFile); + if(is_dir($tmpDir)) rmdir($tmpDir); + } - - // DUPBLICATE STATIC FUNCTIONS TO BE SURE - // NOT TO MESS WITH self:: CALLS - - public static function removeTmpFile($tmpDir, $tmpFile){ - if(is_file($tmpFile)) unlink($tmpFile); - if(is_dir($tmpDir)) rmdir($tmpDir); - } + protected static function closeWrapper() + { + if (self::$crtZip != null) { + self::$crtZip = null; + self::$currentListing = null; + self::$currentListingKeys = null; + self::$currentListingIndex = null; + self::$currentFileKey = null; + } + } - protected static function closeWrapper(){ - if(self::$crtZip != null) { - self::$crtZip = null; - self::$currentListing = null; - self::$currentListingKeys = null; - self::$currentListingIndex = null; - self::$currentFileKey = null; - } - } + public static function getRealFSReference($path, $persistent = false) + { + if ($persistent) { + $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()); + $tmpHandle = fopen($tmpFile, "wb"); + self::copyFileInStream($path, $tmpHandle); + fclose($tmpHandle); + return $tmpFile; + } else { + $realPath = self::initPath($path, "file"); + return $realPath; + } + } - public static function getRealFSReference($path, $persistent = false){ - if($persistent){ - $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()); - $tmpHandle = fopen($tmpFile, "wb"); - self::copyFileInStream($path, $tmpHandle); - fclose($tmpHandle); - return $tmpFile; - }else{ - $realPath = self::initPath($path, "file"); - return $realPath; - } - } + public static function isRemote() + { + return true; + } - public static function isRemote(){ - return true; + public static function copyFileInStream($path, $stream) + { + $fp = fopen(self::getRealFSReference($path), "rb"); + while (!feof($fp)) { + $data = fread($fp, 4096); + fwrite($stream, $data, strlen($data)); + } + fclose($fp); } - - public static function copyFileInStream($path, $stream){ - $fp = fopen(self::getRealFSReference($path), "rb"); - while (!feof($fp)) { - $data = fread($fp, 4096); - fwrite($stream, $data, strlen($data)); - } - fclose($fp); - } - public static function changeMode($path, $chmodValue){ - //$realPath = self::initPath($path, "file"); - //chmod($realPath, $chmodValue); - } + public static function changeMode($path, $chmodValue) + { + //$realPath = self::initPath($path, "file"); + //chmod($realPath, $chmodValue); + } } -?> diff --git a/core/src/plugins/access.smb/i18n/conf/en.php b/core/src/plugins/access.smb/i18n/conf/en.php index b7762042ce..95e996226d 100644 --- a/core/src/plugins/access.smb/i18n/conf/en.php +++ b/core/src/plugins/access.smb/i18n/conf/en.php @@ -28,4 +28,3 @@ "File Creation Mask" => "File Creation Mask", "Optionnaly apply a chmod operation. Value must be numeric, like 0777, 0644, etc." => "Optionnaly apply a chmod operation. Value must be numeric, like 0777, 0644, etc.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.smb/i18n/conf/fr.php b/core/src/plugins/access.smb/i18n/conf/fr.php index 5f3023be83..fb0bda1601 100644 --- a/core/src/plugins/access.smb/i18n/conf/fr.php +++ b/core/src/plugins/access.smb/i18n/conf/fr.php @@ -28,4 +28,3 @@ "File Creation Mask" => "File Creation Mask", "Optionnaly apply a chmod operation. Value must be numeric, like 0777, 0644, etc." => "Optionnaly apply a chmod operation. Value must be numeric, like 0777, 0644, etc.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.smb/i18n/conf/pt.php b/core/src/plugins/access.smb/i18n/conf/pt.php index 605356d4ec..f858b6bfbe 100644 --- a/core/src/plugins/access.smb/i18n/conf/pt.php +++ b/core/src/plugins/access.smb/i18n/conf/pt.php @@ -28,4 +28,3 @@ "File Creation Mask" => "Máscara de Criação do Ficheiro", "Optionnaly apply a chmod operation. Value must be numeric, like 0777, 0644, etc." => "Opcionalmente aplicar um chmod para corrigir permissões. Os valores devem ser numéricos, do género: 0777, 0644, etc.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.smb/smb.php b/core/src/plugins/access.smb/smb.php index c8fa9dd907..c4f1761c64 100644 --- a/core/src/plugins/access.smb/smb.php +++ b/core/src/plugins/access.smb/smb.php @@ -13,12 +13,12 @@ # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# ################################################################### define ('SMB4PHP_VERSION', '0.8'); @@ -26,7 +26,7 @@ ################################################################### # CONFIGURATION SECTION - Change for your needs ################################################################### -if(!defined('SMB4PHP_SMBCLIENT')){ +if (!defined('SMB4PHP_SMBCLIENT')) { define ('SMB4PHP_SMBCLIENT', 'smbclient'); } define ('SMB4PHP_SMBOPTIONS', 'TCP_NODELAY IPTOS_LOWDELAY SO_KEEPALIVE SO_RCVBUF=8192 SO_SNDBUF=8192'); @@ -42,10 +42,11 @@ * @package AjaXplorer_Plugins * @subpackage Access */ -class smb { - - function parse_url ($url) { - $pu = smb::smbparseUrl(trim($url)); +class smb +{ + public function parse_url ($url) + { + $pu = smb::smbparseUrl(trim($url)); //self::debug("URL: " . print_r($pu,true)); foreach (array ('domain', 'user', 'pass', 'host', 'port', 'path') as $i) { if (! isset($pu[$i])) $pu[$i] = ''; @@ -62,36 +63,37 @@ function parse_url ($url) { /* $i = 0; $atcount = 0; //self::debug("COUNT: " . strlen($pu['host'])); while ($i < strlen($pu['host'])) { - if($pu['host'][$i] == '@'){$atcount++;} - $i++; - } - //self::debug("ATCOUNT: " . $atcount); - if($atcount > 0){ - while($pu['host'][$i] != '@'){$i--; continue;} - $pu['pass'] = $pu['pass'] . '@' . substr($pu['host'], 0, $i); - $pu['host'] = substr($pu['host'], $i + 1); - - } - - */ - //self::debug("PU: " . print_r($pu, true)); - //self::debug("HOST: " . $pu['host']); + if ($pu['host'][$i] == '@') {$atcount++;} + $i++; + } + //self::debug("ATCOUNT: " . $atcount); + if ($atcount > 0) { + while ($pu['host'][$i] != '@') {$i--; continue;} + $pu['pass'] = $pu['pass'] . '@' . substr($pu['host'], 0, $i); + $pu['host'] = substr($pu['host'], $i + 1); + + } + + */ + //self::debug("PU: " . print_r($pu, true)); + //self::debug("HOST: " . $pu['host']); return $pu; } - static function debug($str, $array = null){ + public static function debug($str, $array = null) + { if(!AJXP_SERVER_DEBUG) return; // blur credentials! $pos1 = strpos($str, "://"); - if($pos1 !== false) { + if ($pos1 !== false) { $pos1 += 3; $pos2 = strrpos($str, "@", $pos1) + 1; $str = substr($str, 0, $pos1) . "***:***@" . substr($str, $pos2); } - if($array != null){ + if ($array != null) { if(!is_array($array)) $array = array($array); - foreach($array as $k=>$v){ - if(is_string($v) && strpos($v, "://") != false){ + foreach ($array as $k=>$v) { + if (is_string($v) && strpos($v, "://") != false) { $pos1 = strpos($v, "://") + 3; $pos2 = strrpos($v, "@", $pos1) + 1; $array[$k] = substr($v, 0, $pos1) . "***:***@" . substr($v, $pos2); @@ -102,22 +104,24 @@ static function debug($str, $array = null){ } - function look ($purl) { + public function look ($purl) + { return smb::client ('-L ' . escapeshellarg ($purl['host']), $purl); } - function execute ($command, $purl) { + public function execute ($command, $purl) + { return smb::client ('-d 0 ' . escapeshellarg ('//' . $purl['host'] . '/' . $purl['share']) . ' -c ' . escapeshellarg ($command), $purl ); } - function client ($params, $purl) { + public function client ($params, $purl) + { + //var_dump($params); - //var_dump($params); - static $regexp = array ( '^added interface ip=(.*) bcast=(.*) nmask=(.*)$' => 'skip', 'Anonymous login successful' => 'skip', @@ -154,7 +158,7 @@ function client ($params, $purl) { putenv("USER={$purl['user']}%{$purl['pass']}"); $auth = ''; } else { - //$purl['pass'] = preg_replace('/@/', '\@', $purl['pass']); + //$purl['pass'] = preg_replace('/@/', '\@', $purl['pass']); $auth = ($purl['user'] <> '' ? (' -U ' . escapeshellarg ($purl['user'] . '__SEP__' . $purl['pass'])) : ''); $auth = str_replace("__SEP__", "%", $auth); //self::debug($auth); @@ -166,7 +170,7 @@ function client ($params, $purl) { $options = '-O ' . escapeshellarg(SMB4PHP_SMBOPTIONS); //self::debug($auth); self::debug("SMBCLIENT", " -N {$options} {$port} {$options} {$params} 2>/dev/null [auth data]"); - //self::debug("I just ran an smbclient call"); + //self::debug("I just ran an smbclient call"); //$output = popen (SMB4PHP_SMBCLIENT." -N {$options} {$port} {$options} {$params} 2>/dev/null {$auth}", 'r'); $info = array (); @@ -177,30 +181,30 @@ function client ($params, $purl) { 2 => array("pipe", "w") // stderr is a pipe to write to ); $env = null; - if(defined('AJXP_LOCALE')){ + if (defined('AJXP_LOCALE')) { $env = array("LC_ALL" => AJXP_LOCALE); } $process = proc_open($cmd, $descriptorspec, $pipes, null, $env); - if(is_resource($process)){ + if (is_resource($process)) { fclose($pipes[0]); $error = stream_get_contents($pipes[2]); fclose($pipes[2]); - if($error != ""){ + if ($error != "") { $error = strtolower($error); // common error - if(strstr($error, "command not found")!==false){ + if (strstr($error, "command not found")!==false) { fclose($pipes[1]); throw new Exception($error); - }else if(strstr($error, "domain")!==false && strstr($error, "os")!==false ){ + } else if (strstr($error, "domain")!==false && strstr($error, "os")!==false ) { self::debug("Smbclient alternate stream : ".$error); - }else{ + } else { AJXP_Logger::logAction("ERROR", array("Smbclient error" => $error)); } } $output = $pipes[1]; } - if(isset($output) && is_resource($output)){ + if (isset($output) && is_resource($output)) { while ($line = fgets ($output, 4096)) { list ($tag, $regs, $i) = array ('skip', array (), array ()); @@ -247,7 +251,7 @@ function client ($params, $purl) { : array(); break; case 'error': - if(strstr($regs[1], "NO_SUCH_FILE") == 0){ + if (strstr($regs[1], "NO_SUCH_FILE") == 0) { return "NOT_FOUND"; } trigger_error($regs[1], E_USER_ERROR); @@ -266,23 +270,23 @@ function client ($params, $purl) { } //self::debug(print_r($info, true)); return $info; - //return; + //return; } # stats - function url_stat ($url, $flags = STREAM_URL_STAT_LINK) { - global $__count; - if ($s = smb::getstatcache($url)) { - self::debug("Using statcache for $url"); - return $s; + public function url_stat ($url, $flags = STREAM_URL_STAT_LINK) + { + global $__count; + if ($s = smb::getstatcache($url)) { + self::debug("Using statcache for $url"); + return $s; } self::debug("Getting statcache for $url"); //self::debug("Hey: " $url['user']); list ($stat, $pu) = array (array (), smb::parse_url ($url)); - switch ($pu['type']) - { + switch ($pu['type']) { case 'host': if ($o = smb::look ($pu)) //self::debug($_SESSION["AJXP_SESSION_REMOTE_USER"]); @@ -291,117 +295,122 @@ function url_stat ($url, $flags = STREAM_URL_STAT_LINK) { trigger_error ("url_stat(): list failed for host '{$host}'", E_USER_WARNING); break; case 'share': - if($_SESSION["COUNT"] == 0) { - $_SESSION["COUNT"] = 1; - //self::debug("OH HEY"); - //$__count++; - //self::debug($__count); - if ($o = smb::look ($pu)) { - $_SESSION["disk"] = $o['disk']; - self::debug(print_r($_SESSION["disk"], true)); - //self::debug(print_r($_ENV, true)); + if ($_SESSION["COUNT"] == 0) { + $_SESSION["COUNT"] = 1; + //self::debug("OH HEY"); + //$__count++; + //self::debug($__count); + if ($o = smb::look ($pu)) { + $_SESSION["disk"] = $o['disk']; + self::debug(print_r($_SESSION["disk"], true)); + //self::debug(print_r($_ENV, true)); $found = FALSE; $lshare = strtolower ($pu['share']); # fix by Eric Leung - if(is_array($o) && isSet($o['disk']) && is_array($o['disk'])){ - foreach ($o['disk'] as $s) if ($lshare == strtolower($s)) { - $found = TRUE; - //self::debug("DISK: " . $s); - $stat = stat ("/tmp"); - break; - } + if (is_array($o) && isSet($o['disk']) && is_array($o['disk'])) { + foreach ($o['disk'] as $s) if ($lshare == strtolower($s)) { + $found = TRUE; + //self::debug("DISK: " . $s); + $stat = stat ("/tmp"); + break; + } } if (! $found) //trigger_error ("url_stat(): disk resource '{$share}' not found in '{$host}'", E_USER_WARNING); return null; } break; - } else { - //self::debug($__count); - //self::debug("WORKING"); - $found = FALSE; + } else { + //self::debug($__count); + //self::debug("WORKING"); + $found = FALSE; $lshare = strtolower ($pu['share']); # fix by Eric Leung - if(is_array($_SESSION["disk"]) && isSet($_SESSION["disk"]) && is_array($_SESSION["disk"])){ - foreach ($_SESSION["disk"] as $s) if ($lshare == strtolower($s)) { - $found = TRUE; - //self::debug("oh boy"); - $stat = stat ("/tmp"); - break; - } + if (is_array($_SESSION["disk"]) && isSet($_SESSION["disk"]) && is_array($_SESSION["disk"])) { + foreach ($_SESSION["disk"] as $s) if ($lshare == strtolower($s)) { + $found = TRUE; + //self::debug("oh boy"); + $stat = stat ("/tmp"); + break; + } } if (! $found) //trigger_error ("url_stat(): disk resource '{$share}' not found in '{$host}'", E_USER_WARNING); return null; break; } - case 'path': + case 'path': //self::debug('before exe'.print_r($pu, true)); - $o = smb::execute ('dir "'.$pu['path'].'"', $pu); + $o = smb::execute ('dir "'.$pu['path'].'"', $pu); if ($o != null) { - if($o == "NOT_FOUND"){ - return null; - } + if ($o == "NOT_FOUND") { + return null; + } $p = explode ("\\", $pu['path']); - $name = $p[count($p)-1]; + $name = $p[count($p)-1]; if (isset ($o['info'][$name])) { $stat = smb::addstatcache ($url, $o['info'][$name]); } else { - $stat = stat("/tmp"); + $stat = stat("/tmp"); //trigger_error ("url_stat(): path '{$pu['path']}' not found", E_USER_WARNING); } } else { - //$stat = stat("/tmp"); + //$stat = stat("/tmp"); trigger_error ("url_stat(): dir failed for path '{$pu['path']}'", E_USER_WARNING); } break; default: trigger_error ('error in URL', E_USER_ERROR); } - + return $stat; } - function addstatcache ($url, $info) { + public function addstatcache ($url, $info) + { global $__smb_cache; $url = smb::cleanUrl($url); $is_file = (strpos ($info['attr'],'D') === FALSE); - if(stripos(PHP_OS, "win") !== false){ + if (stripos(PHP_OS, "win") !== false) { $s = ($is_file) ? stat (__FILE__) : stat (dirname(__FILE__)); - }else{ + } else { $s = ($is_file) ? stat ('/etc/passwd') : stat ('/tmp'); } - if($is_file){ - $s[2] = $s['mode'] = 0666; - $s[2] = $s['mode'] |= 0100000; + if ($is_file) { + $s[2] = $s['mode'] = 0666; + $s[2] = $s['mode'] |= 0100000; } $s[7] = $s['size'] = $info['size']; $s[8] = $s[9] = $s[10] = $s['atime'] = $s['mtime'] = $s['ctime'] = $info['time']; return $__smb_cache['stat'][$url] = $s; } - function getstatcache ($url) { + public function getstatcache ($url) + { global $__smb_cache; $url = smb::cleanUrl($url); return isset ($__smb_cache['stat'][$url]) ? $__smb_cache['stat'][$url] : FALSE; } - function clearstatcache ($url='') { + public function clearstatcache ($url='') + { global $__smb_cache; $url = smb::cleanUrl($url); if ($url == '') $__smb_cache['stat'] = array (); else unset ($__smb_cache['stat'][$url]); } - static function cleanUrl($url){ - $url = str_replace("smb://", "smb:/__/__", $url); - while (strstr($url, "//")!==FALSE) { - $url = str_replace("//", "/", $url); - } - $url = str_replace("smb:/__/__", "smb://", $url); - return $url; + public static function cleanUrl($url) + { + $url = str_replace("smb://", "smb:/__/__", $url); + while (strstr($url, "//")!==FALSE) { + $url = str_replace("//", "/", $url); + } + $url = str_replace("smb:/__/__", "smb://", $url); + return $url; } - + # commands - function unlink ($url) { + public function unlink ($url) + { $url = smb::cleanUrl($url); $pu = smb::parse_url($url); if ($pu['type'] <> 'path') trigger_error('unlink(): error in URL', E_USER_ERROR); @@ -410,7 +419,8 @@ function unlink ($url) { return true; } - function rename ($url_from, $url_to) { + public function rename ($url_from, $url_to) + { $url_from = smb::cleanUrl($url_from); $url_to = smb::cleanUrl($url_to); @@ -429,8 +439,9 @@ function rename ($url_from, $url_to) { return smb::execute ('rename "'.$from['path'].'" "'.$to['path'].'"', $to); } - function mkdir ($url, $mode, $options) { - //self::debug("hmmmmm"); + public function mkdir ($url, $mode, $options) + { + //self::debug("hmmmmm"); $url = smb::cleanUrl($url); $pu = smb::parse_url($url); @@ -439,90 +450,91 @@ function mkdir ($url, $mode, $options) { return smb::execute ('mkdir "'.$pu['path'].'"', $pu); } - function rmdir ($url) { + public function rmdir ($url) + { $url = smb::cleanUrl($url); $pu = smb::parse_url($url); if ($pu['type'] <> 'path') trigger_error('rmdir(): error in URL', E_USER_ERROR); smb::clearstatcache ($url); return smb::execute ('rmdir "'.$pu['path'].'"', $pu); } - - - function smbparseUrl ($url){ - - $pass = $_SESSION["AJXP_SESSION_REMOTE_PASS"]; - //$pass = $pass["password"]; - $pu['scheme'] = 'smb'; - $temp = substr($url, 6); - //echo $temp . "\n"; + + + public function smbparseUrl ($url) + { + $pass = $_SESSION["AJXP_SESSION_REMOTE_PASS"]; + //$pass = $pass["password"]; + $pu['scheme'] = 'smb'; + $temp = substr($url, 6); + //echo $temp . "\n"; $pu['user'] = ""; - if(strstr($temp, ":") !== false){ + if (strstr($temp, ":") !== false) { $i = 0; - while($temp[$i] != ':'){ + while ($temp[$i] != ':') { $i++; } $pu['user'] = substr($temp, 0 , $i); } - //echo $pu['user'] . "\n"; - - $temp = substr($temp, $i + 1); - //self::debug($temp); - $i = 0; - $j = 0; - $k = 1; - //self::debug("PASS: " . $pass); - $pu['pass'] = ''; - while($pass != $pu['pass']){ - $i = 0; - $j = 0; - while($temp[$i] != '@' || $j <= $k){ - if($temp[$i] == '@')$j++; - if($j == $k) break; - if($i >= strlen($temp)) { - exit("Parse error: bad password"); - } - $i++; - } - $k++; - $pu['pass'] = substr($temp, 0 , $i); - //self::debug("PASS: " . $pu['pass']); - //echo $pu['pass'] . "\n"; - //echo "J: " . $j . " K: " . $k . "\n"; - - - } - $temp = substr($temp, $i+1); - //echo $temp; - $i = 0; - while($temp[$i] != '/'){ - $i++; - } - $pu['host'] = substr($temp, 0 , $i); - $pu['path'] = substr($temp, $i); - - //echo $pu['pass'] . "\n"; - return $pu; - } + //echo $pu['user'] . "\n"; + + $temp = substr($temp, $i + 1); + //self::debug($temp); + $i = 0; + $j = 0; + $k = 1; + //self::debug("PASS: " . $pass); + $pu['pass'] = ''; + while ($pass != $pu['pass']) { + $i = 0; + $j = 0; + while ($temp[$i] != '@' || $j <= $k) { + if($temp[$i] == '@')$j++; + if($j == $k) break; + if ($i >= strlen($temp)) { + exit("Parse error: bad password"); + } + $i++; + } + $k++; + $pu['pass'] = substr($temp, 0 , $i); + //self::debug("PASS: " . $pu['pass']); + //echo $pu['pass'] . "\n"; + //echo "J: " . $j . " K: " . $k . "\n"; + + + } + $temp = substr($temp, $i+1); + //echo $temp; + $i = 0; + while ($temp[$i] != '/') { + $i++; + } + $pu['host'] = substr($temp, 0 , $i); + $pu['path'] = substr($temp, $i); + + //echo $pu['pass'] . "\n"; + return $pu; + } } ################################################################### # SMB_STREAM_WRAPPER - class to be registered for smb:// URLs ################################################################### -class smb_stream_wrapper extends smb { - +class smb_stream_wrapper extends smb +{ # variables - var $stream, $url, $parsed_url = array (), $mode, $tmpfile; - var $need_flush = FALSE; - var $dir = array (), $dir_index = -1; + public $stream, $url, $parsed_url = array (), $mode, $tmpfile; + public $need_flush = FALSE; + public $dir = array (), $dir_index = -1; # directories - function dir_opendir ($url, $options) { - - $d = $this->getdircache ($url); + public function dir_opendir ($url, $options) + { + $d = $this->getdircache ($url); if (is_array($d)) { $this->dir = $d; $this->dir_index = 0; @@ -542,23 +554,23 @@ function dir_opendir ($url, $options) { break; case 'share': case 'path': - $o = smb::execute ('dir "'.$pu['path'].'\*"', $pu); + $o = smb::execute ('dir "'.$pu['path'].'\*"', $pu); if (is_array($o)) { - if(isSet($o['info'])){ - $this->dir = array_keys($o['info']); - $this->dir_index = 0; - $this->adddircache ($url, $this->dir); - foreach ($o['info'] as $name => $info) { - self::debug("Adding to statcache ".$url.'/'.$name); - //smb::addstatcache($url . '/' . urlencode($name), $info); - smb::addstatcache($url .'/'. $name, $info); - } - }else{ - $this->dir = array(); - $this->dir_index = 0; - $this->adddircache($url, $this->dir); - } - } else { + if (isSet($o['info'])) { + $this->dir = array_keys($o['info']); + $this->dir_index = 0; + $this->adddircache ($url, $this->dir); + foreach ($o['info'] as $name => $info) { + self::debug("Adding to statcache ".$url.'/'.$name); + //smb::addstatcache($url . '/' . urlencode($name), $info); + smb::addstatcache($url .'/'. $name, $info); + } + } else { + $this->dir = array(); + $this->dir_index = 0; + $this->adddircache($url, $this->dir); + } + } else { trigger_error ("dir_opendir(): dir failed for path '{$pu['path']}'", E_USER_WARNING); } break; @@ -568,30 +580,33 @@ function dir_opendir ($url, $options) { return TRUE; } - function dir_readdir () { return ($this->dir_index < count($this->dir)) ? $this->dir[$this->dir_index++] : FALSE; } + public function dir_readdir () { return ($this->dir_index < count($this->dir)) ? $this->dir[$this->dir_index++] : FALSE; } - function dir_rewinddir () { $this->dir_index = 0; } + public function dir_rewinddir () { $this->dir_index = 0; } - function dir_closedir () { $this->dir = array(); $this->dir_index = -1; return TRUE; } + public function dir_closedir () { $this->dir = array(); $this->dir_index = -1; return TRUE; } # cache - function adddircache ($url, $content) { - global $__smb_cache; + public function adddircache ($url, $content) + { + global $__smb_cache; $url = smb::cleanUrl($url); self::debug("Adding to dir cache", array("url"=>$url)); return $__smb_cache['dir'][$url] = $content; } - function getdircache ($url) { + public function getdircache ($url) + { global $__smb_cache; $url = smb::cleanUrl($url); self::debug("Testing dir cache", array("url"=>$url)); return isset ($__smb_cache['dir'][$url]) ? $__smb_cache['dir'][$url] : FALSE; } - function cleardircache ($url='') { + public function cleardircache ($url='') + { global $__smb_cache; $url = smb::cleanUrl($url); if ($url == '') $__smb_cache['dir'] = array (); else unset ($__smb_cache['dir'][$url]); @@ -600,7 +615,8 @@ function cleardircache ($url='') { # streams - function stream_open ($url, $mode, $options, $opened_path) { + public function stream_open ($url, $mode, $options, $opened_path) + { $url = smb::cleanUrl($url); $this->url = $url; $this->mode = $mode; @@ -612,21 +628,21 @@ function stream_open ($url, $mode, $options, $opened_path) { case 'r+': case 'rb': case 'a': - case 'a+': - // REFERENCE STREAM BUT DO NOT OPEN IT UNTIL READING IS REALLY NECESSARY! - /* - $this->tmpfile = tempnam('/tmp', 'smb.down.'); + case 'a+': + // REFERENCE STREAM BUT DO NOT OPEN IT UNTIL READING IS REALLY NECESSARY! + /* + $this->tmpfile = tempnam('/tmp', 'smb.down.'); smb::execute ('get "'.$pu['path'].'" "'.$this->tmpfile.'"', $pu); $this->stream = fopen ($this->tmpfile, $mode); */ - $this->defer_stream_read = true; + $this->defer_stream_read = true; break; case 'w': case 'w+': case 'wb': case 'x': - case 'x+': - $this->cleardircache(); + case 'x+': + $this->cleardircache(); $this->tmpfile = tempnam('/tmp', 'smb.up.'); $this->stream = fopen ($this->tmpfile, $mode); $this->need_flush = TRUE; @@ -636,29 +652,32 @@ function stream_open ($url, $mode, $options, $opened_path) { return TRUE; } - function stream_close () { - if(isSet($this->stream)){ - return fclose($this->stream); - }else{ - // Stream was in fact never opened! - return true; - } + public function stream_close () + { + if (isSet($this->stream)) { + return fclose($this->stream); + } else { + // Stream was in fact never opened! + return true; + } } - function stream_read ($count) { return fread($this->getStream(), $count); } + public function stream_read ($count) { return fread($this->getStream(), $count); } - function stream_write ($data) { - $this->need_flush = TRUE; - return fwrite($this->getStream(), $data); + public function stream_write ($data) + { + $this->need_flush = TRUE; + return fwrite($this->getStream(), $data); } - function stream_eof () { return feof($this->getStream()); } + public function stream_eof () { return feof($this->getStream()); } - function stream_tell () { return ftell($this->getStream()); } + public function stream_tell () { return ftell($this->getStream()); } - function stream_seek ($offset, $whence=null) { return fseek($this->getStream(), $offset, $whence); } + public function stream_seek ($offset, $whence=null) { return fseek($this->getStream(), $offset, $whence); } - function stream_flush () { + public function stream_flush () + { if ($this->mode <> 'r' && $this->need_flush) { smb::clearstatcache ($this->url); smb::execute ('put "'.$this->tmpfile.'" "'.$this->parsed_url['path'].'"', $this->parsed_url); @@ -666,27 +685,29 @@ function stream_flush () { } } - function stream_stat () { return smb::url_stat ($this->url); } + public function stream_stat () { return smb::url_stat ($this->url); } - function __destruct () { + public function __destruct () + { if ($this->tmpfile <> '') { if ($this->need_flush) $this->stream_flush (); unlink ($this->tmpfile); } } - - private function getStream(){ - if(isSet($this->stream)){ - return $this->stream; - } - if(isSet($this->defer_stream_read)){ - $this->tmpfile = tempnam('/tmp', 'smb.down'); - self::debug("Creating real tmp file now"); - smb::execute ('get "'.$this->parsed_url['path'].'" "'.$this->tmpfile.'"', $this->parsed_url); - $this->stream = fopen($this->tmpfile, $this->mode); - } - return $this->stream; + + private function getStream() + { + if (isSet($this->stream)) { + return $this->stream; + } + if (isSet($this->defer_stream_read)) { + $this->tmpfile = tempnam('/tmp', 'smb.down'); + self::debug("Creating real tmp file now"); + smb::execute ('get "'.$this->parsed_url['path'].'" "'.$this->tmpfile.'"', $this->parsed_url); + $this->stream = fopen($this->tmpfile, $this->mode); + } + return $this->stream; } } @@ -697,5 +718,3 @@ private function getStream(){ stream_wrapper_register('smb', 'smb_stream_wrapper') or die ('Failed to register protocol'); - -?> diff --git a/core/src/plugins/access.webdav/class.webdavAccessDriver.php b/core/src/plugins/access.webdav/class.webdavAccessDriver.php index bd6e722fb1..8ecad3abfa 100644 --- a/core/src/plugins/access.webdav/class.webdavAccessDriver.php +++ b/core/src/plugins/access.webdav/class.webdavAccessDriver.php @@ -1,106 +1,107 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - * - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); -//require_once(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/access.fs/class.fsAccessDriver.php"); - -/** - * AJXP_Plugin to access a webdav enabled server - * @package AjaXplorer_Plugins - * @subpackage Access - */ -class webdavAccessDriver extends fsAccessDriver -{ - /** - * @var Repository - */ - public $repository; - public $driverConf; - protected $wrapperClassName; - protected $urlBase; - - function performChecks(){ - if(!AJXP_Utils::searchIncludePath('HTTP/WebDAV/Client.php')){ - throw new Exception("The PEAR HTTP_WebDAV_Client package must be installed!"); - } - } - - function initRepository(){ - @include_once("HTTP/WebDAV/Client.php"); - if(is_array($this->pluginConf)){ - $this->driverConf = $this->pluginConf; - }else{ - $this->driverConf = array(); - } - - if(!class_exists('HTTP_WebDAV_Client_Stream')){ - throw new Exception("You must have Pear HTTP/WebDAV/Client package installed to use this access driver!"); - } - $create = $this->repository->getOption("CREATE"); - $path = $this->repository->getOption("PATH"); - $recycle = $this->repository->getOption("RECYCLE_BIN"); - ConfService::setConf("PROBE_REAL_SIZE", false); - /* - if($create == true){ - if(!is_dir($path)) @mkdir($path); - if(!is_dir($path)){ - throw new AJXP_Exception("Cannot create root path for repository (".$this->repository->getDisplay()."). Please check repository configuration or that your folder is writeable!"); - } - if($recycle!= "" && !is_dir($path."/".$recycle)){ - @mkdir($path."/".$recycle); - if(!is_dir($path."/".$recycle)){ - throw new AJXP_Exception("Cannot create recycle bin folder. Please check repository configuration or that your folder is writeable!"); - } - } - }else{ - if(!is_dir($path)){ - throw new AJXP_Exception("Cannot find base path ($path) for your repository! Please check the configuration!"); - } - } - */ - $wrapperData = $this->detectStreamWrapper(true); - $this->wrapperClassName = $wrapperData["classname"]; - $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); - if(!is_dir($this->urlBase)){ - if(webdavAccessWrapper::$lastException){ - throw webdavAccessWrapper::$lastException; - } - throw new AJXP_Exception("Cannot connect to the WebDAV server ($path). Please check the configuration!"); - } - if($recycle != ""){ - RecycleBinManager::init($this->urlBase, "/".$recycle); - } - } - - /** - * Parse - * @param DOMNode $contribNode - */ - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($contribNode->nodeName != "actions") return ; - $this->disableArchiveBrowsingContributions($contribNode); - } - -} - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + * + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); +//require_once(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/access.fs/class.fsAccessDriver.php"); + +/** + * AJXP_Plugin to access a webdav enabled server + * @package AjaXplorer_Plugins + * @subpackage Access + */ +class webdavAccessDriver extends fsAccessDriver +{ + /** + * @var Repository + */ + public $repository; + public $driverConf; + protected $wrapperClassName; + protected $urlBase; + + public function performChecks() + { + if (!AJXP_Utils::searchIncludePath('HTTP/WebDAV/Client.php')) { + throw new Exception("The PEAR HTTP_WebDAV_Client package must be installed!"); + } + } + + public function initRepository() + { + @include_once("HTTP/WebDAV/Client.php"); + if (is_array($this->pluginConf)) { + $this->driverConf = $this->pluginConf; + } else { + $this->driverConf = array(); + } + + if (!class_exists('HTTP_WebDAV_Client_Stream')) { + throw new Exception("You must have Pear HTTP/WebDAV/Client package installed to use this access driver!"); + } + $create = $this->repository->getOption("CREATE"); + $path = $this->repository->getOption("PATH"); + $recycle = $this->repository->getOption("RECYCLE_BIN"); + ConfService::setConf("PROBE_REAL_SIZE", false); + /* + if ($create == true) { + if(!is_dir($path)) @mkdir($path); + if (!is_dir($path)) { + throw new AJXP_Exception("Cannot create root path for repository (".$this->repository->getDisplay()."). Please check repository configuration or that your folder is writeable!"); + } + if ($recycle!= "" && !is_dir($path."/".$recycle)) { + @mkdir($path."/".$recycle); + if (!is_dir($path."/".$recycle)) { + throw new AJXP_Exception("Cannot create recycle bin folder. Please check repository configuration or that your folder is writeable!"); + } + } + } else { + if (!is_dir($path)) { + throw new AJXP_Exception("Cannot find base path ($path) for your repository! Please check the configuration!"); + } + } + */ + $wrapperData = $this->detectStreamWrapper(true); + $this->wrapperClassName = $wrapperData["classname"]; + $this->urlBase = $wrapperData["protocol"]."://".$this->repository->getId(); + if (!is_dir($this->urlBase)) { + if (webdavAccessWrapper::$lastException) { + throw webdavAccessWrapper::$lastException; + } + throw new AJXP_Exception("Cannot connect to the WebDAV server ($path). Please check the configuration!"); + } + if ($recycle != "") { + RecycleBinManager::init($this->urlBase, "/".$recycle); + } + } + + /** + * Parse + * @param DOMNode $contribNode + */ + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if($contribNode->nodeName != "actions") return ; + $this->disableArchiveBrowsingContributions($contribNode); + } + +} diff --git a/core/src/plugins/access.webdav/class.webdavAccessWrapper.php b/core/src/plugins/access.webdav/class.webdavAccessWrapper.php index 0076f40f1d..424635bff4 100644 --- a/core/src/plugins/access.webdav/class.webdavAccessWrapper.php +++ b/core/src/plugins/access.webdav/class.webdavAccessWrapper.php @@ -28,67 +28,68 @@ * @package AjaXplorer_Plugins * @subpackage Access */ -class webdavAccessWrapper extends fsAccessWrapper { - +class webdavAccessWrapper extends fsAccessWrapper +{ public static $lastException; /** - * Initialize the stream from the given path. + * Initialize the stream from the given path. * Concretely, transform ajxp.webdav:// into webdav:// * * @param string $path * @return mixed Real path or -1 if currentListing contains the listing : original path converted to real path */ - protected static function initPath($path, $streamType, $storeOpenContext = false, $skipZip = false){ - $url = parse_url($path); - $repoId = $url["host"]; - $repoObject = ConfService::getRepositoryById($repoId); - if(!isSet($repoObject)) { + protected static function initPath($path, $streamType, $storeOpenContext = false, $skipZip = false) + { + $url = parse_url($path); + $repoId = $url["host"]; + $repoObject = ConfService::getRepositoryById($repoId); + if (!isSet($repoObject)) { $e = new Exception("Cannot find repository with id ".$repoId); self::$lastException = $e; throw $e; } - $path = $url["path"]; - $host = $repoObject->getOption("HOST"); - $hostParts = parse_url($host); - if($hostParts["scheme"] == "https" && !extension_loaded("openssl")){ + $path = $url["path"]; + $host = $repoObject->getOption("HOST"); + $hostParts = parse_url($host); + if ($hostParts["scheme"] == "https" && !extension_loaded("openssl")) { $e = new Exception("Warning you must have the openssl PHP extension loaded to connect an https server!"); self::$lastException = $e; throw $e; } - $credentials = AJXP_Safe::tryLoadingCredentialsFromSources($hostParts, $repoObject); - $user = $credentials["user"]; - $password = $credentials["password"]; - if($user!=null && $password!=null){ - $host = ($hostParts["scheme"]=="https"?"webdavs":"webdav")."://$user:$password@".$hostParts["host"]; - if(isSet($hostParts["port"])){ + $credentials = AJXP_Safe::tryLoadingCredentialsFromSources($hostParts, $repoObject); + $user = $credentials["user"]; + $password = $credentials["password"]; + if ($user!=null && $password!=null) { + $host = ($hostParts["scheme"]=="https"?"webdavs":"webdav")."://$user:$password@".$hostParts["host"]; + if (isSet($hostParts["port"])) { $host .= ":".$hostParts["port"]; } - }else{ - $host = str_replace(array("http", "https"), array("webdav", "webdavs"), $host); - } - // MAKE SURE THERE ARE NO // OR PROBLEMS LIKE THAT... - $basePath = $repoObject->getOption("PATH"); - if($basePath[strlen($basePath)-1] == "/"){ - $basePath = substr($basePath, 0, -1); - } - if($basePath[0] != "/"){ - $basePath = "/$basePath"; - } - $path = AJXP_Utils::securePath($path); - if($path[0] == "/"){ - $path = substr($path, 1); - } - // SHOULD RETURN webdav://host_server/uri/to/webdav/folder + } else { + $host = str_replace(array("http", "https"), array("webdav", "webdavs"), $host); + } + // MAKE SURE THERE ARE NO // OR PROBLEMS LIKE THAT... + $basePath = $repoObject->getOption("PATH"); + if ($basePath[strlen($basePath)-1] == "/") { + $basePath = substr($basePath, 0, -1); + } + if ($basePath[0] != "/") { + $basePath = "/$basePath"; + } + $path = AJXP_Utils::securePath($path); + if ($path[0] == "/") { + $path = substr($path, 1); + } + // SHOULD RETURN webdav://host_server/uri/to/webdav/folder AJXP_Logger::debug($host.$basePath."/".$path); - return $host.$basePath."/".$path; - } - + return $host.$basePath."/".$path; + } + /** * Opens the stream * Diff with parent class : do not "securePath", as it removes double slash * - * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" + * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" * @param String $mode * @param unknown_type $options * @param unknown_type $opened_path @@ -96,93 +97,99 @@ protected static function initPath($path, $streamType, $storeOpenContext = false */ public function stream_open($path, $mode, $options, &$context) { - try{ - $this->realPath = $this->initPath($path, "file"); - }catch (Exception $e){ - AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); - return false; - } - if($this->realPath == -1){ - $this->fp = -1; - return true; - }else{ - $this->fp = fopen($this->realPath, $mode, $options); - return ($this->fp !== false); - } + try { + $this->realPath = $this->initPath($path, "file"); + } catch (Exception $e) { + AJXP_Logger::logAction("error", array("message" => "Error while opening stream $path")); + return false; + } + if ($this->realPath == -1) { + $this->fp = -1; + return true; + } else { + $this->fp = fopen($this->realPath, $mode, $options); + return ($this->fp !== false); + } } - + /** - * Stats the given path. + * Stats the given path. * Fix PEAR by adding S_ISREG mask when file case. * * @param unknown_type $path * @param unknown_type $flags * @return unknown */ - public function url_stat($path, $flags){ - // File and zip case - if($fp = @fopen($path, "r")){ - $stat = fstat($fp); - fclose($fp); - if($stat["mode"] == 0666){ - $stat[2] = $stat["mode"] |= 0100000; // S_ISREG - } - return $stat; - } - - // Non existing file - return null; + public function url_stat($path, $flags) + { + // File and zip case + if ($fp = @fopen($path, "r")) { + $stat = fstat($fp); + fclose($fp); + if ($stat["mode"] == 0666) { + $stat[2] = $stat["mode"] |= 0100000; // S_ISREG + } + return $stat; + } + + // Non existing file + return null; } - + /** * Opens a handle to the dir - * Fix PEAR by being sure it ends up with "/", to avoid + * Fix PEAR by being sure it ends up with "/", to avoid * adding the current dir to the children list. * * @param unknown_type $path * @param unknown_type $options * @return unknown */ - public function dir_opendir ($path , $options ){ - $this->realPath = $this->initPath($path, "dir", true); - if($this->realPath[strlen($this->realPath)-1] != "/"){ - $this->realPath.="/"; - } - if(is_string($this->realPath)){ - $this->dH = @opendir($this->realPath); - }else if($this->realPath == -1){ - $this->dH = -1; - } - return $this->dH !== false; - } - - public function dir_readdir (){ + public function dir_opendir ($path , $options ) + { + $this->realPath = $this->initPath($path, "dir", true); + if ($this->realPath[strlen($this->realPath)-1] != "/") { + $this->realPath.="/"; + } + if (is_string($this->realPath)) { + $this->dH = @opendir($this->realPath); + } else if ($this->realPath == -1) { + $this->dH = -1; + } + return $this->dH !== false; + } + + public function dir_readdir () + { $x = parent::dir_readdir(); if ( strstr( $x, '%') !== false) $x = urldecode( $x); return( $x); } - - // DUPBLICATE STATIC FUNCTIONS TO BE SURE - // NOT TO MESS WITH self:: CALLS - - public static function removeTmpFile($tmpDir, $tmpFile){ - if(is_file($tmpFile)) unlink($tmpFile); - if(is_dir($tmpDir)) rmdir($tmpDir); - } - - protected static function closeWrapper(){ - if(self::$crtZip != null) { - self::$crtZip = null; - self::$currentListing = null; - self::$currentListingKeys = null; - self::$currentListingIndex = null; - self::$currentFileKey = null; - } - } - - public static function getRealFSReference($path, $persistent = false){ - if ( $persistent) { + + // DUPBLICATE STATIC FUNCTIONS TO BE SURE + // NOT TO MESS WITH self:: CALLS + + public static function removeTmpFile($tmpDir, $tmpFile) + { + if(is_file($tmpFile)) unlink($tmpFile); + if(is_dir($tmpDir)) rmdir($tmpDir); + } + + protected static function closeWrapper() + { + if (self::$crtZip != null) { + self::$crtZip = null; + self::$currentListing = null; + self::$currentListingKeys = null; + self::$currentListingIndex = null; + self::$currentFileKey = null; + } + } + + public static function getRealFSReference($path, $persistent = false) + { + if ($persistent) { $tmpFile = AJXP_Utils::getAjxpTmpDir()."/".md5(time()); $tmpHandle = fopen($tmpFile, "wb"); self::copyFileInStream($path, $tmpHandle); @@ -195,23 +202,25 @@ public static function getRealFSReference($path, $persistent = false){ } - public static function isRemote(){ - return true; + public static function isRemote() + { + return true; + } + + public static function copyFileInStream($path, $stream) + { + $fp = fopen(self::getRealFSReference($path), "rb"); + while (!feof($fp)) { + $data = fread($fp, 4096); + fwrite($stream, $data, strlen($data)); + } + fclose($fp); } - - public static function copyFileInStream($path, $stream){ - $fp = fopen(self::getRealFSReference($path), "rb"); - while (!feof($fp)) { - $data = fread($fp, 4096); - fwrite($stream, $data, strlen($data)); - } - fclose($fp); - } - - public static function changeMode($path, $chmodValue){ + + public static function changeMode($path, $chmodValue) + { // DO NOTHING! - //$realPath = self::initPath($path, "file"); - //chmod($realPath, $chmodValue); - } + //$realPath = self::initPath($path, "file"); + //chmod($realPath, $chmodValue); + } } -?> \ No newline at end of file diff --git a/core/src/plugins/access.webdav/i18n/conf/en.php b/core/src/plugins/access.webdav/i18n/conf/en.php index d78f07f3a1..bc8d681eba 100644 --- a/core/src/plugins/access.webdav/i18n/conf/en.php +++ b/core/src/plugins/access.webdav/i18n/conf/en.php @@ -28,4 +28,3 @@ "File Creation Mask" => "File Creation Mask", "Optionnaly apply a chmod operation. Value must be numeric, like 0777, 0644, etc." => "Optionnaly apply a chmod operation. Value must be numeric, like 0777, 0644, etc.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.webdav/i18n/conf/fr.php b/core/src/plugins/access.webdav/i18n/conf/fr.php index 175bfd0ae6..dd9396ab24 100644 --- a/core/src/plugins/access.webdav/i18n/conf/fr.php +++ b/core/src/plugins/access.webdav/i18n/conf/fr.php @@ -28,4 +28,3 @@ "File Creation Mask" => "File Creation Mask", "Optionnaly apply a chmod operation. Value must be numeric, like 0777, 0644, etc." => "Optionnaly apply a chmod operation. Value must be numeric, like 0777, 0644, etc.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.webdav/i18n/conf/pt.php b/core/src/plugins/access.webdav/i18n/conf/pt.php index 2f8a26a8b8..6a1c72f7a8 100644 --- a/core/src/plugins/access.webdav/i18n/conf/pt.php +++ b/core/src/plugins/access.webdav/i18n/conf/pt.php @@ -28,4 +28,3 @@ "File Creation Mask" => "Máscara de criação do ficheiro", "Optionnaly apply a chmod operation. Value must be numeric, like 0777, 0644, etc." => "Opcionalmente aplicar um 'chmod' para corrigir permissões. Os valores devem ser numéricos, do género: 0777, 0644, etc.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.webdav/manifest.xml b/core/src/plugins/access.webdav/manifest.xml index ed65a3c9cb..8790648812 100644 --- a/core/src/plugins/access.webdav/manifest.xml +++ b/core/src/plugins/access.webdav/manifest.xml @@ -22,4 +22,4 @@ - \ No newline at end of file + diff --git a/core/src/plugins/access.wms/class.WmsBrowser.php b/core/src/plugins/access.wms/class.WmsBrowser.php index 9a8318fdda..399fd38601 100644 --- a/core/src/plugins/access.wms/class.WmsBrowser.php +++ b/core/src/plugins/access.wms/class.WmsBrowser.php @@ -25,125 +25,127 @@ * @package AjaXplorer_Plugins * @subpackage Access */ -class WmsBrowser extends AbstractAccessDriver +class WmsBrowser extends AbstractAccessDriver { - function switchAction($action, $httpVars, $fileVars){ - if(!isSet($this->actions[$action])) return; - parent::accessPreprocess($action, $httpVars, $fileVars); - - switch ($action){ - case "ls": - $doc = DOMDocument::load($this->repository->getOption("HOST") . "?request=GetCapabilities"); - $xPath = new DOMXPath($doc); - $dir = $httpVars["dir"]; - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendFilesListComponentConfig(''); - - $layers = $xPath->query("Capability/Layer/Layer"); - // Detect "levels" - $levels = array(); - $leafs = array(); - $styleLevels = $prefixLevels = false; - foreach ($layers as $layer){ - $name = $xPath->evaluate("Name", $layer)->item(0)->nodeValue; - $stylesList = $xPath->query("Style/Name", $layer); - if(strstr($name, ":")!==false){ - $exp = explode(":", $name); - if(!isSet($levels[$exp[0]]))$levels[$exp[0]] = array(); - $levels[$exp[0]][] = $layer; - $prefixLevels = true; - }else if($stylesList->length > 1){ - if(!isSet($levels[$name])) $levels[$name] = array(); - foreach ($stylesList as $style){ - $levels[$name][$style->nodeValue] = $layer; - } - $styleLevels = true; - }else { - $leafs[] = $layer; - } - } - if($dir == "/" || $dir == ""){ - $this->listLevels($levels); - $this->listLayers($leafs, $xPath); - }else if(isSet($levels[basename($dir)])){ - $this->listLayers($levels[basename($dir)], $xPath, ($styleLevels?array($this,"replaceStyle"):null)); - } - AJXP_XMLWriter::close(); - break; - - default: - break; - } - } - - function listLevels($levels) { - foreach ($levels as $key => $layers ){ - AJXP_XMLWriter::renderNode("/$key", $key, false, array( - "icon" => "folder.png", - "openicon" => "openfolder.png", - "parentname" => "/", - "srs" => "-", - "keywords" => "-", - "style" => "-" - )); - } - - } - - function replaceStyle($key, $metaData){ - if(!is_string($key)) return $metaData ; - $metaData["name"] = $metaData["name"]."___".$key; - $metaData["title"] = $metaData["title"]." (".$key.")"; - $metaData["style"] = $key; - return $metaData; - } - - function listLayers($nodeList, $xPath, $replaceCallback = null){ - foreach ($nodeList as $key => $node){ - $name = $xPath->evaluate("Name", $node)->item(0)->nodeValue; - $title =$xPath->evaluate("Title", $node)->item(0)->nodeValue; - $srs =$xPath->evaluate("SRS", $node)->item(0)->nodeValue; + public function switchAction($action, $httpVars, $fileVars) + { + if(!isSet($this->actions[$action])) return; + parent::accessPreprocess($action, $httpVars, $fileVars); + + switch ($action) { + case "ls": + $doc = DOMDocument::load($this->repository->getOption("HOST") . "?request=GetCapabilities"); + $xPath = new DOMXPath($doc); + $dir = $httpVars["dir"]; + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendFilesListComponentConfig(''); + + $layers = $xPath->query("Capability/Layer/Layer"); + // Detect "levels" + $levels = array(); + $leafs = array(); + $styleLevels = $prefixLevels = false; + foreach ($layers as $layer) { + $name = $xPath->evaluate("Name", $layer)->item(0)->nodeValue; + $stylesList = $xPath->query("Style/Name", $layer); + if (strstr($name, ":")!==false) { + $exp = explode(":", $name); + if(!isSet($levels[$exp[0]]))$levels[$exp[0]] = array(); + $levels[$exp[0]][] = $layer; + $prefixLevels = true; + } else if ($stylesList->length > 1) { + if(!isSet($levels[$name])) $levels[$name] = array(); + foreach ($stylesList as $style) { + $levels[$name][$style->nodeValue] = $layer; + } + $styleLevels = true; + } else { + $leafs[] = $layer; + } + } + if ($dir == "/" || $dir == "") { + $this->listLevels($levels); + $this->listLayers($leafs, $xPath); + } else if (isSet($levels[basename($dir)])) { + $this->listLayers($levels[basename($dir)], $xPath, ($styleLevels?array($this,"replaceStyle"):null)); + } + AJXP_XMLWriter::close(); + break; + + default: + break; + } + } + + public function listLevels($levels) + { + foreach ($levels as $key => $layers) { + AJXP_XMLWriter::renderNode("/$key", $key, false, array( + "icon" => "folder.png", + "openicon" => "openfolder.png", + "parentname" => "/", + "srs" => "-", + "keywords" => "-", + "style" => "-" + )); + } + + } + + public function replaceStyle($key, $metaData) + { + if(!is_string($key)) return $metaData ; + $metaData["name"] = $metaData["name"]."___".$key; + $metaData["title"] = $metaData["title"]." (".$key.")"; + $metaData["style"] = $key; + return $metaData; + } + + public function listLayers($nodeList, $xPath, $replaceCallback = null) + { + foreach ($nodeList as $key => $node) { + $name = $xPath->evaluate("Name", $node)->item(0)->nodeValue; + $title =$xPath->evaluate("Title", $node)->item(0)->nodeValue; + $srs =$xPath->evaluate("SRS", $node)->item(0)->nodeValue; $metaData = array( - "icon" => "wms_images/mimes/ICON_SIZE/domtreeviewer.png", - "parentname" => "/", - "name" => $name, - "title" => $title, - "ajxp_mime" => "wms_layer", - "srs" => $srs, - "wms_url" => $this->repository->getOption("HOST") + "icon" => "wms_images/mimes/ICON_SIZE/domtreeviewer.png", + "parentname" => "/", + "name" => $name, + "title" => $title, + "ajxp_mime" => "wms_layer", + "srs" => $srs, + "wms_url" => $this->repository->getOption("HOST") ); - $style = $xPath->query("Style/Name", $node)->item(0)->nodeValue; - $metaData["style"] = $style; - $keys = array(); - $keywordList = $xPath->query("KeywordList/Keyword", $node); - if($keywordList->length){ - foreach ($keywordList as $keyword){ - $keys[] = $keyword->nodeValue; - } - } - $metaData["keywords"] = implode(",",$keys); - $metaData["queryable"] = ($node->attributes->item(0)->value == "1"?"True":"False"); - $bBoxAttributes = array(); - try{ - $bBoxAttributes = $xPath->query("LatLonBoundingBox", $node)->item(0)->attributes; - $attributes = $xPath->query("BoundingBox", $node)->item(0)->attributes; - if(isSet($attributes)){ - $bBoxAttributes = $attributes; - } - }catch(Exception $e){} - foreach ($bBoxAttributes as $domAttr){ - $metaData["bbox_".$domAttr->name] = $domAttr->value; - } - - if($replaceCallback != null){ - $metaData = call_user_func($replaceCallback, $key, $metaData); - } - + $style = $xPath->query("Style/Name", $node)->item(0)->nodeValue; + $metaData["style"] = $style; + $keys = array(); + $keywordList = $xPath->query("KeywordList/Keyword", $node); + if ($keywordList->length) { + foreach ($keywordList as $keyword) { + $keys[] = $keyword->nodeValue; + } + } + $metaData["keywords"] = implode(",",$keys); + $metaData["queryable"] = ($node->attributes->item(0)->value == "1"?"True":"False"); + $bBoxAttributes = array(); + try { + $bBoxAttributes = $xPath->query("LatLonBoundingBox", $node)->item(0)->attributes; + $attributes = $xPath->query("BoundingBox", $node)->item(0)->attributes; + if (isSet($attributes)) { + $bBoxAttributes = $attributes; + } + } catch (Exception $e) {} + foreach ($bBoxAttributes as $domAttr) { + $metaData["bbox_".$domAttr->name] = $domAttr->value; + } + + if ($replaceCallback != null) { + $metaData = call_user_func($replaceCallback, $key, $metaData); + } + AJXP_XMLWriter::renderNode("/".$metaData["name"], $title, true, $metaData); - } - } - - -} + } + } + -?> \ No newline at end of file +} diff --git a/core/src/plugins/access.wms/i18n/conf/en.php b/core/src/plugins/access.wms/i18n/conf/en.php index 0e16993437..106bfae92c 100644 --- a/core/src/plugins/access.wms/i18n/conf/en.php +++ b/core/src/plugins/access.wms/i18n/conf/en.php @@ -24,4 +24,3 @@ "Wms Server" => "Wms Server", "Wms server url" => "Wms server url", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.wms/i18n/conf/fr.php b/core/src/plugins/access.wms/i18n/conf/fr.php index 8ab4cd2a75..3346104e19 100644 --- a/core/src/plugins/access.wms/i18n/conf/fr.php +++ b/core/src/plugins/access.wms/i18n/conf/fr.php @@ -24,4 +24,3 @@ "Wms Server" => "Serveur WMS", "Wms server url" => "Url du serveur", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.wms/i18n/de.php b/core/src/plugins/access.wms/i18n/de.php index cc85778492..ecad7549a7 100644 --- a/core/src/plugins/access.wms/i18n/de.php +++ b/core/src/plugins/access.wms/i18n/de.php @@ -7,6 +7,4 @@ "4" => "Style", "5" => "Stichwörter", "6" => "Vorschau", -) - -?> +); diff --git a/core/src/plugins/access.wms/i18n/en.php b/core/src/plugins/access.wms/i18n/en.php index 4c1ee77127..f88ffaa025 100644 --- a/core/src/plugins/access.wms/i18n/en.php +++ b/core/src/plugins/access.wms/i18n/en.php @@ -7,6 +7,4 @@ "4" => "Style", "5" => "Keywords", "6" => "Projection", -) - -?> \ No newline at end of file +); diff --git a/core/src/plugins/access.wms/i18n/es.php b/core/src/plugins/access.wms/i18n/es.php index 2d57000cca..0b59e400a1 100644 --- a/core/src/plugins/access.wms/i18n/es.php +++ b/core/src/plugins/access.wms/i18n/es.php @@ -7,6 +7,4 @@ "4" => "Estilo", "5" => "Palábras Clave", "6" => "Proyección", -) - -?> +); diff --git a/core/src/plugins/access.wms/i18n/fr.php b/core/src/plugins/access.wms/i18n/fr.php index ad3ef4937a..04f97c615b 100644 --- a/core/src/plugins/access.wms/i18n/fr.php +++ b/core/src/plugins/access.wms/i18n/fr.php @@ -26,4 +26,3 @@ "5" => "Keywords", "6" => "Projection", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.wms/i18n/si.php b/core/src/plugins/access.wms/i18n/si.php index 484b2fe130..a8f281739e 100644 --- a/core/src/plugins/access.wms/i18n/si.php +++ b/core/src/plugins/access.wms/i18n/si.php @@ -27,4 +27,3 @@ "5" => "Ključne besede", "6" => "Projekcija", ); -?> \ No newline at end of file diff --git a/core/src/plugins/access.wms/manifest.xml b/core/src/plugins/access.wms/manifest.xml index 9d0f9117de..3b91d59287 100644 --- a/core/src/plugins/access.wms/manifest.xml +++ b/core/src/plugins/access.wms/manifest.xml @@ -9,7 +9,7 @@ - + @@ -56,12 +56,12 @@ ]]> - + - - + + - + 0){ path = window.actionArguments[0]; if(Object.isString(path)){path = new AjxpNode(path,false,getBaseName(path));} @@ -88,7 +88,7 @@ } if(path){ ajaxplorer.updateContextData(path); - } + } ]]> @@ -97,7 +97,7 @@ - + - - - - + + - + - + - \ No newline at end of file + diff --git a/core/src/plugins/action.antivirus/class.AntivirusScanner.php b/core/src/plugins/action.antivirus/class.AntivirusScanner.php index 4bb58faa1e..ce3c6bf99c 100644 --- a/core/src/plugins/action.antivirus/class.AntivirusScanner.php +++ b/core/src/plugins/action.antivirus/class.AntivirusScanner.php @@ -1,14 +1,14 @@ callSet($newNode); //initializes attributes - if($oldNode!=null || $newNode == null){ - return; - } // This block scans or doesn't scan the file. This is based on plugin parameters - if($this->file_size < $this->scan_max_size) { - if($this->scan_all == true) { - if($this->inList()==true) { - if($this->getFilteredOption("TRACE") == false) {return;} + if ($this->file_size < $this->scan_max_size) { + if ($this->scan_all == true) { + if ($this->inList()==true) { + if ($this->getFilteredOption("TRACE") == false) {return;} $this->scanLater(); return ; - }else { + } else { $this->scanNow(); return ; } } else { - if($this->inList()==true) { + if ($this->inList()==true) { $this->scanNow(); return ; - }else { - if($this->getFilteredOption("TRACE") == false) {return;} + } else { + if ($this->getFilteredOption("TRACE") == false) {return;} $this->scanLater(); return ; } } - }else { + } else { $this->scanLater(); return ; } @@ -55,165 +56,173 @@ public function scanFile ($oldNode, $newNode) { /** * @return bool true if file_extension is in the list extension_scan */ - private function inList() { - - while(strripos($this->extension_scan, $this->file_extension)) { - $start_pos = strripos($this->extension_scan, $this->file_extension); - $leng_ext = strlen($this->file_extension); - $result = substr($this->extension_scan, $start_pos); - $result = substr($result, $leng_ext, 1); - if(preg_match("/[A-Za-z0-9]+/",$result)) { - $this->extension_scan = substr($this->extension_scan, $start_pos + $leng_ext); - } else { - return true; - } - } - return false; - } + private function inList() + { + while (strripos($this->extension_scan, $this->file_extension)) { + $start_pos = strripos($this->extension_scan, $this->file_extension); + $leng_ext = strlen($this->file_extension); + $result = substr($this->extension_scan, $start_pos); + $result = substr($result, $leng_ext, 1); + if (preg_match("/[A-Za-z0-9]+/",$result)) { + $this->extension_scan = substr($this->extension_scan, $start_pos + $leng_ext); + } else { + return true; + } + } + return false; + } /** * This function immediatly scans the file, it calls the antivirus command */ - private function scanNow() { - $command = $this->getFilteredOption("COMMAND"); - $command = str_replace('$' . 'FILE', escapeshellarg($this->path), $command); + private function scanNow() + { + $command = $this->getFilteredOption("COMMAND"); + $command = str_replace('$' . 'FILE', escapeshellarg($this->path), $command); ob_start(); passthru($command, $int); $output=ob_get_contents(); ob_end_clean(); - if($int != 0) { - if(self::DEBUG_ON == 1) { - echo $output; - } else { - $filename = strrchr($this->path, DIRECTORY_SEPARATOR); - $filename = substr($filename, 1); - echo 'Virus has been found in : ' . $filename . ' File removed'; - } - //AJXP_Logger::logAction("Upload Virus File" . $this->path, array("file"=>SystemTextEncoding::fromUTF8($dir).DIRECTORY_SEPARATOR.$realpath)); - } - return; - } + if ($int != 0) { + if (self::DEBUG_ON == 1) { + echo $output; + } else { + $filename = strrchr($this->path, DIRECTORY_SEPARATOR); + $filename = substr($filename, 1); + echo 'Virus has been found in : ' . $filename . ' File removed'; + } + //AJXP_Logger::logAction("Upload Virus File" . $this->path, array("file"=>SystemTextEncoding::fromUTF8($dir).DIRECTORY_SEPARATOR.$realpath)); + } + return; + } /** * This function generates a trace of the file */ - private function scanLater() { - $numero=0; - $scanned=false; - if(is_dir($this->scan_diff_folder) == false) { - $create_folder = mkdir($this->scan_diff_folder, 0755); - if($create_folder == false) { - throw new Exception("can-t create scan_diff_folder, check permission"); - return; - } - } - while($scanned == false) { - if(file_exists( $this->scan_diff_folder .DIRECTORY_SEPARATOR. 'file_' . $numero)) { - $numero++; - } - else { - $command = 'echo "'. '\"' . $this->path . '\"' . '" >' . $this->scan_diff_folder .DIRECTORY_SEPARATOR. 'file_' . $numero; - passthru($command); - $scanned=true; - return; - } - } - } + private function scanLater() + { + $numero=0; + $scanned=false; + if (is_dir($this->scan_diff_folder) == false) { + $create_folder = mkdir($this->scan_diff_folder, 0755); + if ($create_folder == false) { + throw new Exception("can-t create scan_diff_folder, check permission"); + return; + } + } + while ($scanned == false) { + if (file_exists( $this->scan_diff_folder .DIRECTORY_SEPARATOR. 'file_' . $numero)) { + $numero++; + } else { + $command = 'echo "'. '\"' . $this->path . '\"' . '" >' . $this->scan_diff_folder .DIRECTORY_SEPARATOR. 'file_' . $numero; + passthru($command); + $scanned=true; + return; + } + } + } /** * @param AJXP_Node $nodeObject */ - private function callSet($nodeObject) { - - $this->setPath($nodeObject); - $this->setFileExtension($nodeObject); - $this->setExtensionScan(); - $this->setScanDiffFolder (); - $this->setScanMaxSize (); - $this->setFileSize($nodeObject); - $this->setScanAll(); + private function callSet($nodeObject) + { + $this->setPath($nodeObject); + $this->setFileExtension($nodeObject); + $this->setExtensionScan(); + $this->setScanDiffFolder (); + $this->setScanMaxSize (); + $this->setFileSize($nodeObject); + $this->setScanAll(); //debug option, put in a file attribute values - if(self::DEBUG_ON == 1) { - $debug = 'echo "' . $this->path . " " . $this->file_extension . " " . $this->extension_scan . " " . $this->scan_all . " " . $this->scan_diff_folder . " " . $this->scan_max_size . " " . $this->file_size . '" >> plugins/action.antivirus/debug'; - passthru($debug); - } - return ; - } + if (self::DEBUG_ON == 1) { + $debug = 'echo "' . $this->path . " " . $this->file_extension . " " . $this->extension_scan . " " . $this->scan_all . " " . $this->scan_diff_folder . " " . $this->scan_max_size . " " . $this->file_size . '" >> plugins/action.antivirus/debug'; + passthru($debug); + } + return ; + } /** * This function initializes the file path * @param $nodeObject */ - public function setPath($nodeObject){ - $realpath = $nodeObject->getRealFile(); - $realpath = realpath($realpath); - $this->path= $realpath; - return ; - } + public function setPath($nodeObject) + { + $realpath = $nodeObject->getRealFile(); + $realpath = realpath($realpath); + $this->path= $realpath; + return ; + } /** * This function initializes the file extension * @param $nodeObject */ - public function setFileExtension ($nodeObject) { - $realpath = $nodeObject->getRealFile(); - $realpath = realpath($realpath); - $realpath = str_replace(" ", "_",$realpath ); - $realpath = strrchr($realpath, DIRECTORY_SEPARATOR); - $this->file_extension=strrchr($realpath, '.'); - if($this->file_extension == ( "") ){$this->file_extension = ".no_ext";} - return ; - } + public function setFileExtension ($nodeObject) + { + $realpath = $nodeObject->getRealFile(); + $realpath = realpath($realpath); + $realpath = str_replace(" ", "_",$realpath ); + $realpath = strrchr($realpath, DIRECTORY_SEPARATOR); + $this->file_extension=strrchr($realpath, '.'); + if ($this->file_extension == ( "") ) {$this->file_extension = ".no_ext";} + return ; + } /** * This function initializes the extension list */ - public function setExtensionScan() { - $this->extension_scan = $this->getFilteredOption("EXT"); - return ; - } + public function setExtensionScan() + { + $this->extension_scan = $this->getFilteredOption("EXT"); + return ; + } /** * this function initializes attribute scan_all */ - public function setScanAll(){ - $extension = $this->getFilteredOption("EXT"); - if(substr($extension, 0, 2) == "*/"){ - $this->scan_all = true; - }else{ - $this->scan_all = false; - } - return ; - } + public function setScanAll() + { + $extension = $this->getFilteredOption("EXT"); + if (substr($extension, 0, 2) == "*/") { + $this->scan_all = true; + } else { + $this->scan_all = false; + } + return ; + } /** * this function initializes the trace folder */ - public function setScanDiffFolder () { - $this->scan_diff_folder = $this->getFilteredOption("PATH"); - return ; - } + public function setScanDiffFolder () + { + $this->scan_diff_folder = $this->getFilteredOption("PATH"); + return ; + } /** * this function initializes max size of the scanned file */ - public function setScanMaxSize () { - $this->scan_max_size = AJXP_Utils::convertBytes($this->getFilteredOption("SIZE")); - return ; - } + public function setScanMaxSize () + { + $this->scan_max_size = AJXP_Utils::convertBytes($this->getFilteredOption("SIZE")); + return ; + } /** * This function initializes the size of the file * @param AJXP_Node $nodeObject */ - public function setFileSize ($nodeObject) { - $realpath = $nodeObject->getRealFile(); - $realpath = realpath($realpath); - $this->file_size = filesize($realpath); - return ; - } - -} \ No newline at end of file + public function setFileSize ($nodeObject) + { + $realpath = $nodeObject->getRealFile(); + $realpath = realpath($realpath); + $this->file_size = filesize($realpath); + return ; + } + +} diff --git a/core/src/plugins/action.antivirus/manifest.xml b/core/src/plugins/action.antivirus/manifest.xml index 31c2c43ecb..925dfdff19 100644 --- a/core/src/plugins/action.antivirus/manifest.xml +++ b/core/src/plugins/action.antivirus/manifest.xml @@ -1,6 +1,6 @@ - + @@ -20,8 +20,8 @@ - - + + diff --git a/core/src/plugins/action.powerfs/class.PowerFSController.php b/core/src/plugins/action.powerfs/class.PowerFSController.php index 90d27b8a0b..6075820cc7 100644 --- a/core/src/plugins/action.powerfs/class.PowerFSController.php +++ b/core/src/plugins/action.powerfs/class.PowerFSController.php @@ -1,194 +1,195 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die('Access not allowed'); - -/** - * @package AjaXplorer_Plugins - * @subpackage Action - */ -class PowerFSController extends AJXP_Plugin -{ - - function switchAction($action, $httpVars, $fileVars){ - if(!isSet($this->actions[$action])) return; - $selection = new UserSelection(); - $dir = $httpVars["dir"] OR ""; - $dir = AJXP_Utils::securePath($dir); - if($dir == "/") $dir = ""; - $selection->initFromHttpVars($httpVars); - if(!$selection->isEmpty()){ - //$this->filterUserSelectionToHidden($selection->getFiles()); - } - $urlBase = "ajxp.fs://". ConfService::getRepository()->getId(); - $mess = ConfService::getMessages(); - switch ($action){ - - case "monitor_compression" : - - $percentFile = fsAccessWrapper::getRealFSReference($urlBase.$dir."/.zip_operation_".$httpVars["ope_id"]); - $percent = 0; - if(is_file($percentFile)){ - $percent = intval(file_get_contents($percentFile)); - } - if($percent < 100){ - AJXP_XMLWriter::header(); - AJXP_XMLWriter::triggerBgAction( - "monitor_compression", - $httpVars, - $mess["powerfs.1"]." ($percent%)", - true, - 1); - AJXP_XMLWriter::close(); - }else{ - @unlink($percentFile); - AJXP_XMLWriter::header(); - if($httpVars["on_end"] == "reload"){ - AJXP_XMLWriter::triggerBgAction("reload_node", array(), "powerfs.2", true, 2); - }else{ - $archiveName = $httpVars["archive_name"]; - $jsCode = " - $('download_form').action = window.ajxpServerAccessPath; - $('download_form').secure_token.value = window.Connexion.SECURE_TOKEN; - $('download_form').select('input').each(function(input){ - if(input.name!='secure_token') input.remove(); - }); - $('download_form').insert(new Element('input', {type:'hidden', name:'ope_id', value:'".$httpVars["ope_id"]."'})); - $('download_form').insert(new Element('input', {type:'hidden', name:'archive_name', value:'".$archiveName."'})); - $('download_form').insert(new Element('input', {type:'hidden', name:'get_action', value:'postcompress_download'})); - $('download_form').submit(); - $('download_form').get_action.value = 'download'; - "; - AJXP_XMLWriter::triggerBgJsAction($jsCode, "powerfs.3", true); - AJXP_XMLWriter::triggerBgAction("reload_node", array(), "powerfs.2", true, 2); - } - AJXP_XMLWriter::close(); - } - - break; - - case "postcompress_download": - - $archive = AJXP_Utils::getAjxpTmpDir()."/".$httpVars["ope_id"]."_".$httpVars["archive_name"]; - $fsDriver = AJXP_PluginsService::getInstance()->getUniqueActivePluginForType("access"); - if(is_file($archive)){ - register_shutdown_function("unlink", $archive); - $fsDriver->readFile($archive, "force-download", $httpVars["archive_name"], false, null, true); - }else{ - echo(""); - } - break; - - case "compress" : - case "precompress" : - - if(!ConfService::currentContextIsCommandLine() && ConfService::backgroundActionsSupported()){ - $opeId = substr(md5(time()),0,10); - $httpVars["ope_id"] = $opeId; - AJXP_Controller::applyActionInBackground(ConfService::getRepository()->getId(), $action, $httpVars); - AJXP_XMLWriter::header(); - $bgParameters = array( - "dir" => $dir, - "archive_name" => $httpVars["archive_name"], - "on_end" => (isSet($httpVars["on_end"])?$httpVars["on_end"]:"reload"), - "ope_id" => $opeId - ); - AJXP_XMLWriter::triggerBgAction( - "monitor_compression", - $bgParameters, - $mess["powerfs.1"]." (0%)", - true); - AJXP_XMLWriter::close(); - session_write_close(); - exit(); - } - - $rootDir = fsAccessWrapper::getRealFSReference($urlBase) . $dir; - $percentFile = $rootDir."/.zip_operation_".$httpVars["ope_id"]; - $compressLocally = ($action == "compress" ? true : false); - // List all files - $todo = array(); - $args = array(); - $replaceSearch = array($rootDir, "\\"); - $replaceReplace = array("", "/"); - foreach($selection->getFiles() as $selectionFile){ - $args[] = '"'.substr($selectionFile, strlen($dir)+($dir=="/"?0:1)).'"'; - $selectionFile = fsAccessWrapper::getRealFSReference($urlBase.$selectionFile); - $todo[] = ltrim(str_replace($replaceSearch, $replaceReplace, $selectionFile), "/"); - if(is_dir($selectionFile)){ - $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($selectionFile), RecursiveIteratorIterator::SELF_FIRST); - foreach($objects as $name => $object){ - $todo[] = str_replace($replaceSearch, $replaceReplace, $name); - } - } - } - $cmdSeparator = ((PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows")? "&" : ";"); - $archiveName = $httpVars["archive_name"]; - if(!$compressLocally){ - $archiveName = AJXP_Utils::getAjxpTmpDir()."/".$httpVars["ope_id"]."_".$archiveName; - } - chdir($rootDir); - $cmd = "zip -r ".escapeshellarg($archiveName)." ".implode(" ", $args); - $fsDriver = AJXP_PluginsService::getInstance()->getUniqueActivePluginForType("access"); - $c = $fsDriver->getConfigs(); - if(!isSet($c["SHOW_HIDDEN_FILES"]) || $c["SHOW_HIDDEN_FILES"] == false){ - $cmd .= " -x .\*"; - } - $cmd .= " ".$cmdSeparator." echo ZIP_FINISHED"; - $proc = popen($cmd, "r"); - $toks = array(); - $handled = array(); - $finishedEchoed = false; - while (!feof($proc)) { - set_time_limit (20); - $results = fgets($proc, 256); - if (strlen($results) == 0) { - } else { - $tok = strtok($results, "\n"); - while ($tok !== false) { - $toks[] = $tok; - if($tok == "ZIP_FINISHED") { - $finishedEchoed = true; - }else{ - $test = preg_match('/(\w+): (.*) \(([^\(]+)\) \(([^\(]+)\)/', $tok, $matches); - if($test !== false){ - $handled[] = $matches[2]; - } - } - $tok = strtok("\n"); - } - if($finishedEchoed) $percent = 100; - else $percent = min( round(count($handled) / count($todo) * 100), 100); - file_put_contents($percentFile, $percent); - } - // avoid a busy wait - if($percent < 100) usleep(1); - } - pclose($proc); - file_put_contents($percentFile, 100); - - break; - default: - break; - } - - } -} + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die('Access not allowed'); + +/** + * @package AjaXplorer_Plugins + * @subpackage Action + */ +class PowerFSController extends AJXP_Plugin +{ + + public function switchAction($action, $httpVars, $fileVars) + { + if(!isSet($this->actions[$action])) return; + $selection = new UserSelection(); + $dir = $httpVars["dir"] OR ""; + $dir = AJXP_Utils::securePath($dir); + if($dir == "/") $dir = ""; + $selection->initFromHttpVars($httpVars); + if (!$selection->isEmpty()) { + //$this->filterUserSelectionToHidden($selection->getFiles()); + } + $urlBase = "ajxp.fs://". ConfService::getRepository()->getId(); + $mess = ConfService::getMessages(); + switch ($action) { + + case "monitor_compression" : + + $percentFile = fsAccessWrapper::getRealFSReference($urlBase.$dir."/.zip_operation_".$httpVars["ope_id"]); + $percent = 0; + if (is_file($percentFile)) { + $percent = intval(file_get_contents($percentFile)); + } + if ($percent < 100) { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::triggerBgAction( + "monitor_compression", + $httpVars, + $mess["powerfs.1"]." ($percent%)", + true, + 1); + AJXP_XMLWriter::close(); + } else { + @unlink($percentFile); + AJXP_XMLWriter::header(); + if ($httpVars["on_end"] == "reload") { + AJXP_XMLWriter::triggerBgAction("reload_node", array(), "powerfs.2", true, 2); + } else { + $archiveName = $httpVars["archive_name"]; + $jsCode = " + $('download_form').action = window.ajxpServerAccessPath; + $('download_form').secure_token.value = window.Connexion.SECURE_TOKEN; + $('download_form').select('input').each(function(input){ + if(input.name!='secure_token') input.remove(); + }); + $('download_form').insert(new Element('input', {type:'hidden', name:'ope_id', value:'".$httpVars["ope_id"]."'})); + $('download_form').insert(new Element('input', {type:'hidden', name:'archive_name', value:'".$archiveName."'})); + $('download_form').insert(new Element('input', {type:'hidden', name:'get_action', value:'postcompress_download'})); + $('download_form').submit(); + $('download_form').get_action.value = 'download'; + "; + AJXP_XMLWriter::triggerBgJsAction($jsCode, "powerfs.3", true); + AJXP_XMLWriter::triggerBgAction("reload_node", array(), "powerfs.2", true, 2); + } + AJXP_XMLWriter::close(); + } + + break; + + case "postcompress_download": + + $archive = AJXP_Utils::getAjxpTmpDir()."/".$httpVars["ope_id"]."_".$httpVars["archive_name"]; + $fsDriver = AJXP_PluginsService::getInstance()->getUniqueActivePluginForType("access"); + if (is_file($archive)) { + register_shutdown_function("unlink", $archive); + $fsDriver->readFile($archive, "force-download", $httpVars["archive_name"], false, null, true); + } else { + echo(""); + } + break; + + case "compress" : + case "precompress" : + + if (!ConfService::currentContextIsCommandLine() && ConfService::backgroundActionsSupported()) { + $opeId = substr(md5(time()),0,10); + $httpVars["ope_id"] = $opeId; + AJXP_Controller::applyActionInBackground(ConfService::getRepository()->getId(), $action, $httpVars); + AJXP_XMLWriter::header(); + $bgParameters = array( + "dir" => $dir, + "archive_name" => $httpVars["archive_name"], + "on_end" => (isSet($httpVars["on_end"])?$httpVars["on_end"]:"reload"), + "ope_id" => $opeId + ); + AJXP_XMLWriter::triggerBgAction( + "monitor_compression", + $bgParameters, + $mess["powerfs.1"]." (0%)", + true); + AJXP_XMLWriter::close(); + session_write_close(); + exit(); + } + + $rootDir = fsAccessWrapper::getRealFSReference($urlBase) . $dir; + $percentFile = $rootDir."/.zip_operation_".$httpVars["ope_id"]; + $compressLocally = ($action == "compress" ? true : false); + // List all files + $todo = array(); + $args = array(); + $replaceSearch = array($rootDir, "\\"); + $replaceReplace = array("", "/"); + foreach ($selection->getFiles() as $selectionFile) { + $args[] = '"'.substr($selectionFile, strlen($dir)+($dir=="/"?0:1)).'"'; + $selectionFile = fsAccessWrapper::getRealFSReference($urlBase.$selectionFile); + $todo[] = ltrim(str_replace($replaceSearch, $replaceReplace, $selectionFile), "/"); + if (is_dir($selectionFile)) { + $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($selectionFile), RecursiveIteratorIterator::SELF_FIRST); + foreach ($objects as $name => $object) { + $todo[] = str_replace($replaceSearch, $replaceReplace, $name); + } + } + } + $cmdSeparator = ((PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows")? "&" : ";"); + $archiveName = $httpVars["archive_name"]; + if (!$compressLocally) { + $archiveName = AJXP_Utils::getAjxpTmpDir()."/".$httpVars["ope_id"]."_".$archiveName; + } + chdir($rootDir); + $cmd = "zip -r ".escapeshellarg($archiveName)." ".implode(" ", $args); + $fsDriver = AJXP_PluginsService::getInstance()->getUniqueActivePluginForType("access"); + $c = $fsDriver->getConfigs(); + if (!isSet($c["SHOW_HIDDEN_FILES"]) || $c["SHOW_HIDDEN_FILES"] == false) { + $cmd .= " -x .\*"; + } + $cmd .= " ".$cmdSeparator." echo ZIP_FINISHED"; + $proc = popen($cmd, "r"); + $toks = array(); + $handled = array(); + $finishedEchoed = false; + while (!feof($proc)) { + set_time_limit (20); + $results = fgets($proc, 256); + if (strlen($results) == 0) { + } else { + $tok = strtok($results, "\n"); + while ($tok !== false) { + $toks[] = $tok; + if ($tok == "ZIP_FINISHED") { + $finishedEchoed = true; + } else { + $test = preg_match('/(\w+): (.*) \(([^\(]+)\) \(([^\(]+)\)/', $tok, $matches); + if ($test !== false) { + $handled[] = $matches[2]; + } + } + $tok = strtok("\n"); + } + if($finishedEchoed) $percent = 100; + else $percent = min( round(count($handled) / count($todo) * 100), 100); + file_put_contents($percentFile, $percent); + } + // avoid a busy wait + if($percent < 100) usleep(1); + } + pclose($proc); + file_put_contents($percentFile, 100); + + break; + default: + break; + } + + } +} diff --git a/core/src/plugins/action.powerfs/i18n/conf/en.php b/core/src/plugins/action.powerfs/i18n/conf/en.php index 94786e3087..08d167c94d 100644 --- a/core/src/plugins/action.powerfs/i18n/conf/en.php +++ b/core/src/plugins/action.powerfs/i18n/conf/en.php @@ -1,27 +1,25 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess = array( - // will be replaced by the application title - "Power FS" => "Power FS", - "This set of extensions assume that you have an administration access to your server: ability to tweak the webserver and the php configuration, ability to access the command line, etc." => "This set of extensions assume that you have an administration access to your server: ability to tweak the webserver and the php configuration, ability to access the command line, etc." -); - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess = array( + // will be replaced by the application title + "Power FS" => "Power FS", + "This set of extensions assume that you have an administration access to your server: ability to tweak the webserver and the php configuration, ability to access the command line, etc." => "This set of extensions assume that you have an administration access to your server: ability to tweak the webserver and the php configuration, ability to access the command line, etc." +); diff --git a/core/src/plugins/action.powerfs/i18n/conf/fr.php b/core/src/plugins/action.powerfs/i18n/conf/fr.php index 3e73c8cf9c..16c9e97488 100644 --- a/core/src/plugins/action.powerfs/i18n/conf/fr.php +++ b/core/src/plugins/action.powerfs/i18n/conf/fr.php @@ -1,27 +1,25 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess = array( - // will be replaced by the application title - "Power FS" => "Power FS", - "This set of extensions assume that you have an administration access to your server: ability to tweak the webserver and the php configuration, ability to access the command line, etc." => "Ces extensions ne sont utiles que si vous avez un accès étendu au serveur : configs php et webserver, accès ligne de commande, etc" -); - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess = array( + // will be replaced by the application title + "Power FS" => "Power FS", + "This set of extensions assume that you have an administration access to your server: ability to tweak the webserver and the php configuration, ability to access the command line, etc." => "Ces extensions ne sont utiles que si vous avez un accès étendu au serveur : configs php et webserver, accès ligne de commande, etc" +); diff --git a/core/src/plugins/action.powerfs/i18n/conf/pt.php b/core/src/plugins/action.powerfs/i18n/conf/pt.php index a114aa3a06..cfed513ec6 100644 --- a/core/src/plugins/action.powerfs/i18n/conf/pt.php +++ b/core/src/plugins/action.powerfs/i18n/conf/pt.php @@ -23,5 +23,3 @@ "Power FS" => "Power FS", "This set of extensions assume that you have an administration access to your server: ability to tweak the webserver and the php configuration, ability to access the command line, etc." => "Este conjunto de extensões assume que existe um administrador com acesso ao servidor com a habilidade de fazer alterações ao mesmo, configuração PHP, linha de comandos, etc." ); - -?> \ No newline at end of file diff --git a/core/src/plugins/action.powerfs/i18n/en.php b/core/src/plugins/action.powerfs/i18n/en.php index cb2e61f19f..9f396e0c9b 100644 --- a/core/src/plugins/action.powerfs/i18n/en.php +++ b/core/src/plugins/action.powerfs/i18n/en.php @@ -1,28 +1,26 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess = array( - // will be replaced by the application title - "1" => "Creating archive, please wait", - "2" => "Reload current folder", - "3" => "Archive download should start automatically" -); - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess = array( + // will be replaced by the application title + "1" => "Creating archive, please wait", + "2" => "Reload current folder", + "3" => "Archive download should start automatically" +); diff --git a/core/src/plugins/action.powerfs/i18n/fr.php b/core/src/plugins/action.powerfs/i18n/fr.php index 0555c6dfcb..3f9d45f23a 100644 --- a/core/src/plugins/action.powerfs/i18n/fr.php +++ b/core/src/plugins/action.powerfs/i18n/fr.php @@ -1,28 +1,26 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess = array( - // will be replaced by the application title - "1" => "Création de l'archive, veuillez patienter", - "2" => "Rechargement du répertoire", - "3" => "Le téléchargement de l'archive devrait démarrer automatiquement" -); - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess = array( + // will be replaced by the application title + "1" => "Création de l'archive, veuillez patienter", + "2" => "Rechargement du répertoire", + "3" => "Le téléchargement de l'archive devrait démarrer automatiquement" +); diff --git a/core/src/plugins/action.powerfs/i18n/pt.php b/core/src/plugins/action.powerfs/i18n/pt.php index 545fcd1580..eb6e71d75d 100644 --- a/core/src/plugins/action.powerfs/i18n/pt.php +++ b/core/src/plugins/action.powerfs/i18n/pt.php @@ -24,5 +24,3 @@ "2" => "Actualize a pasta actual", "3" => "A Transferência do ficheiro deverá começar automaticamente" ); - -?> \ No newline at end of file diff --git a/core/src/plugins/action.powerfs/manifest.xml b/core/src/plugins/action.powerfs/manifest.xml index 99f254fbc6..7a8d166144 100644 --- a/core/src/plugins/action.powerfs/manifest.xml +++ b/core/src/plugins/action.powerfs/manifest.xml @@ -1,117 +1,117 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/src/plugins/action.scheduler/class.AjxpScheduler.php b/core/src/plugins/action.scheduler/class.AjxpScheduler.php index a08db491dd..f3ce8de3ec 100644 --- a/core/src/plugins/action.scheduler/class.AjxpScheduler.php +++ b/core/src/plugins/action.scheduler/class.AjxpScheduler.php @@ -1,658 +1,656 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * @package AjaXplorer_Plugins - * @subpackage Action - */ -class AjxpScheduler extends AJXP_Plugin{ - - var $db; - - function __construct($id, $baseDir){ - parent::__construct($id, $baseDir); - - } - - public function init($options){ - parent::init($options); - $u = AuthService::getLoggedUser(); - if($u == null) return; - if($u->getGroupPath() != "/"){ - $this->enabled = false; - } - } - - function getDbFile(){ - if(!isSet($this->db)){ - $this->db = $this->getPluginWorkDir(true). "/calendar.json" ; - } - return $this->db; - } - - function unserialize($serialized){ - parent::unserialize($serialized); - } - - - function performChecks(){ - if(!ConfService::backgroundActionsSupported()) { - throw new Exception("The command line must be supported. See 'AjaXplorer Core Options'."); - } - if(!is_dir(dirname($this->getDbFile()))) { - throw new Exception("Could not create the db folder!"); - } - } - - function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($contribNode->nodeName != "actions") return; - $actionXpath=new DOMXPath($contribNode->ownerDocument); - $paramList = $actionXpath->query('action[@name="scheduler_addTask"]/processing/standardFormDefinition/param[@name="repository_id"]', $contribNode); - if(!$paramList->length) return; - $paramNode = $paramList->item(0); - $sVals = array(); - $repos = ConfService::getRepositoriesList(); - foreach($repos as $repoId => $repoObject){ - $sVals[] = $repoId."|". AJXP_Utils::xmlEntities($repoObject->getDisplay()); - } - $sVals[] = "*|All Repositories"; - $paramNode->attributes->getNamedItem("choices")->nodeValue = implode(",", $sVals); - - if(!AuthService::usersEnabled() || AuthService::getLoggedUser() == null) return; - $paramList = $actionXpath->query('action[@name="scheduler_addTask"]/processing/standardFormDefinition/param[@name="user_id"]', $contribNode); - if(!$paramList->length) return; - $paramNode = $paramList->item(0); - $paramNode->attributes->getNamedItem("default")->nodeValue = AuthService::getLoggedUser()->getId(); - } - - function getTaskById($tId){ - $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); - foreach($tasks as $task){ - if( !empty($task["task_id"]) && $task["task_id"] == $tId) { - return $task; - } - } - throw new Exception("Cannot find task"); - } - - function setTaskStatus($taskId, $status, $preserveModeDate =false){ - $statusFile = AJXP_CACHE_DIR."/cmd_outputs/task_".$taskId.".status"; - if($preserveModeDate) $mtime = filemtime($statusFile); - file_put_contents($statusFile, $status); - if($preserveModeDate) @touch($statusFile, $mtime); - } - - function getTaskStatus($taskId){ - $statusFile = AJXP_CACHE_DIR."/cmd_outputs/task_".$taskId.".status"; - if(file_exists($statusFile)){ - $c = explode(":", file_get_contents($statusFile)); - if($c[0] == "RUNNING" && isSet($c[1]) && is_numeric($c[1])){ - $process = new UnixProcess(); - $process->setPid(intval($c[1])); - $s = $process->status(); - if($s === false){ - // Process was probably killed! - $this->setTaskStatus($taskId, "KILLED", true); - return array("KILLED"); - } - } - return $c; - } - return false; - } - - function countCurrentlyRunning(){ - $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); - $count = 0; - foreach($tasks as $task){ - $s = $this->getTaskStatus($task["task_id"]); - if($s !== false && $s[0] == "RUNNING"){ - $count++; - } - } - return $count; - } - - function runTask($taskId, $status = null, &$currentlyRunning = -1, $forceStart=false){ - $data = $this->getTaskById($taskId); - $mess = ConfService::getMessages(); - $timeArray = $this->getTimeArray($data["schedule"]); - - // TODO : Set MasterInterval as config, or detect last execution? - $masterInterval = 1; - $maximumProcesses = 2; - - $now = time(); - $lastExec = time()-60*$masterInterval; - $res = $this->getNextExecutionTimeForScript($lastExec, $timeArray); - $test = date("Y-m-d H:i", $lastExec). " -- ".date("Y-m-d H:i", $res)." -- ".date("Y-m-d H:i", $now); - - $alreadyRunning = false; - $queued = false; - if($status == null) $status = $this->getTaskStatus($taskId); - if($status !== false){ - if($status[0] == "RUNNING"){ - $alreadyRunning = true; - }else if(in_array("QUEUED", $status)){ - $queued = true; // Run now ! - } - } - if( $res >= $lastExec && $res < $now && !$alreadyRunning && $currentlyRunning >= $maximumProcesses){ - $this->setTaskStatus($taskId, "QUEUED", true); - $alreadyRunning = true; - $queued = false; - } - if( ( $res >= $lastExec && $res < $now && !$alreadyRunning ) || $queued || $forceStart){ - if($data["user_id"] == "*"){ - $data["user_id"] = implode(",", array_keys(AuthService::listUsers())); - }else if($data["user_id"] == "*/*"){ - // Recurse all groups and put them into a queue file - $allUsers = array(); - $this->gatherUsers($allUsers, "/"); - $tmpQueue = AJXP_CACHE_DIR."/cmd_outputs/queue_".$taskId.""; - file_put_contents($tmpQueue, implode(",", $allUsers)); - $data["user_id"] = "queue:".$tmpQueue; - } - if($data["repository_id"] == "*"){ - $data["repository_id"] = implode(",", array_keys(ConfService::getRepositoriesList())); - } - $process = AJXP_Controller::applyActionInBackground( - $data["repository_id"], - $data["action_name"], - $data["PARAMS"], - $data["user_id"], - AJXP_CACHE_DIR."/cmd_outputs/task_".$taskId.".status"); - if($process != null && is_a($process, "UnixProcess")){ - $this->setTaskStatus($taskId, "RUNNING:".$process->getPid()); - }else{ - $this->setTaskStatus($taskId, "RUNNING"); - } - $currentlyRunning ++; - return true; - } - return false; - } - - protected function gatherUsers(&$users, $startGroup="/"){ - $u = AuthService::listUsers($startGroup); - $users = array_merge($users, array_keys($u)); - $g = AuthService::listChildrenGroups($startGroup); - if(count($g)){ - foreach($g as $gName => $gLabel){ - $this->gatherUsers($users, $startGroup.$gName); - } - } - } - - - function sortTasksByPriorityStatus($data1, $data2){ - if(is_array($data1["status"]) && in_array("QUEUED", $data1["status"])) return -1; - if(is_array($data2["status"]) && in_array("QUEUED", $data2["status"])) return 1; - return 0; - } - - function switchAction($action, $httpVars, $postProcessData){ - - switch($action){ - - //------------------------------------ - // SHARING FILE OR FOLDER - //------------------------------------ - case "scheduler_runAll": - - $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); - $message = ""; - $startRunning = $this->countCurrentlyRunning(); - $statuses = array(); - foreach($tasks as $index => $task){ - $tasks[$index]["status"] = $this->getTaskStatus($task["task_id"]); - } - usort($tasks, array($this, "sortTasksByPriorityStatus")); - foreach($tasks as $task){ - if(isSet($task["task_id"])){ - $res = $this->runTask($task["task_id"], $task["status"], $startRunning); - if($res){ - $message .= "Running ".$task["label"]." \n "; - } - } - } - if(empty($message)) $message = "Nothing to do"; - - if(ConfService::currentContextIsCommandLine()){ - print(date("Y-m-d H:i:s")."\t".$message."\n"); - }else{ - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($message, null); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - } - - break; - - case "scheduler_runTask": - - $err = -1; - $this->runTask($httpVars["task_id"], null, $err, true); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - - break; - - case "scheduler_generateCronExpression": - - $phpCmd = ConfService::getCoreConf("CLI_PHP"); - $rootInstall = AJXP_INSTALL_PATH.DIRECTORY_SEPARATOR."cmd.php" ; - $logFile = AJXP_CACHE_DIR.DIRECTORY_SEPARATOR."cmd_outputs".DIRECTORY_SEPARATOR."cron_commands.log"; - $cronTiming = "*/5 * * * *"; - HTMLWriter::charsetHeader("text/plain", "UTF-8"); - print "$cronTiming $phpCmd $rootInstall -r=ajxp_conf -u=".AuthService::getLoggedUser()->getId()." -p=YOUR_PASSWORD_HERE -a=scheduler_runAll >> $logFile"; - - break; - - default: - break; - } - - } - - function placeConfigNode(&$configTree){ - $mess = ConfService::getMessages(); - if(isSet($configTree["admin"])){ - $configTree["admin"]["CHILDREN"]["scheduler"] = array( - "LABEL" => $mess["action.scheduler.18"], - "DESCRIPTION" => $mess["action.scheduler.22"], - "ICON" => "scheduler/ICON_SIZE/player_time.png", - "LIST" => array($this, "listTasks")); - } - } - - function listTasks($action, $httpVars, $postProcessData){ - - $mess =ConfService::getMessages(); - AJXP_XMLWriter::renderHeaderNode("/admin/scheduler", "Scheduler", false, array("icon" => "scheduler/ICON_SIZE/player_time.png")); - AJXP_XMLWriter::sendFilesListComponentConfig(' - - - - - - - - - '); - $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); - foreach ($tasks as $task){ - - $timeArray = $this->getTimeArray($task["schedule"]); - $res = $this->getNextExecutionTimeForScript(time(), $timeArray); - $task["NEXT_EXECUTION"] = date($mess["date_format"], $res); - $task["PARAMS"] = implode(", ", $task["PARAMS"]); - $task["icon"] = "scheduler/ICON_SIZE/task.png"; - $task["ajxp_mime"] = "scheduler_task"; - $sFile = AJXP_CACHE_DIR."/cmd_outputs/task_".$task["task_id"].".status"; - if(is_file($sFile)){ - $s = $this->getTaskStatus($task["task_id"]); - $task["STATUS"] = implode(":", $s); - $task["LAST_EXECUTION"] = date($mess["date_format"], filemtime($sFile)); - }else{ - $task["STATUS"] = "n/a"; - $task["LAST_EXECUTION"] = "n/a"; - } - - AJXP_XMLWriter::renderNode("/admin/scheduler/".$task["task_id"], - (isSet($task["label"])?$task["label"]:"Action ".$task["action_name"]), - true, - $task - ); - } - AJXP_XMLWriter::close(); - - } - - function getTimeArray($schedule){ - $parts = explode(" ", $schedule); - if(count($parts)!=5) throw new Exception("Invalid Schedule Format ($schedule)"); - $timeArray['minutes'] = $parts[0]; - $timeArray['hours'] = $parts[1]; - $timeArray['days'] = $parts[2]; - $timeArray['dayWeek'] = $parts[3]; - $timeArray['months'] = $parts[4]; - return $timeArray; - } - - - public function addOrUpdateTask($taskId, $label, $schedule, $actionName, $repositoryIds, $userId, $paramsArray){ - $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); - if(isSet($taskId)){ - foreach($tasks as $index => $task){ - if($task["task_id"] == $taskId){ - $data = $task; - $theIndex = $index; - } - } - } - if(!isSet($theIndex)){ - $data = array(); - $data["task_id"] = substr(md5(time()), 0, 16); - } - $data["label"] = $label; - $data["schedule"] = $schedule; - $data["action_name"] = $actionName; - $data["repository_id"] = $repositoryIds; - $data["user_id"] = $userId; - $data["PARAMS"] = $paramsArray; - if(isSet($theIndex)) $tasks[$theIndex] = $data; - else $tasks[] = $data; - AJXP_Utils::saveSerialFile($this->getDbFile(), $tasks, true, false, "json"); - - } - - public function removeTask($taskId){ - $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); - foreach($tasks as $index => $task){ - if($task["task_id"] == $taskId){ - unset($tasks[$index]); - break; - } - } - AJXP_Utils::saveSerialFile($this->getDbFile(), $tasks, true, false, "json"); - } - - function handleTasks($action, $httpVars, $fileVars){ - - $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); - switch ($action){ - case "scheduler_addTask": - if(isSet($httpVars["task_id"])){ - foreach($tasks as $index => $task){ - if($task["task_id"] == $httpVars["task_id"]){ - $data = $task; - $theIndex = $index; - } - } - } - if(!isSet($theIndex)){ - $data = array(); - $data["task_id"] = substr(md5(time()), 0, 16); - } - $data["label"] = $httpVars["label"]; - $data["schedule"] = $httpVars["schedule"]; - $data["action_name"] = $httpVars["action_name"]; - $data["repository_id"] =$httpVars["repository_id"]; - $i = 1; - while(array_key_exists("repository_id_".$i, $httpVars)) { - $data["repository_id"].=",".$httpVars["repository_id_".$i]; - $i++; - } - $data["user_id"] = $httpVars["user_id"]; - $data["PARAMS"] = array(); - if(!empty($httpVars["param_name"]) && !empty($httpVars["param_value"])){ - $data["PARAMS"][$httpVars["param_name"]] = $httpVars["param_value"]; - } - foreach($httpVars as $key => $value){ - if(preg_match('/^param_name_/', $key)) { - $paramIndex = str_replace("param_name_", "", $key); - if(preg_match('/ajxptype/', $paramIndex)) continue; - if(preg_match('/replication/', $paramIndex)) continue; - if(isSet($httpVars["param_value_".$paramIndex])){ - $data["PARAMS"][$value] = $httpVars["param_value_".$paramIndex]; - } - } - } - if(isSet($theIndex)) $tasks[$theIndex] = $data; - else $tasks[] = $data; - AJXP_Utils::saveSerialFile($this->getDbFile(), $tasks, true, false, "json"); - - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage("Successfully added/edited task", null); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - - break; - - case "scheduler_removeTask" : - - $this->removeTask($httpVars["task_id"]); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage("Successfully removed task", null); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::close(); - - break; - - case "scheduler_loadTask": - - $found = false; - foreach($tasks as $task){ - if($task["task_id"] == $httpVars["task_id"]){ - $index = 0; - $found = true; - foreach($task["PARAMS"] as $pName => $pValue){ - if($index == 0){ - $task["param_name"] = $pName; - $task["param_value"] = $pValue; - }else{ - $task["param_name_".$index] = $pName; - $task["param_value_".$index] = $pValue; - } - $index ++; - } - unset($task["PARAMS"]); - if(strpos($task["repository_id"], ",") !== false){ - $ids = explode(",", $task["repository_id"]); - $task["repository_id"] = $ids[0]; - for($i = 1; $igetId()); - print('STARTING FAKE TASK'); - sleep($minutes * 60); - print('ENDIND FAKE TASK'); - } - - function getNextExecutionTimeForScript($referenceTime, $timeArray) - { - $a=null; $m=null; $j=null; $h=null; $min=null; - - $aNow = date("Y", $referenceTime); - $mNow = date("m", $referenceTime); - $jNow = date("d", $referenceTime); - $hNow = date("H", $referenceTime); - $minNow = date("i", $referenceTime)+1; - - $a = $aNow; - $m = $mNow - 1; - - while($this->nextMonth($timeArray, $a, $m, $j, $h, $min) != -1) /* on parcourt tous les mois de l'intervalle demandé */ - { /* jusqu'à trouver une réponse convanable */ - if ($m != $mNow || $a != $aNow) /*si ce n'est pas ce mois ci */ - { - $j = 0; - if ($this->nextDay($timeArray, $a, $m, $j, $h, $min) == -1) /* le premier jour trouvé sera le bon. */ - { /* -1 si l'intersection entre jour de semaine */ - /* et jour du mois est nulle */ - continue; /* ...auquel cas on passe au mois suivant */ - }else{ /* s'il y a un jour */ - $h=-1; - $this->nextHour($timeArray, $a, $m, $j, $h, $min); /* la première heure et la première minute conviendront*/ - $min = -1; - $this->nextMinute($timeArray, $a, $m, $j, $h, $min); - return mktime($h, $min, 0, $m, $j, $a); - } - }else{ /* c'est ce mois ci */ - $j = $jNow-1; - while($this->nextDay($timeArray, $a, $m, $j, $h, $min) != -1) /* on cherche un jour à partir d'aujourd'hui compris */ - { - if ($j > $jNow) /* si ce n'est pas aujourd'hui */ - { /* on prend les premiers résultats */ - $h=-1; - $this->nextHour($timeArray, $a, $m, $j, $h, $min); - $min = -1; - $this->nextMinute($timeArray, $a, $m, $j, $h, $min); - return mktime($h, $min, 0, $m, $j, $a); - } - if ($j == $jNow) /* même algo pour les heures et les minutes */ - { - $h = $hNow - 1; - while($this->nextHour($timeArray, $a, $m, $j, $h, $min) != -1) - { - if ($h > $hNow) - { - $min = -1; - $this->nextMinute($timeArray, $a, $m, $j, $h, $min); - return mktime($h, $min, 0, $m, $j, $a); - } - if ($h == $hNow) - { - $min = $minNow - 1; - while($this->nextMinute($timeArray, $a, $m, $j, $h, $min) != -1) - { - if ($min > $minNow) { return mktime($h, $min, 0, $m, $j, $a); } - - /* si c'est maintenant, on l'éxécute directement */ - if ($min == $minNow) - { - return $referenceTime; - } - } - } - } - } - } - } - } - } - - function parseFormat($min, $max, $intervalle) - { - $retour = Array(); - - if ($intervalle == '*') - { - for($i=$min; $i<=$max; $i++) $retour[$i] = TRUE; - return $retour; - }else{ - for($i=$min; $i<=$max; $i++) $retour[$i] = FALSE; - } - if($intervalle[0] == "/"){ - // Transform Repeat pattern into range - $repeat = intval(ltrim($intervalle, "/")); - $values= array(); - for($i=$min;$i<=$max;$i++){ - if(($i % $repeat) == 0) $values[] = $i; - } - $intervalle = implode(",", $values); - } - - $intervalle = array_map("trim", explode(',', $intervalle)); - foreach ($intervalle as $val) - { - $val = array_map("trim", explode('-', $val)); - if (isset($val[0]) && isset($val[1])) - { - if ($val[0] <= $val[1]) - { - for($i=$val[0]; $i<=$val[1]; $i++) $retour[$i] = TRUE; /* ex : 9-12 = 9, 10, 11, 12 */ - }else{ - for($i=$val[0]; $i<=$max; $i++) $retour[$i] = TRUE; /* ex : 10-4 = 10, 11, 12... */ - for($i=$min; $i<=$val[1]; $i++) $retour[$i] = TRUE; /* ...et 1, 2, 3, 4 */ - } - }else{ - $retour[$val[0]] = TRUE; - } - } - return $retour; - } - - function nextMonth($timeArray, &$a, &$m, &$j, &$h, &$min) - { - $valeurs = $this->parseFormat(1, 12, $timeArray['months']); - do - { - $m++; - if ($m == 13) - { - $m=1; - $a++; /*si on a fait le tour, on réessaye l'année suivante */ - } - }while($valeurs[$m] != TRUE); - } - function nextDay($timeArray, &$a, &$m, &$j, &$h, &$min) - { - $valeurs = $this->parseFormat(1, 31, $timeArray['days']); - $valeurSemaine = $this->parseFormat(0, 6, $timeArray['dayWeek']); - - do - { - $j++; - - /* si $j est égal au nombre de jours du mois + 1 */ - if ($j == date('t', mktime(0, 0, 0, $m, 1, $a))+1) { return -1; } - - $js = date('w', mktime(0, 0, 0, $m, $j, $a)); - }while($valeurs[$j] != TRUE || $valeurSemaine[$js] != TRUE); - } - function nextHour($timeArray, &$a, &$m, &$j, &$h, &$min) - { - $valeurs = $this->parseFormat(0, 23, $timeArray['hours']); - - do - { - $h++; - if ($h == 24) { return -1; } - }while($valeurs[$h] != TRUE); - } - - function nextMinute($timeArray, &$a, &$m, &$j, &$h, &$min) - { - $valeurs = $this->parseFormat(0, 59, $timeArray['minutes']); - - do - { - $min++; - if ($min == 60) { return -1; } - }while($valeurs[$min] != TRUE); - } -} \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * @package AjaXplorer_Plugins + * @subpackage Action + */ +class AjxpScheduler extends AJXP_Plugin +{ + public $db; + + public function __construct($id, $baseDir) + { + parent::__construct($id, $baseDir); + + } + + public function init($options) + { + parent::init($options); + $u = AuthService::getLoggedUser(); + if($u == null) return; + if ($u->getGroupPath() != "/") { + $this->enabled = false; + } + } + + public function getDbFile() + { + if (!isSet($this->db)) { + $this->db = $this->getPluginWorkDir(true). "/calendar.json" ; + } + return $this->db; + } + + public function unserialize($serialized) + { + parent::unserialize($serialized); + } + + + public function performChecks() + { + if (!ConfService::backgroundActionsSupported()) { + throw new Exception("The command line must be supported. See 'AjaXplorer Core Options'."); + } + if (!is_dir(dirname($this->getDbFile()))) { + throw new Exception("Could not create the db folder!"); + } + } + + public function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if($contribNode->nodeName != "actions") return; + $actionXpath=new DOMXPath($contribNode->ownerDocument); + $paramList = $actionXpath->query('action[@name="scheduler_addTask"]/processing/standardFormDefinition/param[@name="repository_id"]', $contribNode); + if(!$paramList->length) return; + $paramNode = $paramList->item(0); + $sVals = array(); + $repos = ConfService::getRepositoriesList(); + foreach ($repos as $repoId => $repoObject) { + $sVals[] = $repoId."|". AJXP_Utils::xmlEntities($repoObject->getDisplay()); + } + $sVals[] = "*|All Repositories"; + $paramNode->attributes->getNamedItem("choices")->nodeValue = implode(",", $sVals); + + if(!AuthService::usersEnabled() || AuthService::getLoggedUser() == null) return; + $paramList = $actionXpath->query('action[@name="scheduler_addTask"]/processing/standardFormDefinition/param[@name="user_id"]', $contribNode); + if(!$paramList->length) return; + $paramNode = $paramList->item(0); + $paramNode->attributes->getNamedItem("default")->nodeValue = AuthService::getLoggedUser()->getId(); + } + + public function getTaskById($tId) + { + $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); + foreach ($tasks as $task) { + if ( !empty($task["task_id"]) && $task["task_id"] == $tId) { + return $task; + } + } + throw new Exception("Cannot find task"); + } + + public function setTaskStatus($taskId, $status, $preserveModeDate =false) + { + $statusFile = AJXP_CACHE_DIR."/cmd_outputs/task_".$taskId.".status"; + if($preserveModeDate) $mtime = filemtime($statusFile); + file_put_contents($statusFile, $status); + if($preserveModeDate) @touch($statusFile, $mtime); + } + + public function getTaskStatus($taskId) + { + $statusFile = AJXP_CACHE_DIR."/cmd_outputs/task_".$taskId.".status"; + if (file_exists($statusFile)) { + $c = explode(":", file_get_contents($statusFile)); + if ($c[0] == "RUNNING" && isSet($c[1]) && is_numeric($c[1])) { + $process = new UnixProcess(); + $process->setPid(intval($c[1])); + $s = $process->status(); + if ($s === false) { + // Process was probably killed! + $this->setTaskStatus($taskId, "KILLED", true); + return array("KILLED"); + } + } + return $c; + } + return false; + } + + public function countCurrentlyRunning() + { + $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); + $count = 0; + foreach ($tasks as $task) { + $s = $this->getTaskStatus($task["task_id"]); + if ($s !== false && $s[0] == "RUNNING") { + $count++; + } + } + return $count; + } + + public function runTask($taskId, $status = null, &$currentlyRunning = -1, $forceStart=false) + { + $data = $this->getTaskById($taskId); + $mess = ConfService::getMessages(); + $timeArray = $this->getTimeArray($data["schedule"]); + + // TODO : Set MasterInterval as config, or detect last execution? + $masterInterval = 1; + $maximumProcesses = 2; + + $now = time(); + $lastExec = time()-60*$masterInterval; + $res = $this->getNextExecutionTimeForScript($lastExec, $timeArray); + $test = date("Y-m-d H:i", $lastExec). " -- ".date("Y-m-d H:i", $res)." -- ".date("Y-m-d H:i", $now); + + $alreadyRunning = false; + $queued = false; + if($status == null) $status = $this->getTaskStatus($taskId); + if ($status !== false) { + if ($status[0] == "RUNNING") { + $alreadyRunning = true; + } else if (in_array("QUEUED", $status)) { + $queued = true; // Run now ! + } + } + if ($res >= $lastExec && $res < $now && !$alreadyRunning && $currentlyRunning >= $maximumProcesses) { + $this->setTaskStatus($taskId, "QUEUED", true); + $alreadyRunning = true; + $queued = false; + } + if ( ( $res >= $lastExec && $res < $now && !$alreadyRunning ) || $queued || $forceStart) { + if ($data["user_id"] == "*") { + $data["user_id"] = implode(",", array_keys(AuthService::listUsers())); + } else if ($data["user_id"] == "*/*") { + // Recurse all groups and put them into a queue file + $allUsers = array(); + $this->gatherUsers($allUsers, "/"); + $tmpQueue = AJXP_CACHE_DIR."/cmd_outputs/queue_".$taskId.""; + file_put_contents($tmpQueue, implode(",", $allUsers)); + $data["user_id"] = "queue:".$tmpQueue; + } + if ($data["repository_id"] == "*") { + $data["repository_id"] = implode(",", array_keys(ConfService::getRepositoriesList())); + } + $process = AJXP_Controller::applyActionInBackground( + $data["repository_id"], + $data["action_name"], + $data["PARAMS"], + $data["user_id"], + AJXP_CACHE_DIR."/cmd_outputs/task_".$taskId.".status"); + if ($process != null && is_a($process, "UnixProcess")) { + $this->setTaskStatus($taskId, "RUNNING:".$process->getPid()); + } else { + $this->setTaskStatus($taskId, "RUNNING"); + } + $currentlyRunning ++; + return true; + } + return false; + } + + protected function gatherUsers(&$users, $startGroup="/") + { + $u = AuthService::listUsers($startGroup); + $users = array_merge($users, array_keys($u)); + $g = AuthService::listChildrenGroups($startGroup); + if (count($g)) { + foreach ($g as $gName => $gLabel) { + $this->gatherUsers($users, $startGroup.$gName); + } + } + } + + + public function sortTasksByPriorityStatus($data1, $data2) + { + if(is_array($data1["status"]) && in_array("QUEUED", $data1["status"])) return -1; + if(is_array($data2["status"]) && in_array("QUEUED", $data2["status"])) return 1; + return 0; + } + + public function switchAction($action, $httpVars, $postProcessData) + { + switch ($action) { + + //------------------------------------ + // SHARING FILE OR FOLDER + //------------------------------------ + case "scheduler_runAll": + + $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); + $message = ""; + $startRunning = $this->countCurrentlyRunning(); + $statuses = array(); + foreach ($tasks as $index => $task) { + $tasks[$index]["status"] = $this->getTaskStatus($task["task_id"]); + } + usort($tasks, array($this, "sortTasksByPriorityStatus")); + foreach ($tasks as $task) { + if (isSet($task["task_id"])) { + $res = $this->runTask($task["task_id"], $task["status"], $startRunning); + if ($res) { + $message .= "Running ".$task["label"]." \n "; + } + } + } + if(empty($message)) $message = "Nothing to do"; + + if (ConfService::currentContextIsCommandLine()) { + print(date("Y-m-d H:i:s")."\t".$message."\n"); + } else { + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($message, null); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + } + + break; + + case "scheduler_runTask": + + $err = -1; + $this->runTask($httpVars["task_id"], null, $err, true); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + + break; + + case "scheduler_generateCronExpression": + + $phpCmd = ConfService::getCoreConf("CLI_PHP"); + $rootInstall = AJXP_INSTALL_PATH.DIRECTORY_SEPARATOR."cmd.php" ; + $logFile = AJXP_CACHE_DIR.DIRECTORY_SEPARATOR."cmd_outputs".DIRECTORY_SEPARATOR."cron_commands.log"; + $cronTiming = "*/5 * * * *"; + HTMLWriter::charsetHeader("text/plain", "UTF-8"); + print "$cronTiming $phpCmd $rootInstall -r=ajxp_conf -u=".AuthService::getLoggedUser()->getId()." -p=YOUR_PASSWORD_HERE -a=scheduler_runAll >> $logFile"; + + break; + + default: + break; + } + + } + + public function placeConfigNode(&$configTree) + { + $mess = ConfService::getMessages(); + if (isSet($configTree["admin"])) { + $configTree["admin"]["CHILDREN"]["scheduler"] = array( + "LABEL" => $mess["action.scheduler.18"], + "DESCRIPTION" => $mess["action.scheduler.22"], + "ICON" => "scheduler/ICON_SIZE/player_time.png", + "LIST" => array($this, "listTasks")); + } + } + + public function listTasks($action, $httpVars, $postProcessData) + { + $mess =ConfService::getMessages(); + AJXP_XMLWriter::renderHeaderNode("/admin/scheduler", "Scheduler", false, array("icon" => "scheduler/ICON_SIZE/player_time.png")); + AJXP_XMLWriter::sendFilesListComponentConfig(' + + + + + + + + + '); + $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); + foreach ($tasks as $task) { + + $timeArray = $this->getTimeArray($task["schedule"]); + $res = $this->getNextExecutionTimeForScript(time(), $timeArray); + $task["NEXT_EXECUTION"] = date($mess["date_format"], $res); + $task["PARAMS"] = implode(", ", $task["PARAMS"]); + $task["icon"] = "scheduler/ICON_SIZE/task.png"; + $task["ajxp_mime"] = "scheduler_task"; + $sFile = AJXP_CACHE_DIR."/cmd_outputs/task_".$task["task_id"].".status"; + if (is_file($sFile)) { + $s = $this->getTaskStatus($task["task_id"]); + $task["STATUS"] = implode(":", $s); + $task["LAST_EXECUTION"] = date($mess["date_format"], filemtime($sFile)); + } else { + $task["STATUS"] = "n/a"; + $task["LAST_EXECUTION"] = "n/a"; + } + + AJXP_XMLWriter::renderNode("/admin/scheduler/".$task["task_id"], + (isSet($task["label"])?$task["label"]:"Action ".$task["action_name"]), + true, + $task + ); + } + AJXP_XMLWriter::close(); + + } + + public function getTimeArray($schedule) + { + $parts = explode(" ", $schedule); + if(count($parts)!=5) throw new Exception("Invalid Schedule Format ($schedule)"); + $timeArray['minutes'] = $parts[0]; + $timeArray['hours'] = $parts[1]; + $timeArray['days'] = $parts[2]; + $timeArray['dayWeek'] = $parts[3]; + $timeArray['months'] = $parts[4]; + return $timeArray; + } + + + public function addOrUpdateTask($taskId, $label, $schedule, $actionName, $repositoryIds, $userId, $paramsArray) + { + $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); + if (isSet($taskId)) { + foreach ($tasks as $index => $task) { + if ($task["task_id"] == $taskId) { + $data = $task; + $theIndex = $index; + } + } + } + if (!isSet($theIndex)) { + $data = array(); + $data["task_id"] = substr(md5(time()), 0, 16); + } + $data["label"] = $label; + $data["schedule"] = $schedule; + $data["action_name"] = $actionName; + $data["repository_id"] = $repositoryIds; + $data["user_id"] = $userId; + $data["PARAMS"] = $paramsArray; + if(isSet($theIndex)) $tasks[$theIndex] = $data; + else $tasks[] = $data; + AJXP_Utils::saveSerialFile($this->getDbFile(), $tasks, true, false, "json"); + + } + + public function removeTask($taskId) + { + $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); + foreach ($tasks as $index => $task) { + if ($task["task_id"] == $taskId) { + unset($tasks[$index]); + break; + } + } + AJXP_Utils::saveSerialFile($this->getDbFile(), $tasks, true, false, "json"); + } + + public function handleTasks($action, $httpVars, $fileVars) + { + $tasks = AJXP_Utils::loadSerialFile($this->getDbFile(), false, "json"); + switch ($action) { + case "scheduler_addTask": + if (isSet($httpVars["task_id"])) { + foreach ($tasks as $index => $task) { + if ($task["task_id"] == $httpVars["task_id"]) { + $data = $task; + $theIndex = $index; + } + } + } + if (!isSet($theIndex)) { + $data = array(); + $data["task_id"] = substr(md5(time()), 0, 16); + } + $data["label"] = $httpVars["label"]; + $data["schedule"] = $httpVars["schedule"]; + $data["action_name"] = $httpVars["action_name"]; + $data["repository_id"] =$httpVars["repository_id"]; + $i = 1; + while (array_key_exists("repository_id_".$i, $httpVars)) { + $data["repository_id"].=",".$httpVars["repository_id_".$i]; + $i++; + } + $data["user_id"] = $httpVars["user_id"]; + $data["PARAMS"] = array(); + if (!empty($httpVars["param_name"]) && !empty($httpVars["param_value"])) { + $data["PARAMS"][$httpVars["param_name"]] = $httpVars["param_value"]; + } + foreach ($httpVars as $key => $value) { + if (preg_match('/^param_name_/', $key)) { + $paramIndex = str_replace("param_name_", "", $key); + if(preg_match('/ajxptype/', $paramIndex)) continue; + if(preg_match('/replication/', $paramIndex)) continue; + if (isSet($httpVars["param_value_".$paramIndex])) { + $data["PARAMS"][$value] = $httpVars["param_value_".$paramIndex]; + } + } + } + if(isSet($theIndex)) $tasks[$theIndex] = $data; + else $tasks[] = $data; + AJXP_Utils::saveSerialFile($this->getDbFile(), $tasks, true, false, "json"); + + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage("Successfully added/edited task", null); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + + break; + + case "scheduler_removeTask" : + + $this->removeTask($httpVars["task_id"]); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage("Successfully removed task", null); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::close(); + + break; + + case "scheduler_loadTask": + + $found = false; + foreach ($tasks as $task) { + if ($task["task_id"] == $httpVars["task_id"]) { + $index = 0; + $found = true; + foreach ($task["PARAMS"] as $pName => $pValue) { + if ($index == 0) { + $task["param_name"] = $pName; + $task["param_value"] = $pValue; + } else { + $task["param_name_".$index] = $pName; + $task["param_value_".$index] = $pValue; + } + $index ++; + } + unset($task["PARAMS"]); + if (strpos($task["repository_id"], ",") !== false) { + $ids = explode(",", $task["repository_id"]); + $task["repository_id"] = $ids[0]; + for ($i = 1; $igetId()); + print('STARTING FAKE TASK'); + sleep($minutes * 60); + print('ENDIND FAKE TASK'); + } + + public function getNextExecutionTimeForScript($referenceTime, $timeArray) + { + $a=null; $m=null; $j=null; $h=null; $min=null; + + $aNow = date("Y", $referenceTime); + $mNow = date("m", $referenceTime); + $jNow = date("d", $referenceTime); + $hNow = date("H", $referenceTime); + $minNow = date("i", $referenceTime)+1; + + $a = $aNow; + $m = $mNow - 1; + + while ($this->nextMonth($timeArray, $a, $m, $j, $h, $min) != -1) { /* on parcourt tous les mois de l'intervalle demandé */ /* jusqu'à trouver une réponse convanable */ + if ($m != $mNow || $a != $aNow) { /*si ce n'est pas ce mois ci */ + $j = 0; + if ($this->nextDay($timeArray, $a, $m, $j, $h, $min) == -1) { /* le premier jour trouvé sera le bon. */ /* -1 si l'intersection entre jour de semaine */ + /* et jour du mois est nulle */ + continue; /* ...auquel cas on passe au mois suivant */ + } else { /* s'il y a un jour */ + $h=-1; + $this->nextHour($timeArray, $a, $m, $j, $h, $min); /* la première heure et la première minute conviendront*/ + $min = -1; + $this->nextMinute($timeArray, $a, $m, $j, $h, $min); + return mktime($h, $min, 0, $m, $j, $a); + } + } else { /* c'est ce mois ci */ + $j = $jNow-1; + while ($this->nextDay($timeArray, $a, $m, $j, $h, $min) != -1) { /* on cherche un jour à partir d'aujourd'hui compris */ + if ($j > $jNow) { /* si ce n'est pas aujourd'hui */ /* on prend les premiers résultats */ + $h=-1; + $this->nextHour($timeArray, $a, $m, $j, $h, $min); + $min = -1; + $this->nextMinute($timeArray, $a, $m, $j, $h, $min); + return mktime($h, $min, 0, $m, $j, $a); + } + if ($j == $jNow) { /* même algo pour les heures et les minutes */ + $h = $hNow - 1; + while ($this->nextHour($timeArray, $a, $m, $j, $h, $min) != -1) { + if ($h > $hNow) { + $min = -1; + $this->nextMinute($timeArray, $a, $m, $j, $h, $min); + return mktime($h, $min, 0, $m, $j, $a); + } + if ($h == $hNow) { + $min = $minNow - 1; + while ($this->nextMinute($timeArray, $a, $m, $j, $h, $min) != -1) { + if ($min > $minNow) { return mktime($h, $min, 0, $m, $j, $a); } + + /* si c'est maintenant, on l'éxécute directement */ + if ($min == $minNow) { + return $referenceTime; + } + } + } + } + } + } + } + } + } + + public function parseFormat($min, $max, $intervalle) + { + $retour = Array(); + + if ($intervalle == '*') { + for($i=$min; $i<=$max; $i++) $retour[$i] = TRUE; + return $retour; + } else { + for($i=$min; $i<=$max; $i++) $retour[$i] = FALSE; + } + if ($intervalle[0] == "/") { + // Transform Repeat pattern into range + $repeat = intval(ltrim($intervalle, "/")); + $values= array(); + for ($i=$min;$i<=$max;$i++) { + if(($i % $repeat) == 0) $values[] = $i; + } + $intervalle = implode(",", $values); + } + + $intervalle = array_map("trim", explode(',', $intervalle)); + foreach ($intervalle as $val) { + $val = array_map("trim", explode('-', $val)); + if (isset($val[0]) && isset($val[1])) { + if ($val[0] <= $val[1]) { + for($i=$val[0]; $i<=$val[1]; $i++) $retour[$i] = TRUE; /* ex : 9-12 = 9, 10, 11, 12 */ + } else { + for($i=$val[0]; $i<=$max; $i++) $retour[$i] = TRUE; /* ex : 10-4 = 10, 11, 12... */ + for($i=$min; $i<=$val[1]; $i++) $retour[$i] = TRUE; /* ...et 1, 2, 3, 4 */ + } + } else { + $retour[$val[0]] = TRUE; + } + } + return $retour; + } + + public function nextMonth($timeArray, &$a, &$m, &$j, &$h, &$min) + { + $valeurs = $this->parseFormat(1, 12, $timeArray['months']); + do { + $m++; + if ($m == 13) { + $m=1; + $a++; /*si on a fait le tour, on réessaye l'année suivante */ + } + } while ($valeurs[$m] != TRUE); + } + public function nextDay($timeArray, &$a, &$m, &$j, &$h, &$min) + { + $valeurs = $this->parseFormat(1, 31, $timeArray['days']); + $valeurSemaine = $this->parseFormat(0, 6, $timeArray['dayWeek']); + + do { + $j++; + + /* si $j est égal au nombre de jours du mois + 1 */ + if ($j == date('t', mktime(0, 0, 0, $m, 1, $a))+1) { return -1; } + + $js = date('w', mktime(0, 0, 0, $m, $j, $a)); + } while ($valeurs[$j] != TRUE || $valeurSemaine[$js] != TRUE); + } + public function nextHour($timeArray, &$a, &$m, &$j, &$h, &$min) + { + $valeurs = $this->parseFormat(0, 23, $timeArray['hours']); + + do { + $h++; + if ($h == 24) { return -1; } + } while ($valeurs[$h] != TRUE); + } + + public function nextMinute($timeArray, &$a, &$m, &$j, &$h, &$min) + { + $valeurs = $this->parseFormat(0, 59, $timeArray['minutes']); + + do { + $min++; + if ($min == 60) { return -1; } + } while ($valeurs[$min] != TRUE); + } +} diff --git a/core/src/plugins/action.scheduler/i18n/en.php b/core/src/plugins/action.scheduler/i18n/en.php index ebba653ddd..b2494c3666 100644 --- a/core/src/plugins/action.scheduler/i18n/en.php +++ b/core/src/plugins/action.scheduler/i18n/en.php @@ -1,59 +1,59 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess = array( - // will be replaced by the application title - "1" => "Action", - "1d" => "Action to be performed by this task", - "2" => "Schedule", - "2d" => "Crontab like expression under the following format : minutes hours days dayWeeks monthes. You can use wildcards, steps and ranges.", - "3" => "Next Execution", - "4" => "Repository ID", - "4s" => "Repository", - "4d" => "Id of the target workspace", - "5" => "Parameters", - "5d" => "Replicable action parameters", - "6" => "Param Name", - "6d" => "Action specific parameter name", - "7" => "Param Value", - "7d" => "Action specific parameter value", - "8" => "New task", - "9" => "Schedule a task to be executed on a regular basis", - "10" => "Edit task", - "11" => "Edit scheduled task parameters", - "12" => "Label", - "12d"=> "Human readable label for this task", - "13" => "Status", - "14" => "Last Execution", - "15"=> "Run all tasks", - "15d" => "Trigger selected task now", - "16" => "Run task", - "16d" => "Trigger scheduler and run scheduled tasks", - "17" => "User(s)", - "17d" => "Enter a comma separated list of users, or wildcard * to recurse the task on all users.", - "18" => "Scheduler", - "18d" => "Cron-like scheduler actions", - "19" => "Delete Task", - "19d" => "Unschedule and remove the selected task", - "20" => "Cron Expression", - "20d" => "Generate Crontab expression", - "21" => "Add the following line to your CRONTAB, replacing your password real value, and the scheduling you want (here configured to run every five minutes).", - "22" => "Generic scheduler to perform tasks on a regular basis. Requires CLI activation and a CRONTAB or similar system.", -); \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess = array( + // will be replaced by the application title + "1" => "Action", + "1d" => "Action to be performed by this task", + "2" => "Schedule", + "2d" => "Crontab like expression under the following format : minutes hours days dayWeeks monthes. You can use wildcards, steps and ranges.", + "3" => "Next Execution", + "4" => "Repository ID", + "4s" => "Repository", + "4d" => "Id of the target workspace", + "5" => "Parameters", + "5d" => "Replicable action parameters", + "6" => "Param Name", + "6d" => "Action specific parameter name", + "7" => "Param Value", + "7d" => "Action specific parameter value", + "8" => "New task", + "9" => "Schedule a task to be executed on a regular basis", + "10" => "Edit task", + "11" => "Edit scheduled task parameters", + "12" => "Label", + "12d"=> "Human readable label for this task", + "13" => "Status", + "14" => "Last Execution", + "15"=> "Run all tasks", + "15d" => "Trigger selected task now", + "16" => "Run task", + "16d" => "Trigger scheduler and run scheduled tasks", + "17" => "User(s)", + "17d" => "Enter a comma separated list of users, or wildcard * to recurse the task on all users.", + "18" => "Scheduler", + "18d" => "Cron-like scheduler actions", + "19" => "Delete Task", + "19d" => "Unschedule and remove the selected task", + "20" => "Cron Expression", + "20d" => "Generate Crontab expression", + "21" => "Add the following line to your CRONTAB, replacing your password real value, and the scheduling you want (here configured to run every five minutes).", + "22" => "Generic scheduler to perform tasks on a regular basis. Requires CLI activation and a CRONTAB or similar system.", +); diff --git a/core/src/plugins/action.scheduler/i18n/fr.php b/core/src/plugins/action.scheduler/i18n/fr.php index f3cc40a0b4..a5b06f0227 100644 --- a/core/src/plugins/action.scheduler/i18n/fr.php +++ b/core/src/plugins/action.scheduler/i18n/fr.php @@ -1,58 +1,58 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess = array( - "1" => "Action", - "1d" => "Action que cette tâche doit déclencher", - "2" => "Plannification", - "2d" => "Expression de type Crontab au format suivant : minutes heures jours joursDeSemaine mois. Vous pouvez utiliser des wildcards (*), des pas (,) et des intervalles (-), ainsi que le diviseur.", - "3" => "Prochaine execution", - "4" => "ID Dépôt", - "4s" => "Dépôt", - "4d" => "Id du dépôt cible", - "5" => "Paramètres", - "5d" => "Entrez autant de paramêtres que nécessaires pour cette action", - "6" => "Clé", - "6d" => "Nom du parametre", - "7" => "Valeur", - "7d" => "Valeur associée", - "8" => "Nouvelle tâche", - "9" => "Plannifier une tâche qui sera executée régulièrement", - "10" => "Editer tâche", - "11" => "Editer les parametres et la plannification de la tâche", - "12" => "Libellé", - "12d"=> "Libellé de la tâche", - "13" => "Statut", - "14" => "Dernière execution", - "15"=> "Démarrer", - "15d" => "Démarrer le plannificateur pour faire tourner les tâches", - "16" => "Lancer les tâches", - "16d" => "Démarrer le plannificateur pour faire tourner les tâches", - "17" => "Utilisateur(s)", - "17d" => "Entre une liste d'utilisateur, ou un wildcard * pour lancer la tâche sur chaque utilisateur.", - "18" => "Plannificateur", - "18d" => "Actions du plannificateur", - "19" => "Supprimer", - "19d" => "Déplannifier et supprimer la tâche", - "20" => "Expression CRON", - "20d" => "Generer l'expression CRON", - "21" => "Ajoutez la ligne suivante dans votre crontab, en remplaçant votre mot de passe, et éventuellement l'expression de plannification (ici configurées pour déclencher le script toutes les 5 minutes).", - "22" => "Plannificateur permettant l'execution reccurente de tâches. Nécessite l'activation de la ligne de commande et d'un système type CRONTAB.", -); \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess = array( + "1" => "Action", + "1d" => "Action que cette tâche doit déclencher", + "2" => "Plannification", + "2d" => "Expression de type Crontab au format suivant : minutes heures jours joursDeSemaine mois. Vous pouvez utiliser des wildcards (*), des pas (,) et des intervalles (-), ainsi que le diviseur.", + "3" => "Prochaine execution", + "4" => "ID Dépôt", + "4s" => "Dépôt", + "4d" => "Id du dépôt cible", + "5" => "Paramètres", + "5d" => "Entrez autant de paramêtres que nécessaires pour cette action", + "6" => "Clé", + "6d" => "Nom du parametre", + "7" => "Valeur", + "7d" => "Valeur associée", + "8" => "Nouvelle tâche", + "9" => "Plannifier une tâche qui sera executée régulièrement", + "10" => "Editer tâche", + "11" => "Editer les parametres et la plannification de la tâche", + "12" => "Libellé", + "12d"=> "Libellé de la tâche", + "13" => "Statut", + "14" => "Dernière execution", + "15"=> "Démarrer", + "15d" => "Démarrer le plannificateur pour faire tourner les tâches", + "16" => "Lancer les tâches", + "16d" => "Démarrer le plannificateur pour faire tourner les tâches", + "17" => "Utilisateur(s)", + "17d" => "Entre une liste d'utilisateur, ou un wildcard * pour lancer la tâche sur chaque utilisateur.", + "18" => "Plannificateur", + "18d" => "Actions du plannificateur", + "19" => "Supprimer", + "19d" => "Déplannifier et supprimer la tâche", + "20" => "Expression CRON", + "20d" => "Generer l'expression CRON", + "21" => "Ajoutez la ligne suivante dans votre crontab, en remplaçant votre mot de passe, et éventuellement l'expression de plannification (ici configurées pour déclencher le script toutes les 5 minutes).", + "22" => "Plannificateur permettant l'execution reccurente de tâches. Nécessite l'activation de la ligne de commande et d'un système type CRONTAB.", +); diff --git a/core/src/plugins/action.scheduler/i18n/pt.php b/core/src/plugins/action.scheduler/i18n/pt.php index 6af7af065b..02892663fc 100644 --- a/core/src/plugins/action.scheduler/i18n/pt.php +++ b/core/src/plugins/action.scheduler/i18n/pt.php @@ -56,4 +56,4 @@ "20d" => "Gerar uma expressão Cronológica", "21" => "Adicionar a seguinte linha à sua Tabela Cronológica, substituindo o valor da sua palavra-chave real e agendando o que pretende (configurado aqui para correr a cada cinco minutos).", "22" => "Agendamento Genérico para correr tarefas de forma regular. Requer a activação de CLI e de uma Tabela Cronológica ou de um sistema semelhante.", -); \ No newline at end of file +); diff --git a/core/src/plugins/action.scheduler/manifest.xml b/core/src/plugins/action.scheduler/manifest.xml index 0e05bcb47c..12f882ddfd 100644 --- a/core/src/plugins/action.scheduler/manifest.xml +++ b/core/src/plugins/action.scheduler/manifest.xml @@ -1,226 +1,226 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    AJXP_MESSAGE[action.scheduler.21]
    - - - ]]>
    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - -
    - - - - -
    \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AJXP_MESSAGE[action.scheduler.21]
    + + + ]]>
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + +
    diff --git a/core/src/plugins/action.share/class.PublicletCounter.php b/core/src/plugins/action.share/class.PublicletCounter.php index 72519bcaec..2a633e6031 100644 --- a/core/src/plugins/action.share/class.PublicletCounter.php +++ b/core/src/plugins/action.share/class.PublicletCounter.php @@ -25,58 +25,64 @@ * @package AjaXplorer_Plugins * @subpackage Action */ -class PublicletCounter { - - static private $counters; - - static function getCount($publiclet){ - $counters = self::loadCounters(); - if(isSet($counters[$publiclet])) return $counters[$publiclet]; - return 0; - } - - static function increment($publiclet){ - if(!self::isActive()) return -1 ; - $counters = self::loadCounters(); - if(!isSet($counters[$publiclet])){ - $counters[$publiclet] = 0; - } - $counters[$publiclet] ++; - self::saveCounters($counters); - return $counters[$publiclet]; - } - - static function reset($publiclet){ - if(!self::isActive()) return -1 ; - $counters = self::loadCounters(); - $counters[$publiclet] = 0; - self::saveCounters($counters); - } - - static function delete($publiclet){ - if(!self::isActive()) return -1 ; - $counters = self::loadCounters(); - if(isSet($counters[$publiclet])){ - unset($counters[$publiclet]); - self::saveCounters($counters); - } - } - - static private function isActive(){ - return (is_dir(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")) && is_writable(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"))); - } - - static private function loadCounters(){ - if(!isSet(self::$counters)){ - self::$counters = AJXP_Utils::loadSerialFile(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")."/.ajxp_publiclet_counters.ser"); - } - return self::$counters; - } - - static private function saveCounters($counters){ - self::$counters = $counters; - AJXP_Utils::saveSerialFile(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")."/.ajxp_publiclet_counters.ser", $counters, false); - } - +class PublicletCounter +{ + private static $counters; + + public static function getCount($publiclet) + { + $counters = self::loadCounters(); + if(isSet($counters[$publiclet])) return $counters[$publiclet]; + return 0; + } + + public static function increment($publiclet) + { + if(!self::isActive()) return -1 ; + $counters = self::loadCounters(); + if (!isSet($counters[$publiclet])) { + $counters[$publiclet] = 0; + } + $counters[$publiclet] ++; + self::saveCounters($counters); + return $counters[$publiclet]; + } + + public static function reset($publiclet) + { + if(!self::isActive()) return -1 ; + $counters = self::loadCounters(); + $counters[$publiclet] = 0; + self::saveCounters($counters); + } + + public static function delete($publiclet) + { + if(!self::isActive()) return -1 ; + $counters = self::loadCounters(); + if (isSet($counters[$publiclet])) { + unset($counters[$publiclet]); + self::saveCounters($counters); + } + } + + private static function isActive() + { + return (is_dir(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")) && is_writable(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"))); + } + + private static function loadCounters() + { + if (!isSet(self::$counters)) { + self::$counters = AJXP_Utils::loadSerialFile(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")."/.ajxp_publiclet_counters.ser"); + } + return self::$counters; + } + + private static function saveCounters($counters) + { + self::$counters = $counters; + AJXP_Utils::saveSerialFile(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")."/.ajxp_publiclet_counters.ser", $counters, false); + } + } -?> \ No newline at end of file diff --git a/core/src/plugins/action.share/class.ShareCenter.php b/core/src/plugins/action.share/class.ShareCenter.php index 32f0b3a858..230c645517 100644 --- a/core/src/plugins/action.share/class.ShareCenter.php +++ b/core/src/plugins/action.share/class.ShareCenter.php @@ -1,1241 +1,1254 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); - -require_once("class.PublicletCounter.php"); - -/** - * @package AjaXplorer_Plugins - * @subpackage Action - */ -class ShareCenter extends AJXP_Plugin{ - - /** - * @var AbstractAccessDriver - */ - private $accessDriver; - /** - * @var Repository - */ - private $repository; - private $urlBase; - private $baseProtocol; - - /** - * @var MetaStoreProvider - */ - private $metaStore; - - /** - * @var MetaWatchRegister - */ - private $watcher = false; - - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if(isSet($this->actions["share"])){ - $disableSharing = false; - $downloadFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); - if($downloadFolder == ""){ - $disableSharing = true; - }else if((!is_dir($downloadFolder) || !is_writable($downloadFolder))){ - AJXP_Logger::debug("Disabling Public links, $downloadFolder is not writeable!", array("folder" => $downloadFolder, "is_dir" => is_dir($downloadFolder),"is_writeable" => is_writable($downloadFolder))); - $disableSharing = true; - }else{ - if(AuthService::usersEnabled()){ - $loggedUser = AuthService::getLoggedUser(); - if($loggedUser != null && AuthService::isReservedUserId($loggedUser->getId())){ - $disableSharing = true; - } - }else{ - $disableSharing = true; - } - } - if($disableSharing){ - unset($this->actions["share"]); - $actionXpath=new DOMXPath($contribNode->ownerDocument); - $publicUrlNodeList = $actionXpath->query('action[@name="share"]', $contribNode); - $publicUrlNode = $publicUrlNodeList->item(0); - $contribNode->removeChild($publicUrlNode); - } - } - } - - function init($options){ - parent::init($options); - $this->repository = ConfService::getRepository(); - if(!is_a($this->repository->driverInstance, "AjxpWrapperProvider")){ - return; - } - $this->accessDriver = $this->repository->driverInstance; - $this->urlBase = $this->repository->driverInstance->getResourceUrl("/"); - $this->baseProtocol = array_shift(explode("://", $this->urlBase)); - if(array_key_exists("meta.watch", AJXP_PluginsService::getInstance()->getActivePlugins())){ - $this->watcher = AJXP_PluginsService::getInstance()->getPluginById("meta.watch"); - } - } - - function switchAction($action, $httpVars, $fileVars){ - - if(!isSet($this->accessDriver)){ - throw new Exception("Cannot find access driver!"); - } - - - if($this->accessDriver->getId() == "access.demo"){ - $errorMessage = "This is a demo, all 'write' actions are disabled!"; - if($httpVars["sub_action"] == "delegate_repo"){ - return AJXP_XMLWriter::sendMessage(null, $errorMessage, false); - }else{ - print($errorMessage); - } - return; - } - - - switch($action){ - - //------------------------------------ - // SHARING FILE OR FOLDER - //------------------------------------ - case "share": - $subAction = (isSet($httpVars["sub_action"])?$httpVars["sub_action"]:""); - $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); - $ajxpNode = new AJXP_Node($this->urlBase.$file); - $metadata = null; - - if($subAction == "delegate_repo"){ - header("Content-type:text/plain"); - $result = $this->createSharedRepository($httpVars, $this->repository, $this->accessDriver); - if(is_a($result, "Repository")){ - $metadata = array("element" => $result->getUniqueId()); - $numResult = 200; - }else{ - $numResult = $result; - } - print($numResult); - }else if ($subAction == "create_minisite"){ - header("Content-type:text/plain"); - $res = $this->createSharedMinisite($httpVars, $this->repository, $this->accessDriver); - if(!is_array($res)){ - $url = $res; - }else{ - list($hash, $url) = $res; - $metadata = array("element" => $hash, "minisite" => (isSet($httpVars["create_guest_user"])?"public":"private")); - } - print($url); - }else{ - $maxdownload = $this->getFilteredOption("FILE_MAX_DOWNLOAD", $this->repository->getId()); - if(!isSet($httpVars["downloadlimit"]) || $httpVars["downloadlimit"] == 0){ - $httpVars["downloadlimit"] = $maxdownload; - }else{ - $httpVars["downloadlimit"] = min($maxdownload,floor(abs($httpVars["downloadlimit"]))); - } - $maxexpiration = $this->getFilteredOption("FILE_MAX_EXPIRATION", $this->repository->getId()); - if(!isSet($httpVars["expiration"]) || $httpVars["expiration"] == 0){ - $httpVars["expiration"] = $maxexpiration; - }else{ - $httpVars["expiration"] = min($maxexpiration,floor(abs($httpVars["expiration"]))); - } - - $data = $this->accessDriver->makePublicletOptions($file, $httpVars["password"], $httpVars["expiration"], $httpVars["downloadlimit"], $this->repository); - $customData = array(); - foreach($httpVars as $key => $value){ - if(substr($key, 0, strlen("PLUGINS_DATA_")) == "PLUGINS_DATA_"){ - $customData[substr($key, strlen("PLUGINS_DATA_"))] = $value; - } - } - if(count($customData)){ - $data["PLUGINS_DATA"] = $customData; - } - list($hash, $url) = $this->writePubliclet($data, $this->accessDriver, $this->repository); - $metadata = array("element" => $hash); - header("Content-type:text/plain"); - echo $url; - } - if($metadata != null && $ajxpNode->hasMetaStore()){ - $ajxpNode->setMetadata( - "ajxp_shared", - $metadata, - true, - AJXP_METADATA_SCOPE_REPOSITORY, - true - ); - } - AJXP_Controller::applyHook("msg.instant", array("", ConfService::getRepository()->getId())); - // as the result can be quite small (e.g error code), make sure it's output in case of OB active. - flush(); - - break; - - case "toggle_link_watch": - - $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); - $watchValue = $httpVars["set_watch"] == "true" ? true : false; - $node = new AJXP_Node($this->urlBase.$file); - $metadata = $node->retrieveMetadata( - "ajxp_shared", - true, - AJXP_METADATA_SCOPE_REPOSITORY - ); - $elementId = $metadata["element"]; - - if($this->watcher !== false){ - if($watchValue){ - $this->watcher->setWatchOnFolder( - $node, - AuthService::getLoggedUser()->getId(), - MetaWatchRegister::$META_WATCH_USERS_READ, - array($elementId) - ); - }else{ - $this->watcher->removeWatchFromFolder( - $node, - AuthService::getLoggedUser()->getId(), - true - ); - } - } - $mess = ConfService::getMessages(); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::sendMessage($mess["share_center.47"], null); - AJXP_XMLWriter::close(); - - break; - - case "load_shared_element_data": - - $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); - $elementType = $httpVars["element_type"]; - $messages = ConfService::getMessages(); - $node = new AJXP_Node($this->urlBase.$file); - - $metadata = $node->retrieveMetadata( - "ajxp_shared", - true, - AJXP_METADATA_SCOPE_REPOSITORY - ); - $elementWatch = false; - if(count($metadata)){ - header("Content-type:application/json"); - - if($elementType == "file"){ - $pData = self::loadPublicletData($metadata["element"]); - if($pData["OWNER_ID"] != AuthService::getLoggedUser()->getId()){ - throw new Exception($messages["share_center.48"]); - } - if(isSet($metadata["short_form_url"])){ - $link = $metadata["short_form_url"]; - }else{ - $link = $this->buildPublicletLink($metadata["element"]); - } - if($this->watcher != false){ - $elementWatch = $this->watcher->hasWatchOnNode( - $node, - AuthService::getLoggedUser()->getId(), - MetaWatchRegister::$META_WATCH_USERS_NAMESPACE - ); - } - $jsonData = array( - "publiclet_link" => $link, - "download_counter" => PublicletCounter::getCount($metadata["element"]), - "download_limit" => $pData["DOWNLOAD_LIMIT"], - "expire_time" => ($pData["EXPIRE_TIME"]!=0?date($messages["date_format"], $pData["EXPIRE_TIME"]):0), - "has_password" => (!empty($pData["PASSWORD"])), - "element_watch" => $elementWatch - ); - }else if( $elementType == "repository"){ - if(isSet($metadata["minisite"])){ - $minisiteData = self::loadPublicletData($metadata["element"]); - $repoId = $minisiteData["REPOSITORY"]; - $minisiteIsPublic = isSet($minisiteData["PRELOG_USER"]); - $dlDisabled = isSet($minisiteData["DOWNLOAD_DISABLED"]); - if(isSet($metadata["short_form_url"])){ - $minisiteLink = $metadata["short_form_url"]; - }else{ - $minisiteLink = $this->buildPublicletLink($metadata["element"]); - } - }else{ - $repoId = $metadata["element"]; - } - $repo = ConfService::getRepositoryById($repoId); - if($repo == null || $repo->getOwner() != AuthService::getLoggedUser()->getId()){ - throw new Exception($messages["share_center.48"]); - } - if($this->watcher != false){ - $elementWatch = $this->watcher->hasWatchOnNode( - new AJXP_Node($this->baseProtocol."://".$repoId."/"), - AuthService::getLoggedUser()->getId(), - MetaWatchRegister::$META_WATCH_NAMESPACE - ); - } - $sharedEntries = $this->computeSharedRepositoryAccessRights($repoId, true, $this->urlBase.$file); - - $jsonData = array( - "repositoryId" => $repoId, - "label" => $repo->getDisplay(), - "description" => $repo->getDescription(), - "entries" => $sharedEntries, - "element_watch" => $elementWatch, - "repository_url"=> AJXP_Utils::detectServerURL(true)."?goto=". $repo->getSlug() ."/" - ); - if(isSet($minisiteData)){ - $jsonData["minisite"] = array( - "public" => $minisiteIsPublic?"true":"false", - "public_link" => $minisiteLink, - "disable_download" => $dlDisabled - ); - - } - } - echo json_encode($jsonData); - } - - - break; - - case "unshare": - $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); - $ajxpNode = new AJXP_Node($this->urlBase.$file); - $metadata = $ajxpNode->retrieveMetadata( - "ajxp_shared", - true, - AJXP_METADATA_SCOPE_REPOSITORY - ); - if(count($metadata)){ - $eType = $httpVars["element_type"]; - if(isSet($metadata["minisite"])) $eType = "minisite"; - self::deleteSharedElement($eType, $metadata["element"], AuthService::getLoggedUser()); - $ajxpNode->removeMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true); - } - AJXP_Controller::applyHook("msg.instant", array("", ConfService::getRepository()->getId())); - - break; - - case "reset_counter": - $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); - $ajxpNode = new AJXP_Node($this->urlBase.$file); - $metadata = $ajxpNode->retrieveMetadata( - "ajxp_shared", - true, - AJXP_METADATA_SCOPE_REPOSITORY - ); - if(isSet($metadata["element"])){ - PublicletCounter::reset($metadata["element"]); - } - break; - - default: - break; - } - - - } - - - /** - * @param AJXP_Node $ajxpNode - * @return void - */ - function nodeSharedMetadata(&$ajxpNode){ - if($this->accessDriver->getId() == "access.imap") return; - $metadata = $ajxpNode->retrieveMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true); - if(count($metadata)){ - $eType = $ajxpNode->isLeaf()?"file":"repository"; - if(isSet($metadata["minisite"])) $eType = "minisite"; - if(!self::sharedElementExists($eType, $metadata["element"], AuthService::getLoggedUser())){ - $ajxpNode->removeMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true); - return; - } - $merge = array( - "ajxp_shared" => "true", - "overlay_icon" => "shared.png" - ); - if($eType == "minisite") $merge["ajxp_shared_minisite"] = $metadata["minisite"]; - $ajxpNode->mergeMetadata($merge, true); - } - } - - /** - * - * Hooked to node.change, this will update the index - * if $oldNode = null => create node $newNode - * if $newNode = null => delete node $oldNode - * Else copy or move oldNode to newNode. - * - * @param AJXP_Node $oldNode - */ - public function updateNodeSharedData($oldNode/*, $newNode = null, $copy = false*/){ - if($this->accessDriver->getId() == "access.imap") return; - if($oldNode == null || !$oldNode->hasMetaStore()) return; - $metadata = $oldNode->retrieveMetadata("ajxp_shared", true); - if(count($metadata) && !empty($metadata["element"])){ - // TODO - // Make sure node info is loaded, to check if it's a dir or a file. - // Maybe could be directly embedded in metadata, to avoid having to load here. - $oldNode->loadNodeInfo(); - try{ - self::deleteSharedElement( - ($oldNode->isLeaf()?"file":"repository"), - $metadata["element"], - AuthService::getLoggedUser() - ); - $oldNode->removeMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true); - }catch(Exception $e){ - AJXP_Logger::logAction("ERROR : ".$e->getMessage(), $e->getTrace() ); - } - } - } - - /** Cypher the publiclet object data and write to disk. - * @param Array $data The publiclet data array to write - The data array must have the following keys: - - DRIVER The driver used to get the file's content - - OPTIONS The driver options to be successfully constructed (usually, the user and password) - - FILE_PATH The path to the file's content - - PASSWORD If set, the written publiclet will ask for this password before sending the content - - ACTION If set, action to perform - - USER If set, the AJXP user - - EXPIRE_TIME If set, the publiclet will deny downloading after this time, and probably self destruct. - * - AUTHOR_WATCH If set, will post notifications for the publiclet author each time the file is loaded - * @param AbstractAccessDriver $accessDriver - * @param Repository $repository - * @return array An array containing the hash (0) and the generated url (1) - */ - function writePubliclet(&$data, $accessDriver, $repository) - { - $downloadFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); - if(!is_dir($downloadFolder)){ - return "ERROR : Public URL folder does not exist!"; - } - if(!function_exists("mcrypt_create_iv")){ - return "ERROR : MCrypt must be installed to use publiclets!"; - } - $this->initPublicFolder($downloadFolder); - $data["PLUGIN_ID"] = $accessDriver->getId(); - $data["BASE_DIR"] = $accessDriver->getBaseDir(); - //$data["REPOSITORY"] = $repository; - if(AuthService::usersEnabled()){ - $data["OWNER_ID"] = AuthService::getLoggedUser()->getId(); - } - if($accessDriver->hasMixin("credentials_consumer")){ - $cred = AJXP_Safe::tryLoadingCredentialsFromSources(array(), $repository); - if(isSet($cred["user"]) && isset($cred["password"])){ - $data["SAFE_USER"] = $cred["user"]; - $data["SAFE_PASS"] = $cred["password"]; - } - } - // Force expanded path in publiclet - $copy = clone $repository; - $copy->addOption("PATH", $repository->getOption("PATH")); - $data["REPOSITORY"] = $copy; - if ($data["ACTION"] == "") $data["ACTION"] = "download"; - // Create a random key - $data["FINAL_KEY"] = md5(mt_rand().time()); - // Cypher the data with a random key - $outputData = serialize($data); - // Hash the data to make sure it wasn't modified - $hash = $this->computeHash($outputData, $downloadFolder); // md5($outputData); - - $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); - $outputData = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $hash, $outputData, MCRYPT_MODE_ECB, $iv)); - $fileData = "<"."?"."php \n". - ' require_once("'.str_replace("\\", "/", AJXP_INSTALL_PATH).'/publicLet.inc.php"); '."\n". - ' $id = str_replace(".php", "", basename(__FILE__)); '."\n". // Not using "" as php would replace $ inside - ' $cypheredData = base64_decode("'.$outputData.'"); '."\n". - ' $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); '."\n". - ' $inputData = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $id, $cypheredData, MCRYPT_MODE_ECB, $iv), "\0"); '."\n". - ' if (!ShareCenter::checkHash($inputData, $id)) { header("HTTP/1.0 401 Not allowed, script was modified"); exit(); } '."\n". - ' // Ok extract the data '."\n". - ' $data = unserialize($inputData); ShareCenter::loadPubliclet($data); '; - if (@file_put_contents($downloadFolder."/".$hash.".php", $fileData) === FALSE){ - return "Can't write to PUBLIC URL"; - } - @chmod($downloadFolder."/".$hash.".php", 0755); - PublicletCounter::reset($hash); - return array($hash, $this->buildPublicletLink($hash)); - } - - /** - * Computes a short form of the hash, checking if it already exists in the folder, - * in which case it increases the hashlength until there is no collision. - * @static - * @param String $outputData Serialized data - * @param String|null $checkInFolder Path to folder - * @return string - */ - public function computeHash($outputData, $checkInFolder = null){ - $length = $this->getFilteredOption("HASH_MIN_LENGTH", $this->repository->getId()); - $full = md5($outputData); - $starter = substr($full, 0, $length); - if($checkInFolder != null){ - while(file_exists($checkInFolder.DIRECTORY_SEPARATOR.$starter.".php")){ - $length ++; - $starter = substr($full, 0, $length); - } - } - return $starter; - } - - /** - * Check if the hash seems to correspond to the serialized data. - * @static - * @param String $outputData serialized data - * @param String $hash Id to check - * @return bool - */ - public static function checkHash($outputData, $hash){ - $full = md5($outputData); - return (!empty($hash) && strpos($full, $hash) === 0); - } - - function buildPublicDlURL(){ - $downloadFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); - $dlURL = ConfService::getCoreConf("PUBLIC_DOWNLOAD_URL"); - $langSuffix = "?lang=".ConfService::getLanguage(); - if($dlURL != ""){ - return rtrim($dlURL, "/"); - }else{ - $fullUrl = AJXP_Utils::detectServerURL() . dirname($_SERVER['REQUEST_URI']); - return str_replace("\\", "/", rtrim($fullUrl, "/").rtrim(str_replace(AJXP_INSTALL_PATH, "", $downloadFolder), "/")); - } - } - - function computeMinisiteToServerURL(){ - $minisite = parse_url($this->buildPublicDlURL(), PHP_URL_PATH) ."/a.php"; - $server = rtrim(parse_url( AJXP_Utils::detectServerURL(true), PHP_URL_PATH), "/"); - return AJXP_Utils::getTravelPath($minisite, $server); - } - - function buildPublicletLink($hash){ - $addLang = ConfService::getLanguage() != ConfService::getCoreConf("DEFAULT_LANGUAGE"); - if($this->getFilteredOption("USE_REWRITE_RULE", $this->repository->getId()) == true){ - if($addLang) return $this->buildPublicDlURL()."/".$hash."-".ConfService::getLanguage(); - else return $this->buildPublicDlURL()."/".$hash; - }else{ - if($addLang) return $this->buildPublicDlURL()."/".$hash.".php?lang=".ConfService::getLanguage(); - else return $this->buildPublicDlURL()."/".$hash.".php"; - } - } - - function initPublicFolder($downloadFolder){ - if(is_file($downloadFolder."/grid_t.png")){ - return; - } - $language = ConfService::getLanguage(); - $pDir = dirname(__FILE__); - $messages = array(); - if(is_file($pDir."/res/i18n/".$language.".php")){ - include($pDir."/res/i18n/".$language.".php"); - if(isSet($mess)){ - $messages = $mess; - } - }else{ - include($pDir."/res/i18n/en.php"); - } - $sTitle = sprintf($messages[1], ConfService::getCoreConf("APPLICATION_TITLE")); - $sLegend = $messages[20]; - - @copy($pDir."/res/dl.png", $downloadFolder."/dl.png"); - @copy($pDir."/res/grid_t.png", $downloadFolder."/grid_t.png"); - @copy($pDir."/res/button_cancel.png", $downloadFolder."/button_cancel.png"); - @copy(AJXP_INSTALL_PATH."/server/index.html", $downloadFolder."/index.html"); - $dlUrl = $this->buildPublicDlURL(); - $htaccessContent = "ErrorDocument 404 ".$dlUrl."/404.html\n\ndeny from all\n"; - if($this->getFilteredOption("USE_REWRITE_RULE", $this->repository->getId()) == true){ - $path = parse_url($dlUrl, PHP_URL_PATH); - $htaccessContent .= ' - - RewriteEngine on - RewriteBase '.$path.' - RewriteCond %{REQUEST_FILENAME} !-f - RewriteCond %{REQUEST_FILENAME} !-d - RewriteRule ^([a-z0-9]+)-([a-z]+)$ $1.php?lang=$2 [QSA] - RewriteRule ^([a-z0-9]+)$ $1.php [QSA] - - '; - } - file_put_contents($downloadFolder."/.htaccess", $htaccessContent); - $content404 = file_get_contents($pDir."/res/404.html"); - $content404 = str_replace(array("AJXP_MESSAGE_TITLE", "AJXP_MESSAGE_LEGEND"), array($sTitle, $sLegend), $content404); - file_put_contents($downloadFolder."/404.html", $content404); - - } - - static function loadMinisite($data){ - $repository = $data["REPOSITORY"]; - AJXP_PluginsService::getInstance()->initActivePlugins(); - $html = file_get_contents(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/action.share/res/minisite.php"); - AJXP_Controller::applyHook("tpl.filter_html", array(&$html)); - $html = AJXP_XMLWriter::replaceAjxpXmlKeywords($html); - $html = str_replace("AJXP_START_REPOSITORY", $repository, $html); - $html = str_replace("AJXP_REPOSITORY_LABEL", ConfService::getRepositoryById($repository)->getDisplay(), $html); - session_name("AjaXplorer_Shared"); - session_start(); - if(!empty($data["PRELOG_USER"])){ - AuthService::logUser($data["PRELOG_USER"], "", true); - $html = str_replace("AJXP_PRELOGED_USER", "ajxp_preloged_user", $html); - }else{ - $_SESSION["PENDING_REPOSITORY_ID"] = $repository; - $_SESSION["PENDING_FOLDER"] = "/"; - $html = str_replace("AJXP_PRELOGED_USER", "", $html); - } - if(isSet($_GET["lang"])) { - $loggedUser = &AuthService::getLoggedUser(); - if($loggedUser != null){ - $loggedUser->setPref("lang", $_GET["lang"]); - }else{ - setcookie("AJXP_lang", $_GET["lang"]); - } - } - - $tPath = (!empty($data["TRAVEL_PATH_TO_ROOT"]) ? $data["TRAVEL_PATH_TO_ROOT"] : "../.."); - $html = str_replace("AJXP_PATH_TO_ROOT", $tPath, $html); - HTMLWriter::internetExplorerMainDocumentHeader(); - HTMLWriter::charsetHeader(); - echo($html); - } - - /** - * @static - * @param Array $data - * @return void - */ - static function loadPubliclet($data) - { - // create driver from $data - $className = $data["DRIVER"]."AccessDriver"; - $hash = md5(serialize($data)); - $u = parse_url($_SERVER["REQUEST_URI"]); - $shortHash = pathinfo(basename($u["path"]), PATHINFO_FILENAME); - - if ( ($data["EXPIRE_TIME"] && time() > $data["EXPIRE_TIME"]) || - ($data["DOWNLOAD_LIMIT"] && $data["DOWNLOAD_LIMIT"]> 0 && $data["DOWNLOAD_LIMIT"] <= PublicletCounter::getCount($shortHash)) ) - { - // Remove the publiclet, it's done - if (strstr(realpath($_SERVER["SCRIPT_FILENAME"]),realpath(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"))) !== FALSE){ - PublicletCounter::delete($shortHash); - unlink($_SERVER["SCRIPT_FILENAME"]); - } - - echo "Link is expired, sorry."; - exit(); - } - // Load language messages - $language = "en"; - if(isSet($_GET["lang"])){ - $language = $_GET["lang"]; - } - $messages = array(); - if(is_file(dirname(__FILE__)."/res/i18n/".$language.".php")){ - include(dirname(__FILE__)."/res/i18n/".$language.".php"); - if(isSet($mess)) $messages = $mess; - }else{ - include(dirname(__FILE__)."/res/i18n/en.php"); - } - - $AJXP_LINK_HAS_PASSWORD = false; - $AJXP_LINK_BASENAME = SystemTextEncoding::toUTF8(basename($data["FILE_PATH"])); - $customs = array("title", "legend", "legend_pass", "background_attributes_1", "background_attributes_2", "background_attributes_3", "text_color", "background_color", "textshadow_color"); - $images = array("button", "background_1", "background_2", "background_3"); - $shareCenter = AJXP_PluginsService::findPlugin("action", "share"); - $confs = $shareCenter->getConfigs(); - foreach($customs as $custom){ - $varName = "CUSTOM_SHAREPAGE_".strtoupper($custom); - $$varName = $confs[$varName]; - } - $dlFolder = realpath(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")); - foreach($images as $custom){ - $varName = "CUSTOM_SHAREPAGE_".strtoupper($custom); - if(!empty($confs[$varName])){ - if(strpos($confs[$varName], "plugins/") === 0 && is_file(AJXP_INSTALL_PATH."/".$confs[$varName])){ - $realFile = AJXP_INSTALL_PATH."/".$confs[$varName]; - copy($realFile, $dlFolder."/binary-".basename($realFile)); - $$varName = "binary-".basename($realFile); - }else{ - $$varName = "binary-".$confs[$varName]; - if(is_file($dlFolder."/binary-".$confs[$varName])) continue; - $copiedImageName = $dlFolder."/binary-".$confs[$varName]; - $imgFile = fopen($copiedImageName, "wb"); - ConfService::getConfStorageImpl()->loadBinary(array(), $confs[$varName], $imgFile); - fclose($imgFile); - } - - } - } - - HTMLWriter::charsetHeader(); - // Check password - if (strlen($data["PASSWORD"])) - { - if (!isSet($_POST['password']) || ($_POST['password'] != $data["PASSWORD"])) - { - AJXP_PluginsService::getInstance()->initActivePlugins(); - $AJXP_LINK_HAS_PASSWORD = true; - $AJXP_LINK_WRONG_PASSWORD = (isSet($_POST['password']) && ($_POST['password'] != $data["PASSWORD"])); - include (AJXP_INSTALL_PATH."/plugins/action.share/res/public_links.php"); - $res = ('

    Build your own box with AjaXplorer : http://ajaxplorer.info/
    Community - Free non supported version © C. du Jeu 2008-2013
    '); - AJXP_Controller::applyHook("tpl.filter_html", array(&$res)); - echo($res); - return; - } - }else{ - if (!isSet($_GET["dl"])){ - AJXP_PluginsService::getInstance()->initActivePlugins(); - include (AJXP_INSTALL_PATH."/plugins/action.share/res/public_links.php"); - $res = '

    Build your own box with AjaXplorer : http://ajaxplorer.info/
    Community - Free non supported version © C. du Jeu 2008-2013
    '; - AJXP_Controller::applyHook("tpl.filter_html", array(&$res)); - echo($res); - return; - } - } - $filePath = AJXP_INSTALL_PATH."/plugins/access.".$data["DRIVER"]."/class.".$className.".php"; - if(!is_file($filePath)){ - die("Warning, cannot find driver for conf storage! ($className, $filePath)"); - } - require_once($filePath); - $driver = new $className($data["PLUGIN_ID"], $data["BASE_DIR"]); - $driver->loadManifest(); - - //$hash = md5(serialize($data)); - PublicletCounter::increment($shortHash); - - //AuthService::logUser($data["OWNER_ID"], "", true); - AuthService::logTemporaryUser($data["OWNER_ID"], $shortHash); - if($driver->hasMixin("credentials_consumer") && isSet($data["SAFE_USER"]) && isSet($data["SAFE_PASS"])){ - // FORCE SESSION MODE - AJXP_Safe::getInstance()->forceSessionCredentialsUsage(); - AJXP_Safe::storeCredentials($data["SAFE_USER"], $data["SAFE_PASS"]); - } - - $repoObject = $data["REPOSITORY"]; - ConfService::switchRootDir($repoObject->getId()); - ConfService::loadRepositoryDriver(); - AJXP_PluginsService::getInstance()->initActivePlugins(); - try{ - $params = array("file" => SystemTextEncoding::toUTF8($data["FILE_PATH"])); - if(isSet($data["PLUGINS_DATA"])){ - $params["PLUGINS_DATA"] = $data["PLUGINS_DATA"]; - } - if(isset($_GET["ct"]) && $_GET["ct"] == "true"){ - $mime = pathinfo($params["file"], PATHINFO_EXTENSION); - $editors = AJXP_PluginsService::searchAllManifests("//editor[contains(@mimes,'$mime') and @previewProvider='true']", "node", true, true, false); - if(count($editors)){ - foreach($editors as $editor){ - $xPath = new DOMXPath($editor->ownerDocument); - $callbacks = $xPath->query("//action[@contentTypedProvider]", $editor); - if($callbacks->length) { - $data["ACTION"] = $callbacks->item(0)->getAttribute("name"); - if($data["ACTION"] == "audio_proxy") $params["file"] = base64_encode($params["file"]); - break; - } - } - } - } - AJXP_Controller::findActionAndApply($data["ACTION"], $params, null); - register_shutdown_function(array("AuthService", "clearTemporaryUser"), $shortHash); - }catch (Exception $e){ - AuthService::clearTemporaryUser($shortHash); - die($e->getMessage()); - } - } - - /** - * @param String $repoId - * @param $mixUsersAndGroups - * @param $currentFileUrl - * @return array - */ - function computeSharedRepositoryAccessRights($repoId, $mixUsersAndGroups, $currentFileUrl){ - - $loggedUser = AuthService::getLoggedUser(); - $users = AuthService::getUsersForRepository($repoId); - $baseGroup = "/"; - $groups = AuthService::listChildrenGroups($baseGroup); - $mess = ConfService::getMessages(); - $groups[$baseGroup] = $mess["447"]; - $sharedEntries = array(); - if(!$mixUsersAndGroups){ - $sharedGroups = array(); - } - - foreach($groups as $gId => $gLabel){ - $r = AuthService::getRole("AJXP_GRP_".AuthService::filterBaseGroup($gId)); - if($r != null){ - $right = $r->getAcl($repoId); - if(!empty($right)){ - $entry = array( - "ID" => $gId, - "TYPE" => "group", - "LABEL" => $gLabel, - "RIGHT" => $right); - if(!$mixUsersAndGroups){ - $sharedGroups[$gId] = $entry; - }else{ - $sharedEntries[] = $entry; - } - } - } - } - - foreach ($users as $userId => $userObject) { - if($userObject->getId() == $loggedUser->getId()) continue; - $ri = $userObject->personalRole->getAcl($repoId); - $uLabel = $userObject->personalRole->filterParameterValue("core.conf", "USER_DISPLAY_NAME", AJXP_REPO_SCOPE_ALL, ""); - if(empty($uLabel)) $uLabel = $userId; - if(!empty($ri)){ - $entry = array( - "ID" => $userId, - "TYPE" => $userObject->hasParent()?"tmp_user":"user", - "LABEL" => $uLabel, - "RIGHT" => $userObject->personalRole->getAcl($repoId) - ); - if($this->watcher !== false){ - $entry["WATCH"] = $this->watcher->hasWatchOnNode( - new AJXP_Node($currentFileUrl), - $userId, - MetaWatchRegister::$META_WATCH_USERS_NAMESPACE - ); - } - if(!$mixUsersAndGroups){ - $sharedEntries[$userId] = $entry; - }else{ - $sharedEntries[] = $entry; - } - } - } - - if(!$mixUsersAndGroups){ - return array("USERS" => $sharedEntries, "GROUPS" => $sharedGroups); - } - return $sharedEntries; - - } - - /** - * @param $httpVars - * @param $repository - * @param $accessDriver - * @return array An array containing the hash (0) and the generated url (1) - */ - function createSharedMinisite($httpVars, $repository, $accessDriver){ - - $uniqueUser = null; - if(isSet($httpVars["create_guest_user"])){ - // Create a guest user - $userId = substr(md5(time()), 0, 12); - $pref = $this->getFilteredOption("SHARED_USERS_TMP_PREFIX", $this->repository->getId()); - if(!empty($pref)){ - $userId = $pref.$userId; - } - $userPass = substr(md5(time()), 13, 24); - $httpVars["user_0"] = $userId; - $httpVars["user_pass_0"] = $httpVars["shared_pass"] = $userPass; - $httpVars["entry_type_0"] = "user"; - $httpVars["right_read_0"] = (isSet($httpVars["simple_right_read"]) ? "true" : "false"); - $httpVars["right_write_0"] = (isSet($httpVars["simple_right_write"]) ? "true" : "false"); - $httpVars["right_watch_0"] = "false"; - $httpVars["disable_download"] = (isSet($httpVars["simple_right_download"]) ? false : true); - if($httpVars["right_write_0"] == "false" && $httpVars["right_read_0"] == "false"){ - return "share_center.58"; - } - if($httpVars["right_read_0"] == "false" && !$httpVars["disable_download"]){ - $httpVars["right_read_0"] = "true"; - } - $uniqueUser = $userId; - } - - $httpVars["minisite"] = true; - $newRepo = $this->createSharedRepository($httpVars, $repository, $accessDriver, $uniqueUser); - - if(!is_a($newRepo, "Repository")) return $newRepo; - - $newId = $newRepo->getId(); - $downloadFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); - $this->initPublicFolder($downloadFolder); - $data = array("REPOSITORY"=>$newId, "PRELOG_USER"=>$userId); - if($httpVars["disable_download"]){ - $data["DOWNLOAD_DISABLED"] = true; - } - $data["TRAVEL_PATH_TO_ROOT"] = $this->computeMinisiteToServerURL(); - - $outputData = serialize($data); - $hash = self::computeHash($outputData, $downloadFolder); - - $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); - $outputData = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $hash, $outputData, MCRYPT_MODE_ECB, $iv)); - $fileData = "<"."?"."php \n". - ' require_once("'.str_replace("\\", "/", AJXP_INSTALL_PATH).'/publicLet.inc.php"); '."\n". - ' $id = str_replace(".php", "", basename(__FILE__)); '."\n". // Not using "" as php would replace $ inside - ' $cypheredData = base64_decode("'.$outputData.'"); '."\n". - ' $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); '."\n". - ' $inputData = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $id, $cypheredData, MCRYPT_MODE_ECB, $iv), "\0"); '."\n". - ' if (!ShareCenter::checkHash($inputData, $id)) { header("HTTP/1.0 401 Not allowed, script was modified"); exit(); } '."\n". - ' // Ok extract the data '."\n". - ' $data = unserialize($inputData); ShareCenter::loadMinisite($data); '; - if (@file_put_contents($downloadFolder."/".$hash.".php", $fileData) === FALSE){ - return "Can't write to PUBLIC URL"; - } - @chmod($downloadFolder."/".$hash.".php", 0755); - - return array($hash, $this->buildPublicletLink($hash)); - - } - - /** - * @param Array $httpVars - * @param Repository $repository - * @param AbstractAccessDriver $accessDriver - * @param null $uniqueUser - * @throws Exception - * @return int|Repository - */ - function createSharedRepository($httpVars, $repository, $accessDriver, $uniqueUser = null){ - // ERRORS - // 100 : missing args - // 101 : repository label already exists - // 102 : user already exists - // 103 : current user is not allowed to share - // SUCCESS - // 200 - - if(!isSet($httpVars["repo_label"]) || $httpVars["repo_label"] == ""){ - return 100; - } - $loggedUser = AuthService::getLoggedUser(); - $actRights = $loggedUser->mergedRole->listActionsStatesFor($repository); - if(isSet($actRights["share"]) && $actRights["share"] === false){ - return 103; - } - $users = array(); - $uRights = array(); - $uPasses = array(); - $groups = array(); - - $index = 0; - $prefix = $this->getFilteredOption("SHARED_USERS_TMP_PREFIX", $this->repository->getId()); - while(isSet($httpVars["user_".$index])){ - $eType = $httpVars["entry_type_".$index]; - $rightString = ($httpVars["right_read_".$index]=="true"?"r":"").($httpVars["right_write_".$index]=="true"?"w":""); - if($this->watcher !== false) $uWatch = $httpVars["right_watch_".$index] == "true" ? true : false; - if(empty($rightString)) { - $index++; - continue; - } - if($eType == "user"){ - $u = AJXP_Utils::decodeSecureMagic($httpVars["user_".$index], AJXP_SANITIZE_ALPHANUM); - if(!AuthService::userExists($u) && !isSet($httpVars["user_pass_".$index])){ - return 100; - }else if(AuthService::userExists($u) && isSet($httpVars["user_pass_".$index])){ - throw new Exception("User $u already exists, please choose another name."); - } - if(!AuthService::userExists($u, "w") && !empty($prefix) - && strpos($u, $prefix)!==0 ){ - $u = $prefix . $u; - } - $users[] = $u; - }else{ - $u = AJXP_Utils::decodeSecureMagic($httpVars["user_".$index]); - $groups[] = $u; - } - $uRights[$u] = $rightString; - $uPasses[$u] = isSet($httpVars["user_pass_".$index])?$httpVars["user_pass_".$index]:""; - if($this->watcher !== false){ - $uWatches[$u] = $uWatch; - } - $index ++; - } - - $label = AJXP_Utils::decodeSecureMagic($httpVars["repo_label"]); - $description = AJXP_Utils::decodeSecureMagic($httpVars["repo_description"]); - if(isSet($httpVars["repository_id"])){ - $editingRepo = ConfService::getRepositoryById($httpVars["repository_id"]); - } - - // CHECK USER & REPO DOES NOT ALREADY EXISTS - if( $this->getFilteredOption("AVOID_SHARED_FOLDER_SAME_LABEL", $this->repository->getId()) == true) { - $repos = ConfService::getRepositoriesList(); - foreach ($repos as $obj){ - if($obj->getDisplay() == $label && (!isSet($editingRepo) || $editingRepo != $obj)){ - return 101; - } - } - } - - $confDriver = ConfService::getConfStorageImpl(); - foreach($users as $userName){ - if(AuthService::userExists($userName)){ - // check that it's a child user - $userObject = $confDriver->createUserObject($userName); - if( ConfService::getCoreConf("ALLOW_CROSSUSERS_SHARING", "conf") != true && ( !$userObject->hasParent() || $userObject->getParent() != $loggedUser->id ) ){ - return 102; - } - }else{ - if(AuthService::isReservedUserId($userName)){ - return 102; - } - if(!isSet($httpVars["shared_pass"]) || $httpVars["shared_pass"] == "") return 100; - } - } - - // CREATE SHARED OPTIONS - $options = $accessDriver->makeSharedRepositoryOptions($httpVars, $repository); - $customData = array(); - foreach($httpVars as $key => $value){ - if(substr($key, 0, strlen("PLUGINS_DATA_")) == "PLUGINS_DATA_"){ - $customData[substr($key, strlen("PLUGINS_DATA_"))] = $value; - } - } - if(count($customData)){ - $options["PLUGINS_DATA"] = $customData; - } - if(isSet($editingRepo)){ - $newRepo = $editingRepo; - if($editingRepo->getDisplay() != $label){ - $newRepo->setDisplay($label); - ConfService::replaceRepository($httpVars["repository_id"], $newRepo); - } - $editingRepo->setDescription($description); - }else{ - if($repository->getOption("META_SOURCES")){ - $options["META_SOURCES"] = $repository->getOption("META_SOURCES"); - foreach($options["META_SOURCES"] as $index => $data){ - if(isSet($data["USE_SESSION_CREDENTIALS"]) && $data["USE_SESSION_CREDENTIALS"] === true){ - $options["META_SOURCES"][$index]["ENCODED_CREDENTIALS"] = AJXP_Safe::getEncodedCredentialString(); - } - } - } - $newRepo = $repository->createSharedChild( - $label, - $options, - $repository->id, - $loggedUser->id, - null - ); - $gPath = $loggedUser->getGroupPath(); - if(!empty($gPath)){ - $newRepo->setGroupPath($gPath); - } - $newRepo->setDescription($description); - ConfService::addRepository($newRepo); - } - - $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); - - if(isSet($editingRepo)){ - - $currentRights = $this->computeSharedRepositoryAccessRights($httpVars["repository_id"], false, $this->urlBase.$file); - $originalUsers = array_keys($currentRights["USERS"]); - $removeUsers = array_diff($originalUsers, $users); - if(count($removeUsers)){ - foreach($removeUsers as $user){ - if(AuthService::userExists($user)){ - $userObject = $confDriver->createUserObject($user); - $userObject->personalRole->setAcl($newRepo->getUniqueId(), ""); - $userObject->save("superuser"); - } - } - } - $originalGroups = array_keys($currentRights["GROUPS"]); - $removeGroups = array_diff($originalGroups, $groups); - if(count($removeGroups)){ - foreach($removeGroups as $groupId){ - $role = AuthService::getRole("AJXP_GRP_".AuthService::filterBaseGroup($groupId)); - if($role !== false){ - $role->setAcl($newRepo->getUniqueId(), ""); - AuthService::updateRole($role); - } - } - } - } - - foreach($users as $userName){ - if(AuthService::userExists($userName, "w")){ - // check that it's a child user - $userObject = $confDriver->createUserObject($userName); - }else{ - if(ConfService::getAuthDriverImpl()->getOption("TRANSMIT_CLEAR_PASS")){ - $pass = $uPasses[$userName]; - }else{ - $pass = md5($uPasses[$userName]); - } - AuthService::createUser($userName, $pass); - $userObject = $confDriver->createUserObject($userName); - $userObject->personalRole->clearAcls(); - $userObject->setParent($loggedUser->id); - $userObject->setGroupPath($loggedUser->getGroupPath()); - $userObject->setProfile("shared"); - AJXP_Controller::applyHook("user.after_create", array($userObject)); - } - // CREATE USER WITH NEW REPO RIGHTS - $userObject->personalRole->setAcl($newRepo->getUniqueId(), $uRights[$userName]); - if(isSet($httpVars["minisite"])){ - $newRole = new AJXP_Role("AJXP_SHARED-".$newRepo->getUniqueId()); - $r = AuthService::getRole("MINISITE"); - if(is_a($r, "AJXP_Role")){ - if($httpVars["disable_download"]){ - $f = AuthService::getRole("MINISITE_NODOWNLOAD"); - if(is_a($f, "AJXP_Role")){ - $r = $f->override($r); - } - } - $allData = $r->getDataArray(); - $newData = $newRole->getDataArray(); - if(isSet($allData["ACTIONS"][AJXP_REPO_SCOPE_SHARED])) $newData["ACTIONS"][$newRepo->getUniqueId()] = $allData["ACTIONS"][AJXP_REPO_SCOPE_SHARED]; - if(isSet($allData["PARAMETERS"][AJXP_REPO_SCOPE_SHARED])) $newData["PARAMETERS"][$newRepo->getUniqueId()] = $allData["PARAMETERS"][AJXP_REPO_SCOPE_SHARED]; - $newRole->bunchUpdate($newData); - AuthService::updateRole($newRole); - $userObject->addRole($newRole); - } - } - $userObject->save("superuser"); - if($this->watcher !== false){ - // Register a watch on the current folder for shared user - if($uWatches[$userName] == "true"){ - $this->watcher->setWatchOnFolder( - new AJXP_Node($this->urlBase.$file), - $userName, - MetaWatchRegister::$META_WATCH_USERS_CHANGE, - array(AuthService::getLoggedUser()->getId()) - ); - }else{ - $this->watcher->removeWatchFromFolder( - new AJXP_Node($this->urlBase.$file), - $userName, - true - ); - } - } - } - - if($this->watcher !== false){ - // Register a watch on the new repository root for current user - if($httpVars["self_watch_folder"] == "true"){ - $this->watcher->setWatchOnFolder( - new AJXP_Node($this->baseProtocol."://".$newRepo->getUniqueId()."/"), - AuthService::getLoggedUser()->getId(), - MetaWatchRegister::$META_WATCH_BOTH); - }else{ - $this->watcher->removeWatchFromFolder( - new AJXP_Node($this->baseProtocol."://".$newRepo->getUniqueId()."/"), - AuthService::getLoggedUser()->getId()); - } - } - - foreach($groups as $group){ - $grRole = AuthService::getRole("AJXP_GRP_".AuthService::filterBaseGroup($group), true); - $grRole->setAcl($newRepo->getUniqueId(), $uRights[$group]); - AuthService::updateRole($grRole); - } - - return $newRepo; - } - - - /** - * @static - * @param String $type - * @param String $element - * @param AbstractAjxpUser $loggedUser - * @throws Exception - */ - public static function deleteSharedElement($type, $element, $loggedUser){ - $mess = ConfService::getMessages(); - AJXP_Logger::debug($type."-".$element); - if($type == "repository"){ - $repo = ConfService::getRepositoryById($element); - if($repo == null) return; - if(!$repo->hasOwner() || $repo->getOwner() != $loggedUser->getId()){ - throw new Exception($mess["ajxp_shared.12"]); - }else{ - $res = ConfService::deleteRepository($element); - if($res == -1){ - throw new Exception($mess["ajxp_conf.51"]); - } - } - }else if( $type == "minisite"){ - $minisiteData = self::loadPublicletData($element); - $repoId = $minisiteData["REPOSITORY"]; - $repo = ConfService::getRepositoryById($repoId); - if(!$repo->hasOwner() || $repo->getOwner() != $loggedUser->getId()){ - throw new Exception($mess["ajxp_shared.12"]); - }else{ - $res = ConfService::deleteRepository($repoId); - if($res == -1){ - throw new Exception($mess["ajxp_conf.51"]); - } - // Silently delete corresponding role if it exists - AuthService::deleteRole("AJXP_SHARED-".$repoId); - // If guest user created, remove it now. - if(isSet($minisiteData["PRELOG_USER"])){ - AuthService::deleteUser($minisiteData["PRELOG_USER"]); - } - unlink($minisiteData["PUBLICLET_PATH"]); - } - }else if( $type == "user" ){ - $confDriver = ConfService::getConfStorageImpl(); - $object = $confDriver->createUserObject($element); - if(!$object->hasParent() || $object->getParent() != $loggedUser->getId()){ - throw new Exception($mess["ajxp_shared.12"]); - }else{ - AuthService::deleteUser($element); - } - }else if( $type == "file" ){ - $publicletData = self::loadPublicletData($element); - if(isSet($publicletData["OWNER_ID"]) && $publicletData["OWNER_ID"] == $loggedUser->getId()){ - PublicletCounter::delete($element); - unlink($publicletData["PUBLICLET_PATH"]); - }else{ - throw new Exception($mess["ajxp_shared.12"]); - } - } - } - - public static function sharedElementExists($type, $element, $loggedUser){ - if($type == "repository"){ - return (ConfService::getRepositoryById($element) != null); - }else if($type == "file" || $type == "minisite"){ - $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); - return is_file($dlFolder."/".$element.".php"); - } - } - - - public static function loadPublicletData($id){ - $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); - $file = $dlFolder."/".$id.".php"; - if(!is_file($file)) return array(); - $lines = file($file); - $inputData = ''; - $code = $lines[3] . $lines[4] . $lines[5]; - eval($code); - $dataModified = self::checkHash($inputData, $id); //(md5($inputData) != $id); - $publicletData = unserialize($inputData); - $publicletData["SECURITY_MODIFIED"] = $dataModified; - if(!isSet($publicletData["REPOSITORY"])){ - $publicletData["DOWNLOAD_COUNT"] = PublicletCounter::getCount($id); - } - $publicletData["PUBLICLET_PATH"] = $file; - return $publicletData; - } - -} + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); + +require_once("class.PublicletCounter.php"); + +/** + * @package AjaXplorer_Plugins + * @subpackage Action + */ +class ShareCenter extends AJXP_Plugin +{ + /** + * @var AbstractAccessDriver + */ + private $accessDriver; + /** + * @var Repository + */ + private $repository; + private $urlBase; + private $baseProtocol; + + /** + * @var MetaStoreProvider + */ + private $metaStore; + + /** + * @var MetaWatchRegister + */ + private $watcher = false; + + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if (isSet($this->actions["share"])) { + $disableSharing = false; + $downloadFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); + if ($downloadFolder == "") { + $disableSharing = true; + } else if ((!is_dir($downloadFolder) || !is_writable($downloadFolder))) { + AJXP_Logger::debug("Disabling Public links, $downloadFolder is not writeable!", array("folder" => $downloadFolder, "is_dir" => is_dir($downloadFolder),"is_writeable" => is_writable($downloadFolder))); + $disableSharing = true; + } else { + if (AuthService::usersEnabled()) { + $loggedUser = AuthService::getLoggedUser(); + if ($loggedUser != null && AuthService::isReservedUserId($loggedUser->getId())) { + $disableSharing = true; + } + } else { + $disableSharing = true; + } + } + if ($disableSharing) { + unset($this->actions["share"]); + $actionXpath=new DOMXPath($contribNode->ownerDocument); + $publicUrlNodeList = $actionXpath->query('action[@name="share"]', $contribNode); + $publicUrlNode = $publicUrlNodeList->item(0); + $contribNode->removeChild($publicUrlNode); + } + } + } + + public function init($options) + { + parent::init($options); + $this->repository = ConfService::getRepository(); + if (!is_a($this->repository->driverInstance, "AjxpWrapperProvider")) { + return; + } + $this->accessDriver = $this->repository->driverInstance; + $this->urlBase = $this->repository->driverInstance->getResourceUrl("/"); + $this->baseProtocol = array_shift(explode("://", $this->urlBase)); + if (array_key_exists("meta.watch", AJXP_PluginsService::getInstance()->getActivePlugins())) { + $this->watcher = AJXP_PluginsService::getInstance()->getPluginById("meta.watch"); + } + } + + public function switchAction($action, $httpVars, $fileVars) + { + if (!isSet($this->accessDriver)) { + throw new Exception("Cannot find access driver!"); + } + + + if ($this->accessDriver->getId() == "access.demo") { + $errorMessage = "This is a demo, all 'write' actions are disabled!"; + if ($httpVars["sub_action"] == "delegate_repo") { + return AJXP_XMLWriter::sendMessage(null, $errorMessage, false); + } else { + print($errorMessage); + } + return; + } + + + switch ($action) { + + //------------------------------------ + // SHARING FILE OR FOLDER + //------------------------------------ + case "share": + $subAction = (isSet($httpVars["sub_action"])?$httpVars["sub_action"]:""); + $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + $ajxpNode = new AJXP_Node($this->urlBase.$file); + $metadata = null; + + if ($subAction == "delegate_repo") { + header("Content-type:text/plain"); + $result = $this->createSharedRepository($httpVars, $this->repository, $this->accessDriver); + if (is_a($result, "Repository")) { + $metadata = array("element" => $result->getUniqueId()); + $numResult = 200; + } else { + $numResult = $result; + } + print($numResult); + } else if ($subAction == "create_minisite") { + header("Content-type:text/plain"); + $res = $this->createSharedMinisite($httpVars, $this->repository, $this->accessDriver); + if (!is_array($res)) { + $url = $res; + } else { + list($hash, $url) = $res; + $metadata = array("element" => $hash, "minisite" => (isSet($httpVars["create_guest_user"])?"public":"private")); + } + print($url); + } else { + $maxdownload = $this->getFilteredOption("FILE_MAX_DOWNLOAD", $this->repository->getId()); + if (!isSet($httpVars["downloadlimit"]) || $httpVars["downloadlimit"] == 0) { + $httpVars["downloadlimit"] = $maxdownload; + } else { + $httpVars["downloadlimit"] = min($maxdownload,floor(abs($httpVars["downloadlimit"]))); + } + $maxexpiration = $this->getFilteredOption("FILE_MAX_EXPIRATION", $this->repository->getId()); + if (!isSet($httpVars["expiration"]) || $httpVars["expiration"] == 0) { + $httpVars["expiration"] = $maxexpiration; + } else { + $httpVars["expiration"] = min($maxexpiration,floor(abs($httpVars["expiration"]))); + } + + $data = $this->accessDriver->makePublicletOptions($file, $httpVars["password"], $httpVars["expiration"], $httpVars["downloadlimit"], $this->repository); + $customData = array(); + foreach ($httpVars as $key => $value) { + if (substr($key, 0, strlen("PLUGINS_DATA_")) == "PLUGINS_DATA_") { + $customData[substr($key, strlen("PLUGINS_DATA_"))] = $value; + } + } + if (count($customData)) { + $data["PLUGINS_DATA"] = $customData; + } + list($hash, $url) = $this->writePubliclet($data, $this->accessDriver, $this->repository); + $metadata = array("element" => $hash); + header("Content-type:text/plain"); + echo $url; + } + if ($metadata != null && $ajxpNode->hasMetaStore()) { + $ajxpNode->setMetadata( + "ajxp_shared", + $metadata, + true, + AJXP_METADATA_SCOPE_REPOSITORY, + true + ); + } + AJXP_Controller::applyHook("msg.instant", array("", ConfService::getRepository()->getId())); + // as the result can be quite small (e.g error code), make sure it's output in case of OB active. + flush(); + + break; + + case "toggle_link_watch": + + $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + $watchValue = $httpVars["set_watch"] == "true" ? true : false; + $node = new AJXP_Node($this->urlBase.$file); + $metadata = $node->retrieveMetadata( + "ajxp_shared", + true, + AJXP_METADATA_SCOPE_REPOSITORY + ); + $elementId = $metadata["element"]; + + if ($this->watcher !== false) { + if ($watchValue) { + $this->watcher->setWatchOnFolder( + $node, + AuthService::getLoggedUser()->getId(), + MetaWatchRegister::$META_WATCH_USERS_READ, + array($elementId) + ); + } else { + $this->watcher->removeWatchFromFolder( + $node, + AuthService::getLoggedUser()->getId(), + true + ); + } + } + $mess = ConfService::getMessages(); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::sendMessage($mess["share_center.47"], null); + AJXP_XMLWriter::close(); + + break; + + case "load_shared_element_data": + + $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + $elementType = $httpVars["element_type"]; + $messages = ConfService::getMessages(); + $node = new AJXP_Node($this->urlBase.$file); + + $metadata = $node->retrieveMetadata( + "ajxp_shared", + true, + AJXP_METADATA_SCOPE_REPOSITORY + ); + $elementWatch = false; + if (count($metadata)) { + header("Content-type:application/json"); + + if ($elementType == "file") { + $pData = self::loadPublicletData($metadata["element"]); + if ($pData["OWNER_ID"] != AuthService::getLoggedUser()->getId()) { + throw new Exception($messages["share_center.48"]); + } + if (isSet($metadata["short_form_url"])) { + $link = $metadata["short_form_url"]; + } else { + $link = $this->buildPublicletLink($metadata["element"]); + } + if ($this->watcher != false) { + $elementWatch = $this->watcher->hasWatchOnNode( + $node, + AuthService::getLoggedUser()->getId(), + MetaWatchRegister::$META_WATCH_USERS_NAMESPACE + ); + } + $jsonData = array( + "publiclet_link" => $link, + "download_counter" => PublicletCounter::getCount($metadata["element"]), + "download_limit" => $pData["DOWNLOAD_LIMIT"], + "expire_time" => ($pData["EXPIRE_TIME"]!=0?date($messages["date_format"], $pData["EXPIRE_TIME"]):0), + "has_password" => (!empty($pData["PASSWORD"])), + "element_watch" => $elementWatch + ); + } else if ($elementType == "repository") { + if (isSet($metadata["minisite"])) { + $minisiteData = self::loadPublicletData($metadata["element"]); + $repoId = $minisiteData["REPOSITORY"]; + $minisiteIsPublic = isSet($minisiteData["PRELOG_USER"]); + $dlDisabled = isSet($minisiteData["DOWNLOAD_DISABLED"]); + if (isSet($metadata["short_form_url"])) { + $minisiteLink = $metadata["short_form_url"]; + } else { + $minisiteLink = $this->buildPublicletLink($metadata["element"]); + } + } else { + $repoId = $metadata["element"]; + } + $repo = ConfService::getRepositoryById($repoId); + if ($repo == null || $repo->getOwner() != AuthService::getLoggedUser()->getId()) { + throw new Exception($messages["share_center.48"]); + } + if ($this->watcher != false) { + $elementWatch = $this->watcher->hasWatchOnNode( + new AJXP_Node($this->baseProtocol."://".$repoId."/"), + AuthService::getLoggedUser()->getId(), + MetaWatchRegister::$META_WATCH_NAMESPACE + ); + } + $sharedEntries = $this->computeSharedRepositoryAccessRights($repoId, true, $this->urlBase.$file); + + $jsonData = array( + "repositoryId" => $repoId, + "label" => $repo->getDisplay(), + "description" => $repo->getDescription(), + "entries" => $sharedEntries, + "element_watch" => $elementWatch, + "repository_url"=> AJXP_Utils::detectServerURL(true)."?goto=". $repo->getSlug() ."/" + ); + if (isSet($minisiteData)) { + $jsonData["minisite"] = array( + "public" => $minisiteIsPublic?"true":"false", + "public_link" => $minisiteLink, + "disable_download" => $dlDisabled + ); + + } + } + echo json_encode($jsonData); + } + + + break; + + case "unshare": + $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + $ajxpNode = new AJXP_Node($this->urlBase.$file); + $metadata = $ajxpNode->retrieveMetadata( + "ajxp_shared", + true, + AJXP_METADATA_SCOPE_REPOSITORY + ); + if (count($metadata)) { + $eType = $httpVars["element_type"]; + if(isSet($metadata["minisite"])) $eType = "minisite"; + self::deleteSharedElement($eType, $metadata["element"], AuthService::getLoggedUser()); + $ajxpNode->removeMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true); + } + AJXP_Controller::applyHook("msg.instant", array("", ConfService::getRepository()->getId())); + + break; + + case "reset_counter": + $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + $ajxpNode = new AJXP_Node($this->urlBase.$file); + $metadata = $ajxpNode->retrieveMetadata( + "ajxp_shared", + true, + AJXP_METADATA_SCOPE_REPOSITORY + ); + if (isSet($metadata["element"])) { + PublicletCounter::reset($metadata["element"]); + } + break; + + default: + break; + } + + + } + + + /** + * @param AJXP_Node $ajxpNode + * @return void + */ + public function nodeSharedMetadata(&$ajxpNode) + { + if($this->accessDriver->getId() == "access.imap") return; + $metadata = $ajxpNode->retrieveMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true); + if (count($metadata)) { + $eType = $ajxpNode->isLeaf()?"file":"repository"; + if(isSet($metadata["minisite"])) $eType = "minisite"; + if (!self::sharedElementExists($eType, $metadata["element"], AuthService::getLoggedUser())) { + $ajxpNode->removeMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true); + return; + } + $merge = array( + "ajxp_shared" => "true", + "overlay_icon" => "shared.png" + ); + if($eType == "minisite") $merge["ajxp_shared_minisite"] = $metadata["minisite"]; + $ajxpNode->mergeMetadata($merge, true); + } + } + + /** + * + * Hooked to node.change, this will update the index + * if $oldNode = null => create node $newNode + * if $newNode = null => delete node $oldNode + * Else copy or move oldNode to newNode. + * + * @param AJXP_Node $oldNode + */ + public function updateNodeSharedData($oldNode/*, $newNode = null, $copy = false*/) + { + if($this->accessDriver->getId() == "access.imap") return; + if($oldNode == null || !$oldNode->hasMetaStore()) return; + $metadata = $oldNode->retrieveMetadata("ajxp_shared", true); + if (count($metadata) && !empty($metadata["element"])) { + // TODO + // Make sure node info is loaded, to check if it's a dir or a file. + // Maybe could be directly embedded in metadata, to avoid having to load here. + $oldNode->loadNodeInfo(); + try { + self::deleteSharedElement( + ($oldNode->isLeaf()?"file":"repository"), + $metadata["element"], + AuthService::getLoggedUser() + ); + $oldNode->removeMetadata("ajxp_shared", true, AJXP_METADATA_SCOPE_REPOSITORY, true); + } catch (Exception $e) { + AJXP_Logger::logAction("ERROR : ".$e->getMessage(), $e->getTrace() ); + } + } + } + + /** Cypher the publiclet object data and write to disk. + * @param Array $data The publiclet data array to write + The data array must have the following keys: + - DRIVER The driver used to get the file's content + - OPTIONS The driver options to be successfully constructed (usually, the user and password) + - FILE_PATH The path to the file's content + - PASSWORD If set, the written publiclet will ask for this password before sending the content + - ACTION If set, action to perform + - USER If set, the AJXP user + - EXPIRE_TIME If set, the publiclet will deny downloading after this time, and probably self destruct. + * - AUTHOR_WATCH If set, will post notifications for the publiclet author each time the file is loaded + * @param AbstractAccessDriver $accessDriver + * @param Repository $repository + * @return array An array containing the hash (0) and the generated url (1) + */ + public function writePubliclet(&$data, $accessDriver, $repository) + { + $downloadFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); + if (!is_dir($downloadFolder)) { + return "ERROR : Public URL folder does not exist!"; + } + if (!function_exists("mcrypt_create_iv")) { + return "ERROR : MCrypt must be installed to use publiclets!"; + } + $this->initPublicFolder($downloadFolder); + $data["PLUGIN_ID"] = $accessDriver->getId(); + $data["BASE_DIR"] = $accessDriver->getBaseDir(); + //$data["REPOSITORY"] = $repository; + if (AuthService::usersEnabled()) { + $data["OWNER_ID"] = AuthService::getLoggedUser()->getId(); + } + if ($accessDriver->hasMixin("credentials_consumer")) { + $cred = AJXP_Safe::tryLoadingCredentialsFromSources(array(), $repository); + if (isSet($cred["user"]) && isset($cred["password"])) { + $data["SAFE_USER"] = $cred["user"]; + $data["SAFE_PASS"] = $cred["password"]; + } + } + // Force expanded path in publiclet + $copy = clone $repository; + $copy->addOption("PATH", $repository->getOption("PATH")); + $data["REPOSITORY"] = $copy; + if ($data["ACTION"] == "") $data["ACTION"] = "download"; + // Create a random key + $data["FINAL_KEY"] = md5(mt_rand().time()); + // Cypher the data with a random key + $outputData = serialize($data); + // Hash the data to make sure it wasn't modified + $hash = $this->computeHash($outputData, $downloadFolder); // md5($outputData); + + $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); + $outputData = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $hash, $outputData, MCRYPT_MODE_ECB, $iv)); + $fileData = "<"."?"."php \n". + ' require_once("'.str_replace("\\", "/", AJXP_INSTALL_PATH).'/publicLet.inc.php"); '."\n". + ' $id = str_replace(".php", "", basename(__FILE__)); '."\n". // Not using "" as php would replace $ inside + ' $cypheredData = base64_decode("'.$outputData.'"); '."\n". + ' $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); '."\n". + ' $inputData = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $id, $cypheredData, MCRYPT_MODE_ECB, $iv), "\0"); '."\n". + ' if (!ShareCenter::checkHash($inputData, $id)) { header("HTTP/1.0 401 Not allowed, script was modified"); exit(); } '."\n". + ' // Ok extract the data '."\n". + ' $data = unserialize($inputData); ShareCenter::loadPubliclet($data); '; + if (@file_put_contents($downloadFolder."/".$hash.".php", $fileData) === FALSE) { + return "Can't write to PUBLIC URL"; + } + @chmod($downloadFolder."/".$hash.".php", 0755); + PublicletCounter::reset($hash); + return array($hash, $this->buildPublicletLink($hash)); + } + + /** + * Computes a short form of the hash, checking if it already exists in the folder, + * in which case it increases the hashlength until there is no collision. + * @static + * @param String $outputData Serialized data + * @param String|null $checkInFolder Path to folder + * @return string + */ + public function computeHash($outputData, $checkInFolder = null) + { + $length = $this->getFilteredOption("HASH_MIN_LENGTH", $this->repository->getId()); + $full = md5($outputData); + $starter = substr($full, 0, $length); + if ($checkInFolder != null) { + while (file_exists($checkInFolder.DIRECTORY_SEPARATOR.$starter.".php")) { + $length ++; + $starter = substr($full, 0, $length); + } + } + return $starter; + } + + /** + * Check if the hash seems to correspond to the serialized data. + * @static + * @param String $outputData serialized data + * @param String $hash Id to check + * @return bool + */ + public static function checkHash($outputData, $hash) + { + $full = md5($outputData); + return (!empty($hash) && strpos($full, $hash) === 0); + } + + public function buildPublicDlURL() + { + $downloadFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); + $dlURL = ConfService::getCoreConf("PUBLIC_DOWNLOAD_URL"); + $langSuffix = "?lang=".ConfService::getLanguage(); + if ($dlURL != "") { + return rtrim($dlURL, "/"); + } else { + $fullUrl = AJXP_Utils::detectServerURL() . dirname($_SERVER['REQUEST_URI']); + return str_replace("\\", "/", rtrim($fullUrl, "/").rtrim(str_replace(AJXP_INSTALL_PATH, "", $downloadFolder), "/")); + } + } + + public function computeMinisiteToServerURL() + { + $minisite = parse_url($this->buildPublicDlURL(), PHP_URL_PATH) ."/a.php"; + $server = rtrim(parse_url( AJXP_Utils::detectServerURL(true), PHP_URL_PATH), "/"); + return AJXP_Utils::getTravelPath($minisite, $server); + } + + public function buildPublicletLink($hash) + { + $addLang = ConfService::getLanguage() != ConfService::getCoreConf("DEFAULT_LANGUAGE"); + if ($this->getFilteredOption("USE_REWRITE_RULE", $this->repository->getId()) == true) { + if($addLang) return $this->buildPublicDlURL()."/".$hash."-".ConfService::getLanguage(); + else return $this->buildPublicDlURL()."/".$hash; + } else { + if($addLang) return $this->buildPublicDlURL()."/".$hash.".php?lang=".ConfService::getLanguage(); + else return $this->buildPublicDlURL()."/".$hash.".php"; + } + } + + public function initPublicFolder($downloadFolder) + { + if (is_file($downloadFolder."/grid_t.png")) { + return; + } + $language = ConfService::getLanguage(); + $pDir = dirname(__FILE__); + $messages = array(); + if (is_file($pDir."/res/i18n/".$language.".php")) { + include($pDir."/res/i18n/".$language.".php"); + if (isSet($mess)) { + $messages = $mess; + } + } else { + include($pDir."/res/i18n/en.php"); + } + $sTitle = sprintf($messages[1], ConfService::getCoreConf("APPLICATION_TITLE")); + $sLegend = $messages[20]; + + @copy($pDir."/res/dl.png", $downloadFolder."/dl.png"); + @copy($pDir."/res/grid_t.png", $downloadFolder."/grid_t.png"); + @copy($pDir."/res/button_cancel.png", $downloadFolder."/button_cancel.png"); + @copy(AJXP_INSTALL_PATH."/server/index.html", $downloadFolder."/index.html"); + $dlUrl = $this->buildPublicDlURL(); + $htaccessContent = "ErrorDocument 404 ".$dlUrl."/404.html\n\ndeny from all\n"; + if ($this->getFilteredOption("USE_REWRITE_RULE", $this->repository->getId()) == true) { + $path = parse_url($dlUrl, PHP_URL_PATH); + $htaccessContent .= ' + + RewriteEngine on + RewriteBase '.$path.' + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^([a-z0-9]+)-([a-z]+)$ $1.php?lang=$2 [QSA] + RewriteRule ^([a-z0-9]+)$ $1.php [QSA] + + '; + } + file_put_contents($downloadFolder."/.htaccess", $htaccessContent); + $content404 = file_get_contents($pDir."/res/404.html"); + $content404 = str_replace(array("AJXP_MESSAGE_TITLE", "AJXP_MESSAGE_LEGEND"), array($sTitle, $sLegend), $content404); + file_put_contents($downloadFolder."/404.html", $content404); + + } + + public static function loadMinisite($data) + { + $repository = $data["REPOSITORY"]; + AJXP_PluginsService::getInstance()->initActivePlugins(); + $html = file_get_contents(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/action.share/res/minisite.php"); + AJXP_Controller::applyHook("tpl.filter_html", array(&$html)); + $html = AJXP_XMLWriter::replaceAjxpXmlKeywords($html); + $html = str_replace("AJXP_START_REPOSITORY", $repository, $html); + $html = str_replace("AJXP_REPOSITORY_LABEL", ConfService::getRepositoryById($repository)->getDisplay(), $html); + session_name("AjaXplorer_Shared"); + session_start(); + if (!empty($data["PRELOG_USER"])) { + AuthService::logUser($data["PRELOG_USER"], "", true); + $html = str_replace("AJXP_PRELOGED_USER", "ajxp_preloged_user", $html); + } else { + $_SESSION["PENDING_REPOSITORY_ID"] = $repository; + $_SESSION["PENDING_FOLDER"] = "/"; + $html = str_replace("AJXP_PRELOGED_USER", "", $html); + } + if (isSet($_GET["lang"])) { + $loggedUser = &AuthService::getLoggedUser(); + if ($loggedUser != null) { + $loggedUser->setPref("lang", $_GET["lang"]); + } else { + setcookie("AJXP_lang", $_GET["lang"]); + } + } + + $tPath = (!empty($data["TRAVEL_PATH_TO_ROOT"]) ? $data["TRAVEL_PATH_TO_ROOT"] : "../.."); + $html = str_replace("AJXP_PATH_TO_ROOT", $tPath, $html); + HTMLWriter::internetExplorerMainDocumentHeader(); + HTMLWriter::charsetHeader(); + echo($html); + } + + /** + * @static + * @param Array $data + * @return void + */ + public static function loadPubliclet($data) + { + // create driver from $data + $className = $data["DRIVER"]."AccessDriver"; + $hash = md5(serialize($data)); + $u = parse_url($_SERVER["REQUEST_URI"]); + $shortHash = pathinfo(basename($u["path"]), PATHINFO_FILENAME); + + if ( ($data["EXPIRE_TIME"] && time() > $data["EXPIRE_TIME"]) || + ($data["DOWNLOAD_LIMIT"] && $data["DOWNLOAD_LIMIT"]> 0 && $data["DOWNLOAD_LIMIT"] <= PublicletCounter::getCount($shortHash)) ) + { + // Remove the publiclet, it's done + if (strstr(realpath($_SERVER["SCRIPT_FILENAME"]),realpath(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"))) !== FALSE) { + PublicletCounter::delete($shortHash); + unlink($_SERVER["SCRIPT_FILENAME"]); + } + + echo "Link is expired, sorry."; + exit(); + } + // Load language messages + $language = "en"; + if (isSet($_GET["lang"])) { + $language = $_GET["lang"]; + } + $messages = array(); + if (is_file(dirname(__FILE__)."/res/i18n/".$language.".php")) { + include(dirname(__FILE__)."/res/i18n/".$language.".php"); + if(isSet($mess)) $messages = $mess; + } else { + include(dirname(__FILE__)."/res/i18n/en.php"); + } + + $AJXP_LINK_HAS_PASSWORD = false; + $AJXP_LINK_BASENAME = SystemTextEncoding::toUTF8(basename($data["FILE_PATH"])); + $customs = array("title", "legend", "legend_pass", "background_attributes_1", "background_attributes_2", "background_attributes_3", "text_color", "background_color", "textshadow_color"); + $images = array("button", "background_1", "background_2", "background_3"); + $shareCenter = AJXP_PluginsService::findPlugin("action", "share"); + $confs = $shareCenter->getConfigs(); + foreach ($customs as $custom) { + $varName = "CUSTOM_SHAREPAGE_".strtoupper($custom); + $$varName = $confs[$varName]; + } + $dlFolder = realpath(ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER")); + foreach ($images as $custom) { + $varName = "CUSTOM_SHAREPAGE_".strtoupper($custom); + if (!empty($confs[$varName])) { + if (strpos($confs[$varName], "plugins/") === 0 && is_file(AJXP_INSTALL_PATH."/".$confs[$varName])) { + $realFile = AJXP_INSTALL_PATH."/".$confs[$varName]; + copy($realFile, $dlFolder."/binary-".basename($realFile)); + $$varName = "binary-".basename($realFile); + } else { + $$varName = "binary-".$confs[$varName]; + if(is_file($dlFolder."/binary-".$confs[$varName])) continue; + $copiedImageName = $dlFolder."/binary-".$confs[$varName]; + $imgFile = fopen($copiedImageName, "wb"); + ConfService::getConfStorageImpl()->loadBinary(array(), $confs[$varName], $imgFile); + fclose($imgFile); + } + + } + } + + HTMLWriter::charsetHeader(); + // Check password + if (strlen($data["PASSWORD"])) { + if (!isSet($_POST['password']) || ($_POST['password'] != $data["PASSWORD"])) { + AJXP_PluginsService::getInstance()->initActivePlugins(); + $AJXP_LINK_HAS_PASSWORD = true; + $AJXP_LINK_WRONG_PASSWORD = (isSet($_POST['password']) && ($_POST['password'] != $data["PASSWORD"])); + include (AJXP_INSTALL_PATH."/plugins/action.share/res/public_links.php"); + $res = ('

    Build your own box with AjaXplorer : http://ajaxplorer.info/
    Community - Free non supported version © C. du Jeu 2008-2013
    '); + AJXP_Controller::applyHook("tpl.filter_html", array(&$res)); + echo($res); + return; + } + } else { + if (!isSet($_GET["dl"])) { + AJXP_PluginsService::getInstance()->initActivePlugins(); + include (AJXP_INSTALL_PATH."/plugins/action.share/res/public_links.php"); + $res = '

    Build your own box with AjaXplorer : http://ajaxplorer.info/
    Community - Free non supported version © C. du Jeu 2008-2013
    '; + AJXP_Controller::applyHook("tpl.filter_html", array(&$res)); + echo($res); + return; + } + } + $filePath = AJXP_INSTALL_PATH."/plugins/access.".$data["DRIVER"]."/class.".$className.".php"; + if (!is_file($filePath)) { + die("Warning, cannot find driver for conf storage! ($className, $filePath)"); + } + require_once($filePath); + $driver = new $className($data["PLUGIN_ID"], $data["BASE_DIR"]); + $driver->loadManifest(); + + //$hash = md5(serialize($data)); + PublicletCounter::increment($shortHash); + + //AuthService::logUser($data["OWNER_ID"], "", true); + AuthService::logTemporaryUser($data["OWNER_ID"], $shortHash); + if ($driver->hasMixin("credentials_consumer") && isSet($data["SAFE_USER"]) && isSet($data["SAFE_PASS"])) { + // FORCE SESSION MODE + AJXP_Safe::getInstance()->forceSessionCredentialsUsage(); + AJXP_Safe::storeCredentials($data["SAFE_USER"], $data["SAFE_PASS"]); + } + + $repoObject = $data["REPOSITORY"]; + ConfService::switchRootDir($repoObject->getId()); + ConfService::loadRepositoryDriver(); + AJXP_PluginsService::getInstance()->initActivePlugins(); + try { + $params = array("file" => SystemTextEncoding::toUTF8($data["FILE_PATH"])); + if (isSet($data["PLUGINS_DATA"])) { + $params["PLUGINS_DATA"] = $data["PLUGINS_DATA"]; + } + if (isset($_GET["ct"]) && $_GET["ct"] == "true") { + $mime = pathinfo($params["file"], PATHINFO_EXTENSION); + $editors = AJXP_PluginsService::searchAllManifests("//editor[contains(@mimes,'$mime') and @previewProvider='true']", "node", true, true, false); + if (count($editors)) { + foreach ($editors as $editor) { + $xPath = new DOMXPath($editor->ownerDocument); + $callbacks = $xPath->query("//action[@contentTypedProvider]", $editor); + if ($callbacks->length) { + $data["ACTION"] = $callbacks->item(0)->getAttribute("name"); + if($data["ACTION"] == "audio_proxy") $params["file"] = base64_encode($params["file"]); + break; + } + } + } + } + AJXP_Controller::findActionAndApply($data["ACTION"], $params, null); + register_shutdown_function(array("AuthService", "clearTemporaryUser"), $shortHash); + } catch (Exception $e) { + AuthService::clearTemporaryUser($shortHash); + die($e->getMessage()); + } + } + + /** + * @param String $repoId + * @param $mixUsersAndGroups + * @param $currentFileUrl + * @return array + */ + public function computeSharedRepositoryAccessRights($repoId, $mixUsersAndGroups, $currentFileUrl) + { + $loggedUser = AuthService::getLoggedUser(); + $users = AuthService::getUsersForRepository($repoId); + $baseGroup = "/"; + $groups = AuthService::listChildrenGroups($baseGroup); + $mess = ConfService::getMessages(); + $groups[$baseGroup] = $mess["447"]; + $sharedEntries = array(); + if (!$mixUsersAndGroups) { + $sharedGroups = array(); + } + + foreach ($groups as $gId => $gLabel) { + $r = AuthService::getRole("AJXP_GRP_".AuthService::filterBaseGroup($gId)); + if ($r != null) { + $right = $r->getAcl($repoId); + if (!empty($right)) { + $entry = array( + "ID" => $gId, + "TYPE" => "group", + "LABEL" => $gLabel, + "RIGHT" => $right); + if (!$mixUsersAndGroups) { + $sharedGroups[$gId] = $entry; + } else { + $sharedEntries[] = $entry; + } + } + } + } + + foreach ($users as $userId => $userObject) { + if($userObject->getId() == $loggedUser->getId()) continue; + $ri = $userObject->personalRole->getAcl($repoId); + $uLabel = $userObject->personalRole->filterParameterValue("core.conf", "USER_DISPLAY_NAME", AJXP_REPO_SCOPE_ALL, ""); + if(empty($uLabel)) $uLabel = $userId; + if (!empty($ri)) { + $entry = array( + "ID" => $userId, + "TYPE" => $userObject->hasParent()?"tmp_user":"user", + "LABEL" => $uLabel, + "RIGHT" => $userObject->personalRole->getAcl($repoId) + ); + if ($this->watcher !== false) { + $entry["WATCH"] = $this->watcher->hasWatchOnNode( + new AJXP_Node($currentFileUrl), + $userId, + MetaWatchRegister::$META_WATCH_USERS_NAMESPACE + ); + } + if (!$mixUsersAndGroups) { + $sharedEntries[$userId] = $entry; + } else { + $sharedEntries[] = $entry; + } + } + } + + if (!$mixUsersAndGroups) { + return array("USERS" => $sharedEntries, "GROUPS" => $sharedGroups); + } + return $sharedEntries; + + } + + /** + * @param $httpVars + * @param $repository + * @param $accessDriver + * @return array An array containing the hash (0) and the generated url (1) + */ + public function createSharedMinisite($httpVars, $repository, $accessDriver) + { + $uniqueUser = null; + if (isSet($httpVars["create_guest_user"])) { + // Create a guest user + $userId = substr(md5(time()), 0, 12); + $pref = $this->getFilteredOption("SHARED_USERS_TMP_PREFIX", $this->repository->getId()); + if (!empty($pref)) { + $userId = $pref.$userId; + } + $userPass = substr(md5(time()), 13, 24); + $httpVars["user_0"] = $userId; + $httpVars["user_pass_0"] = $httpVars["shared_pass"] = $userPass; + $httpVars["entry_type_0"] = "user"; + $httpVars["right_read_0"] = (isSet($httpVars["simple_right_read"]) ? "true" : "false"); + $httpVars["right_write_0"] = (isSet($httpVars["simple_right_write"]) ? "true" : "false"); + $httpVars["right_watch_0"] = "false"; + $httpVars["disable_download"] = (isSet($httpVars["simple_right_download"]) ? false : true); + if ($httpVars["right_write_0"] == "false" && $httpVars["right_read_0"] == "false") { + return "share_center.58"; + } + if ($httpVars["right_read_0"] == "false" && !$httpVars["disable_download"]) { + $httpVars["right_read_0"] = "true"; + } + $uniqueUser = $userId; + } + + $httpVars["minisite"] = true; + $newRepo = $this->createSharedRepository($httpVars, $repository, $accessDriver, $uniqueUser); + + if(!is_a($newRepo, "Repository")) return $newRepo; + + $newId = $newRepo->getId(); + $downloadFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); + $this->initPublicFolder($downloadFolder); + $data = array("REPOSITORY"=>$newId, "PRELOG_USER"=>$userId); + if ($httpVars["disable_download"]) { + $data["DOWNLOAD_DISABLED"] = true; + } + $data["TRAVEL_PATH_TO_ROOT"] = $this->computeMinisiteToServerURL(); + + $outputData = serialize($data); + $hash = self::computeHash($outputData, $downloadFolder); + + $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); + $outputData = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $hash, $outputData, MCRYPT_MODE_ECB, $iv)); + $fileData = "<"."?"."php \n". + ' require_once("'.str_replace("\\", "/", AJXP_INSTALL_PATH).'/publicLet.inc.php"); '."\n". + ' $id = str_replace(".php", "", basename(__FILE__)); '."\n". // Not using "" as php would replace $ inside + ' $cypheredData = base64_decode("'.$outputData.'"); '."\n". + ' $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND); '."\n". + ' $inputData = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $id, $cypheredData, MCRYPT_MODE_ECB, $iv), "\0"); '."\n". + ' if (!ShareCenter::checkHash($inputData, $id)) { header("HTTP/1.0 401 Not allowed, script was modified"); exit(); } '."\n". + ' // Ok extract the data '."\n". + ' $data = unserialize($inputData); ShareCenter::loadMinisite($data); '; + if (@file_put_contents($downloadFolder."/".$hash.".php", $fileData) === FALSE) { + return "Can't write to PUBLIC URL"; + } + @chmod($downloadFolder."/".$hash.".php", 0755); + + return array($hash, $this->buildPublicletLink($hash)); + + } + + /** + * @param Array $httpVars + * @param Repository $repository + * @param AbstractAccessDriver $accessDriver + * @param null $uniqueUser + * @throws Exception + * @return int|Repository + */ + public function createSharedRepository($httpVars, $repository, $accessDriver, $uniqueUser = null) + { + // ERRORS + // 100 : missing args + // 101 : repository label already exists + // 102 : user already exists + // 103 : current user is not allowed to share + // SUCCESS + // 200 + + if (!isSet($httpVars["repo_label"]) || $httpVars["repo_label"] == "") { + return 100; + } + $loggedUser = AuthService::getLoggedUser(); + $actRights = $loggedUser->mergedRole->listActionsStatesFor($repository); + if (isSet($actRights["share"]) && $actRights["share"] === false) { + return 103; + } + $users = array(); + $uRights = array(); + $uPasses = array(); + $groups = array(); + + $index = 0; + $prefix = $this->getFilteredOption("SHARED_USERS_TMP_PREFIX", $this->repository->getId()); + while (isSet($httpVars["user_".$index])) { + $eType = $httpVars["entry_type_".$index]; + $rightString = ($httpVars["right_read_".$index]=="true"?"r":"").($httpVars["right_write_".$index]=="true"?"w":""); + if($this->watcher !== false) $uWatch = $httpVars["right_watch_".$index] == "true" ? true : false; + if (empty($rightString)) { + $index++; + continue; + } + if ($eType == "user") { + $u = AJXP_Utils::decodeSecureMagic($httpVars["user_".$index], AJXP_SANITIZE_ALPHANUM); + if (!AuthService::userExists($u) && !isSet($httpVars["user_pass_".$index])) { + return 100; + } else if (AuthService::userExists($u) && isSet($httpVars["user_pass_".$index])) { + throw new Exception("User $u already exists, please choose another name."); + } + if(!AuthService::userExists($u, "w") && !empty($prefix) + && strpos($u, $prefix)!==0 ){ + $u = $prefix . $u; + } + $users[] = $u; + } else { + $u = AJXP_Utils::decodeSecureMagic($httpVars["user_".$index]); + $groups[] = $u; + } + $uRights[$u] = $rightString; + $uPasses[$u] = isSet($httpVars["user_pass_".$index])?$httpVars["user_pass_".$index]:""; + if ($this->watcher !== false) { + $uWatches[$u] = $uWatch; + } + $index ++; + } + + $label = AJXP_Utils::decodeSecureMagic($httpVars["repo_label"]); + $description = AJXP_Utils::decodeSecureMagic($httpVars["repo_description"]); + if (isSet($httpVars["repository_id"])) { + $editingRepo = ConfService::getRepositoryById($httpVars["repository_id"]); + } + + // CHECK USER & REPO DOES NOT ALREADY EXISTS + if ( $this->getFilteredOption("AVOID_SHARED_FOLDER_SAME_LABEL", $this->repository->getId()) == true) { + $repos = ConfService::getRepositoriesList(); + foreach ($repos as $obj) { + if ($obj->getDisplay() == $label && (!isSet($editingRepo) || $editingRepo != $obj)) { + return 101; + } + } + } + + $confDriver = ConfService::getConfStorageImpl(); + foreach ($users as $userName) { + if (AuthService::userExists($userName)) { + // check that it's a child user + $userObject = $confDriver->createUserObject($userName); + if ( ConfService::getCoreConf("ALLOW_CROSSUSERS_SHARING", "conf") != true && ( !$userObject->hasParent() || $userObject->getParent() != $loggedUser->id ) ) { + return 102; + } + } else { + if (AuthService::isReservedUserId($userName)) { + return 102; + } + if(!isSet($httpVars["shared_pass"]) || $httpVars["shared_pass"] == "") return 100; + } + } + + // CREATE SHARED OPTIONS + $options = $accessDriver->makeSharedRepositoryOptions($httpVars, $repository); + $customData = array(); + foreach ($httpVars as $key => $value) { + if (substr($key, 0, strlen("PLUGINS_DATA_")) == "PLUGINS_DATA_") { + $customData[substr($key, strlen("PLUGINS_DATA_"))] = $value; + } + } + if (count($customData)) { + $options["PLUGINS_DATA"] = $customData; + } + if (isSet($editingRepo)) { + $newRepo = $editingRepo; + if ($editingRepo->getDisplay() != $label) { + $newRepo->setDisplay($label); + ConfService::replaceRepository($httpVars["repository_id"], $newRepo); + } + $editingRepo->setDescription($description); + } else { + if ($repository->getOption("META_SOURCES")) { + $options["META_SOURCES"] = $repository->getOption("META_SOURCES"); + foreach ($options["META_SOURCES"] as $index => $data) { + if (isSet($data["USE_SESSION_CREDENTIALS"]) && $data["USE_SESSION_CREDENTIALS"] === true) { + $options["META_SOURCES"][$index]["ENCODED_CREDENTIALS"] = AJXP_Safe::getEncodedCredentialString(); + } + } + } + $newRepo = $repository->createSharedChild( + $label, + $options, + $repository->id, + $loggedUser->id, + null + ); + $gPath = $loggedUser->getGroupPath(); + if (!empty($gPath)) { + $newRepo->setGroupPath($gPath); + } + $newRepo->setDescription($description); + ConfService::addRepository($newRepo); + } + + $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + + if (isSet($editingRepo)) { + + $currentRights = $this->computeSharedRepositoryAccessRights($httpVars["repository_id"], false, $this->urlBase.$file); + $originalUsers = array_keys($currentRights["USERS"]); + $removeUsers = array_diff($originalUsers, $users); + if (count($removeUsers)) { + foreach ($removeUsers as $user) { + if (AuthService::userExists($user)) { + $userObject = $confDriver->createUserObject($user); + $userObject->personalRole->setAcl($newRepo->getUniqueId(), ""); + $userObject->save("superuser"); + } + } + } + $originalGroups = array_keys($currentRights["GROUPS"]); + $removeGroups = array_diff($originalGroups, $groups); + if (count($removeGroups)) { + foreach ($removeGroups as $groupId) { + $role = AuthService::getRole("AJXP_GRP_".AuthService::filterBaseGroup($groupId)); + if ($role !== false) { + $role->setAcl($newRepo->getUniqueId(), ""); + AuthService::updateRole($role); + } + } + } + } + + foreach ($users as $userName) { + if (AuthService::userExists($userName, "w")) { + // check that it's a child user + $userObject = $confDriver->createUserObject($userName); + } else { + if (ConfService::getAuthDriverImpl()->getOption("TRANSMIT_CLEAR_PASS")) { + $pass = $uPasses[$userName]; + } else { + $pass = md5($uPasses[$userName]); + } + AuthService::createUser($userName, $pass); + $userObject = $confDriver->createUserObject($userName); + $userObject->personalRole->clearAcls(); + $userObject->setParent($loggedUser->id); + $userObject->setGroupPath($loggedUser->getGroupPath()); + $userObject->setProfile("shared"); + AJXP_Controller::applyHook("user.after_create", array($userObject)); + } + // CREATE USER WITH NEW REPO RIGHTS + $userObject->personalRole->setAcl($newRepo->getUniqueId(), $uRights[$userName]); + if (isSet($httpVars["minisite"])) { + $newRole = new AJXP_Role("AJXP_SHARED-".$newRepo->getUniqueId()); + $r = AuthService::getRole("MINISITE"); + if (is_a($r, "AJXP_Role")) { + if ($httpVars["disable_download"]) { + $f = AuthService::getRole("MINISITE_NODOWNLOAD"); + if (is_a($f, "AJXP_Role")) { + $r = $f->override($r); + } + } + $allData = $r->getDataArray(); + $newData = $newRole->getDataArray(); + if(isSet($allData["ACTIONS"][AJXP_REPO_SCOPE_SHARED])) $newData["ACTIONS"][$newRepo->getUniqueId()] = $allData["ACTIONS"][AJXP_REPO_SCOPE_SHARED]; + if(isSet($allData["PARAMETERS"][AJXP_REPO_SCOPE_SHARED])) $newData["PARAMETERS"][$newRepo->getUniqueId()] = $allData["PARAMETERS"][AJXP_REPO_SCOPE_SHARED]; + $newRole->bunchUpdate($newData); + AuthService::updateRole($newRole); + $userObject->addRole($newRole); + } + } + $userObject->save("superuser"); + if ($this->watcher !== false) { + // Register a watch on the current folder for shared user + if ($uWatches[$userName] == "true") { + $this->watcher->setWatchOnFolder( + new AJXP_Node($this->urlBase.$file), + $userName, + MetaWatchRegister::$META_WATCH_USERS_CHANGE, + array(AuthService::getLoggedUser()->getId()) + ); + } else { + $this->watcher->removeWatchFromFolder( + new AJXP_Node($this->urlBase.$file), + $userName, + true + ); + } + } + } + + if ($this->watcher !== false) { + // Register a watch on the new repository root for current user + if ($httpVars["self_watch_folder"] == "true") { + $this->watcher->setWatchOnFolder( + new AJXP_Node($this->baseProtocol."://".$newRepo->getUniqueId()."/"), + AuthService::getLoggedUser()->getId(), + MetaWatchRegister::$META_WATCH_BOTH); + } else { + $this->watcher->removeWatchFromFolder( + new AJXP_Node($this->baseProtocol."://".$newRepo->getUniqueId()."/"), + AuthService::getLoggedUser()->getId()); + } + } + + foreach ($groups as $group) { + $grRole = AuthService::getRole("AJXP_GRP_".AuthService::filterBaseGroup($group), true); + $grRole->setAcl($newRepo->getUniqueId(), $uRights[$group]); + AuthService::updateRole($grRole); + } + + return $newRepo; + } + + + /** + * @static + * @param String $type + * @param String $element + * @param AbstractAjxpUser $loggedUser + * @throws Exception + */ + public static function deleteSharedElement($type, $element, $loggedUser) + { + $mess = ConfService::getMessages(); + AJXP_Logger::debug($type."-".$element); + if ($type == "repository") { + $repo = ConfService::getRepositoryById($element); + if($repo == null) return; + if (!$repo->hasOwner() || $repo->getOwner() != $loggedUser->getId()) { + throw new Exception($mess["ajxp_shared.12"]); + } else { + $res = ConfService::deleteRepository($element); + if ($res == -1) { + throw new Exception($mess["ajxp_conf.51"]); + } + } + } else if ($type == "minisite") { + $minisiteData = self::loadPublicletData($element); + $repoId = $minisiteData["REPOSITORY"]; + $repo = ConfService::getRepositoryById($repoId); + if (!$repo->hasOwner() || $repo->getOwner() != $loggedUser->getId()) { + throw new Exception($mess["ajxp_shared.12"]); + } else { + $res = ConfService::deleteRepository($repoId); + if ($res == -1) { + throw new Exception($mess["ajxp_conf.51"]); + } + // Silently delete corresponding role if it exists + AuthService::deleteRole("AJXP_SHARED-".$repoId); + // If guest user created, remove it now. + if (isSet($minisiteData["PRELOG_USER"])) { + AuthService::deleteUser($minisiteData["PRELOG_USER"]); + } + unlink($minisiteData["PUBLICLET_PATH"]); + } + } else if ($type == "user") { + $confDriver = ConfService::getConfStorageImpl(); + $object = $confDriver->createUserObject($element); + if (!$object->hasParent() || $object->getParent() != $loggedUser->getId()) { + throw new Exception($mess["ajxp_shared.12"]); + } else { + AuthService::deleteUser($element); + } + } else if ($type == "file") { + $publicletData = self::loadPublicletData($element); + if (isSet($publicletData["OWNER_ID"]) && $publicletData["OWNER_ID"] == $loggedUser->getId()) { + PublicletCounter::delete($element); + unlink($publicletData["PUBLICLET_PATH"]); + } else { + throw new Exception($mess["ajxp_shared.12"]); + } + } + } + + public static function sharedElementExists($type, $element, $loggedUser) + { + if ($type == "repository") { + return (ConfService::getRepositoryById($element) != null); + } else if ($type == "file" || $type == "minisite") { + $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); + return is_file($dlFolder."/".$element.".php"); + } + } + + + public static function loadPublicletData($id) + { + $dlFolder = ConfService::getCoreConf("PUBLIC_DOWNLOAD_FOLDER"); + $file = $dlFolder."/".$id.".php"; + if(!is_file($file)) return array(); + $lines = file($file); + $inputData = ''; + $code = $lines[3] . $lines[4] . $lines[5]; + eval($code); + $dataModified = self::checkHash($inputData, $id); //(md5($inputData) != $id); + $publicletData = unserialize($inputData); + $publicletData["SECURITY_MODIFIED"] = $dataModified; + if (!isSet($publicletData["REPOSITORY"])) { + $publicletData["DOWNLOAD_COUNT"] = PublicletCounter::getCount($id); + } + $publicletData["PUBLICLET_PATH"] = $file; + return $publicletData; + } + +} diff --git a/core/src/plugins/action.share/manifest.xml b/core/src/plugins/action.share/manifest.xml index 1b9a60e50b..7c32b7c917 100644 --- a/core/src/plugins/action.share/manifest.xml +++ b/core/src/plugins/action.share/manifest.xml @@ -1,288 +1,288 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    AJXP_MESSAGE[share_center.27]
    -
    AJXP_MESSAGE[share_center.24]
    -
    -
    -
    AJXP_MESSAGE[share_center.21]
    - -
    -
    -
    AJXP_MESSAGE[share_center.22]
    - -
    -
    -
    AJXP_MESSAGE[share_center.23]
    - -
    - -
    -
    -
    AJXP_MESSAGE[309]
    -
    -
    - -
    - - -
    -
    AJXP_MESSAGE[share_center.28]
    - -
    -
    -
    -
    AJXP_MESSAGE[share_center.28]
    -
    AJXP_MESSAGE[share_center.36]
    -
    -
    -
    AJXP_MESSAGE[share_center.69]
    -
    AJXP_MESSAGE[share_center.70]
    -
    -
    -
    AJXP_MESSAGE[share_center.35]
    - -
    Description
    - -
    -
    -
    AJXP_MESSAGE[share_center.71]
    -
    -
    -
    -
    -
    -
    -
    - - -
    -
    -
    AJXP_MESSAGE[share_center.30]
    -
    AJXP_MESSAGE[share_center.26]
    -
    - - -
    - - ]]> -
    - - -
    -
    - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - -
    #{type_string}
    -
    - - ]]> -
    -
    -
    -
    - - - - -
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AJXP_MESSAGE[share_center.27]
    +
    AJXP_MESSAGE[share_center.24]
    +
    +
    +
    AJXP_MESSAGE[share_center.21]
    + +
    +
    +
    AJXP_MESSAGE[share_center.22]
    + +
    +
    +
    AJXP_MESSAGE[share_center.23]
    + +
    + +
    +
    +
    AJXP_MESSAGE[309]
    +
    +
    + +
    + + +
    +
    AJXP_MESSAGE[share_center.28]
    + +
    +
    +
    +
    AJXP_MESSAGE[share_center.28]
    +
    AJXP_MESSAGE[share_center.36]
    +
    +
    +
    AJXP_MESSAGE[share_center.69]
    +
    AJXP_MESSAGE[share_center.70]
    +
    +
    +
    AJXP_MESSAGE[share_center.35]
    + +
    Description
    + +
    +
    +
    AJXP_MESSAGE[share_center.71]
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    AJXP_MESSAGE[share_center.30]
    +
    AJXP_MESSAGE[share_center.26]
    +
    + + +
    + + ]]> +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + +
    + + + + + + + +
    #{type_string}
    +
    + + ]]> +
    +
    +
    +
    + + + + +
    diff --git a/core/src/plugins/action.share/res/i18n/ca.php b/core/src/plugins/action.share/res/i18n/ca.php index 23e3dd26e2..7c8d77943d 100644 --- a/core/src/plugins/action.share/res/i18n/ca.php +++ b/core/src/plugins/action.share/res/i18n/ca.php @@ -81,4 +81,4 @@ "77"=> "Please enable JavaScript to access this application", "78"=> "Warning, you should only use standard alphanumerical characters for user names. The identifier '%CURRENT%' will be replaced by '%NEW%'", -); \ No newline at end of file +); diff --git a/core/src/plugins/action.share/res/i18n/conf/en.php b/core/src/plugins/action.share/res/i18n/conf/en.php index 79b7815635..a83facda9e 100644 --- a/core/src/plugins/action.share/res/i18n/conf/en.php +++ b/core/src/plugins/action.share/res/i18n/conf/en.php @@ -26,4 +26,3 @@ "File location" => "File location", "Where to store the metadata file : LOCAL means a hidden file will be created in each folder, GLOBAL means that one file will be created in AJXP_DATA_PATH/plugins/action.share folder." => "Where to store the metadata file : LOCAL means a hidden file will be created in each folder, GLOBAL means that one file will be created in AJXP_DATA_PATH/plugins/action.share folder.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.share/res/i18n/conf/fr.php b/core/src/plugins/action.share/res/i18n/conf/fr.php index cceb2d0a9f..a5fbc5f81a 100644 --- a/core/src/plugins/action.share/res/i18n/conf/fr.php +++ b/core/src/plugins/action.share/res/i18n/conf/fr.php @@ -26,4 +26,3 @@ "File location" => "Emplacement", "Where to store the metadata file : LOCAL means a hidden file will be created in each folder, GLOBAL means that one file will be created in AJXP_DATA_PATH/plugins/action.share folder." => "Où stocker le fichier : LOCAL un fichier caché sera créé dans chaque répertoire, GLOBAL un fichier global sera créé dans AJXP_DATA_PATH/plugins/action.share folder.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.share/res/i18n/conf/pt.php b/core/src/plugins/action.share/res/i18n/conf/pt.php index 8123d01e8b..48efb73239 100644 --- a/core/src/plugins/action.share/res/i18n/conf/pt.php +++ b/core/src/plugins/action.share/res/i18n/conf/pt.php @@ -26,4 +26,3 @@ "File location" => "Localização do ficheiro", "Where to store the metadata file : LOCAL means a hidden file will be created in each folder, GLOBAL means that one file will be created in AJXP_DATA_PATH/plugins/action.share folder." => "Onde guardar o ficheiro de Metadata : LOCAL significa que será criado um ficheiro oculto em cada pasta, GLOBAL significa que será criado um ficheiro na pasta 'AJXP_DATA_PATH/plugins/action.share'.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.share/res/i18n/de.php b/core/src/plugins/action.share/res/i18n/de.php index 2cb9cce34f..0756552c9d 100644 --- a/core/src/plugins/action.share/res/i18n/de.php +++ b/core/src/plugins/action.share/res/i18n/de.php @@ -80,4 +80,4 @@ "77"=> "Please enable JavaScript to access this application", "78"=> "Warning, you should only use standard alphanumerical characters for user names. The identifier '%CURRENT%' will be replaced by '%NEW%'", -); \ No newline at end of file +); diff --git a/core/src/plugins/action.share/res/i18n/en.php b/core/src/plugins/action.share/res/i18n/en.php index 026dc1ee3f..776050bb41 100644 --- a/core/src/plugins/action.share/res/i18n/en.php +++ b/core/src/plugins/action.share/res/i18n/en.php @@ -1,84 +1,84 @@ - "%s Public Download", - // will be replaced by the filename to download - "2" => "Click on the image to download %s to your hard drive", - "3" => "Wrong password", - "4" => "Enter the required password and click on the image to download %s to your hard drive", - "5" => "password", - "6" => "Stop Sharing", - "7" => "Stopping the share will not remove the file. If you want to change the parameters, re-share the file.", - "8" => "File is shared", - "9" => "Use this button to stop sharing this folder", - "10"=> "Folder is shared", - "11"=> "Expiration", - "12"=> "Password", - "13"=> "Yes", - "14"=> "No", - "15"=> "File was download %s times", - "16"=> "reset", - "17"=> "Click to reset download counter", - "18"=> "Folder is shared as a new workspace", - "19"=> "Shared workspace options were successfully modified", - "20"=> "Ooops, the file you required could not be found! Maybe it was deleted or it is not shared with you anymore.", - "21"=> "Expire after (days): ", - "22"=> "Allowed Downloads: ", - "23"=> "Optional password: ", - "24"=> "Set expiration limits and define a password to access the file, then click on \"Generate\".", - "25"=> "No limit", - "26"=> "Choose users or groups and set their access rights. 'Write' only will create an upload-only workspace.", - "27"=> "Share file", - "28"=> "Share folder", - "29"=> "WebLink", - "30"=> "User Access", - "31"=> "Read", - "32"=> "Write", - "33"=> "Watch", - "34"=> "Existing or new user", - "35"=> "Workspace Label", - "36"=> "The folder will appear to the shared users as a workspace with the following label.", - "37"=> "Confirm", - "38"=> "Watch this folder content", - "39"=> "Watch this file activity", - "40"=> "Invitations", - "41"=> "Send invitations by email to the users you have shared this item with.", - "42"=> "A user of %s is sharing a link with you", - "43"=> "A user of %s is sharing a folder with you", - "44"=> "%s Share", - "45"=> "Send Invitation", - "46"=> "Open workspace %s1 directly in %s2", - "47"=> "Successfully updated watch status", - "48"=> "You are not allowed to access this data", - "49"=> "create user", - "50"=> "Shared element", - "51"=> "Downloaded", - "52"=> "Configuration", - "53"=> "none", - "54"=> "With...", - "55"=> "Shared...", - "56"=> "Configure sharing...", - "57"=> "times", - "58"=> "Please check at least one permission!", - "59"=> "Download Page", - "60"=> "Direct Download Link", - "61"=> "HTML Embed Code", - "62"=> "Minisite Adress", - "63"=> "New workspace", - "64"=> "For both internal and external users, the folder will appear as a new workspace in the target users workspace list.", - "65"=> "Public Minisite (no authentification required)", - "66"=> "For external users, the folder will appear at a new public adress as a simple file list.", - "67"=> "Private Minisite (users authentification required)", - "68"=> "For internal or external users, the folder will appear at a new adress as a simple file list, but with user authentification required", - "69"=> "Configure Minisite", - "70"=> "Use the checkboxes to grant permissions to this folder for the public. If you check 'Upload' only, this folder will be an empty inbox in which people can drop files.", - "71"=> "Permissions", - "72"=> "Browse & Preview", - "73"=> "Download", - "74"=> "Upload files", - "75"=> "Please use a positive number for both Expiration and Download limit fields.", - "76"=> "Please enable Cookies to access this application", - "77"=> "Please enable JavaScript to access this application", - "78"=> "Warning, you should only use standard alphanumerical characters for user names. The identifier '%CURRENT%' will be replaced by '%NEW%'", -); \ No newline at end of file + "%s Public Download", + // will be replaced by the filename to download + "2" => "Click on the image to download %s to your hard drive", + "3" => "Wrong password", + "4" => "Enter the required password and click on the image to download %s to your hard drive", + "5" => "password", + "6" => "Stop Sharing", + "7" => "Stopping the share will not remove the file. If you want to change the parameters, re-share the file.", + "8" => "File is shared", + "9" => "Use this button to stop sharing this folder", + "10"=> "Folder is shared", + "11"=> "Expiration", + "12"=> "Password", + "13"=> "Yes", + "14"=> "No", + "15"=> "File was download %s times", + "16"=> "reset", + "17"=> "Click to reset download counter", + "18"=> "Folder is shared as a new workspace", + "19"=> "Shared workspace options were successfully modified", + "20"=> "Ooops, the file you required could not be found! Maybe it was deleted or it is not shared with you anymore.", + "21"=> "Expire after (days): ", + "22"=> "Allowed Downloads: ", + "23"=> "Optional password: ", + "24"=> "Set expiration limits and define a password to access the file, then click on \"Generate\".", + "25"=> "No limit", + "26"=> "Choose users or groups and set their access rights. 'Write' only will create an upload-only workspace.", + "27"=> "Share file", + "28"=> "Share folder", + "29"=> "WebLink", + "30"=> "User Access", + "31"=> "Read", + "32"=> "Write", + "33"=> "Watch", + "34"=> "Existing or new user", + "35"=> "Workspace Label", + "36"=> "The folder will appear to the shared users as a workspace with the following label.", + "37"=> "Confirm", + "38"=> "Watch this folder content", + "39"=> "Watch this file activity", + "40"=> "Invitations", + "41"=> "Send invitations by email to the users you have shared this item with.", + "42"=> "A user of %s is sharing a link with you", + "43"=> "A user of %s is sharing a folder with you", + "44"=> "%s Share", + "45"=> "Send Invitation", + "46"=> "Open workspace %s1 directly in %s2", + "47"=> "Successfully updated watch status", + "48"=> "You are not allowed to access this data", + "49"=> "create user", + "50"=> "Shared element", + "51"=> "Downloaded", + "52"=> "Configuration", + "53"=> "none", + "54"=> "With...", + "55"=> "Shared...", + "56"=> "Configure sharing...", + "57"=> "times", + "58"=> "Please check at least one permission!", + "59"=> "Download Page", + "60"=> "Direct Download Link", + "61"=> "HTML Embed Code", + "62"=> "Minisite Adress", + "63"=> "New workspace", + "64"=> "For both internal and external users, the folder will appear as a new workspace in the target users workspace list.", + "65"=> "Public Minisite (no authentification required)", + "66"=> "For external users, the folder will appear at a new public adress as a simple file list.", + "67"=> "Private Minisite (users authentification required)", + "68"=> "For internal or external users, the folder will appear at a new adress as a simple file list, but with user authentification required", + "69"=> "Configure Minisite", + "70"=> "Use the checkboxes to grant permissions to this folder for the public. If you check 'Upload' only, this folder will be an empty inbox in which people can drop files.", + "71"=> "Permissions", + "72"=> "Browse & Preview", + "73"=> "Download", + "74"=> "Upload files", + "75"=> "Please use a positive number for both Expiration and Download limit fields.", + "76"=> "Please enable Cookies to access this application", + "77"=> "Please enable JavaScript to access this application", + "78"=> "Warning, you should only use standard alphanumerical characters for user names. The identifier '%CURRENT%' will be replaced by '%NEW%'", +); diff --git a/core/src/plugins/action.share/res/i18n/es.php b/core/src/plugins/action.share/res/i18n/es.php index e7e81216a2..c72f5ab303 100644 --- a/core/src/plugins/action.share/res/i18n/es.php +++ b/core/src/plugins/action.share/res/i18n/es.php @@ -81,4 +81,3 @@ "77"=> "Please enable JavaScript to access this application", "78"=> "Warning, you should only use standard alphanumerical characters for user names. The identifier '%CURRENT%' will be replaced by '%NEW%'", ); - diff --git a/core/src/plugins/action.share/res/i18n/fr.php b/core/src/plugins/action.share/res/i18n/fr.php index 23d2edcf4e..01fc9cc49b 100644 --- a/core/src/plugins/action.share/res/i18n/fr.php +++ b/core/src/plugins/action.share/res/i18n/fr.php @@ -1,84 +1,84 @@ - "Téléchargement public %s", - // will be replaced by the filename to download - "2" => "Cliquez sur l'image pour télécharger %s sur votre disque dur", - "3" => "Mauvais mot de passe", - "4" => "Entrez le mot de passe fourni et cliquez sur l'image télécharger %s sur votre disque dur", - "5" => "mot de passe", - "6" => "Ne plus partager", - "7" => "L'arrêt du partage ne supprimera pas le fichier. Si vous voulez modifier les paramêtres, veuillez re-partager le fichier.", - "8" => "Fichier partagé", - "9" => "Utiliser ce bouton pour ne plus partager le répertoire", - "10"=> "Répertoire partagé", - "11"=> "Expiration", - "12"=> "Mot de passe", - "13"=> "Oui", - "14"=> "Non", - "15"=> "Fichier téléchargé %s fois", - "16"=> "Remise à zéro", - "17"=> "Cliquer pour remettre à zéro le compteur de téléchargements", - "18"=> "Le répertoire a été partagé comme un nouveau dépôt", - "19"=> "Les options de partage ont été modifiées avec succès", - "20"=> "Ooops, le fichier que vous recherchez n'a pas été trouvé! Peut-être n'est il plus partagé avec vous?", - "21"=> "Expire après (jours): ", - "22"=> "Downloads autorisés: ", - "23"=> "Mot de passe: ", - "24"=> "Fixer les limites d'expiration et un mot de passe optionnel, puis cliquer sur \"Génerer\".", - "25"=> "Pas de limite", - "26"=> "Choisir les utilisateurs et les groupes et leurs droits d'accès.", - "27"=> "Partage de fichier", - "28"=> "Partage de répertoire", - "29"=> "Lien public", - "30"=> "Contrôle d'accès", - "31"=> "Lire", - "32"=> "Ecrire", - "33"=> "Notif.", - "34"=> "Utilisateur existant ou nouveau", - "35"=> "Libellé", - "36"=> "Le répertoire apparaîtra comme un dépôt pour les utilisateurs partagés avec le libellé suivant.", - "37"=> "Confirmer", - "38"=> "Surveiller le contenu du répertoire", - "39"=> "Surveiller l'activité sur ce fichier", - "40"=> "Invitations", - "41"=> "Envoyer des invitations par email aux utilisateurs avec qui vous partagez le fichier", - "42"=> "Un utilisateur de %s partage un lien avec vous", - "43"=> "Un utilisateur de %s vous invite à partager un dossier", - "44"=> "Partage %s", - "45"=> "Envoyer l'invitation", - "46"=> "Ouvrir le dépôt %s1 directement dans %s2", - "47"=> "Le statut de surveillance a été changé", - "48"=> "Vous n'êtes pas autorisé à accéder à cette donnée.", - "49"=> "créer l'utilisateur", - "50"=> "Element partagé", - "51"=> "Téléchargé", - "52"=> "Configuration", - "53"=> "non", - "54"=> "Avec...", - "55"=> "Partagé...", - "56"=> "Configurer le partage...", - "57"=> "fois", - "58"=> "Veuillez sélectionner au moins un droit!", - "59"=> "Page de téléchargement", - "60"=> "Lien de téléchargement direct", - "61"=> "Code HTML à insérer", - "62"=> "Adresse du minisite", - "63"=> "Nouveau workspace", - "64"=> "Pour les utilisateurs internes comme externes, le répertoire apparaîtra comme un nouveau workspace partagé.", - "65"=> "Minisite Public (pas d'authentification requise)", - "66"=> "Pour des utilisateurs publiques, le répertoire apparaîtra comme une liste de fichiers enrichie (avec prévisualisation), à une adresse unique.", - "67"=> "Minisite Privé (authentification requise)", - "68"=> "Le répertoire apparaît à une nouvelle adresse, mais nécessite une authentification des utilisateurs (internes comme externes).", - "69"=> "Configurer le minisite", - "70"=> "Utiliser les cases pour donner des droits aux utilisateurs lorsqu'ils accèdent au minisite. Si vous cochez 'Envoi' seulement, ceci peut servir de simple boite de réception.", - "71"=> "Droits", - "72"=> "Lister & Prévisualiser", - "73"=> "Télécharger", - "74"=> "Envoyer des fichiers", - "75"=> "Veuillez utiliser des entiers positifs pour les champs Expiration et Nombre de downloads!", - "76"=> "Merci d'activer les Cookies pour accèder à cette application", - "77"=> "Merci d'activer JavaScript pour accèder à cette application", - "78"=> "Attention, vous ne devez utiliser que des caractères alphanumériques standards pour les identifiants. L'identifiant '%CURRENT%' sera remplaçé par '%NEW%'", -); + "Téléchargement public %s", + // will be replaced by the filename to download + "2" => "Cliquez sur l'image pour télécharger %s sur votre disque dur", + "3" => "Mauvais mot de passe", + "4" => "Entrez le mot de passe fourni et cliquez sur l'image télécharger %s sur votre disque dur", + "5" => "mot de passe", + "6" => "Ne plus partager", + "7" => "L'arrêt du partage ne supprimera pas le fichier. Si vous voulez modifier les paramêtres, veuillez re-partager le fichier.", + "8" => "Fichier partagé", + "9" => "Utiliser ce bouton pour ne plus partager le répertoire", + "10"=> "Répertoire partagé", + "11"=> "Expiration", + "12"=> "Mot de passe", + "13"=> "Oui", + "14"=> "Non", + "15"=> "Fichier téléchargé %s fois", + "16"=> "Remise à zéro", + "17"=> "Cliquer pour remettre à zéro le compteur de téléchargements", + "18"=> "Le répertoire a été partagé comme un nouveau dépôt", + "19"=> "Les options de partage ont été modifiées avec succès", + "20"=> "Ooops, le fichier que vous recherchez n'a pas été trouvé! Peut-être n'est il plus partagé avec vous?", + "21"=> "Expire après (jours): ", + "22"=> "Downloads autorisés: ", + "23"=> "Mot de passe: ", + "24"=> "Fixer les limites d'expiration et un mot de passe optionnel, puis cliquer sur \"Génerer\".", + "25"=> "Pas de limite", + "26"=> "Choisir les utilisateurs et les groupes et leurs droits d'accès.", + "27"=> "Partage de fichier", + "28"=> "Partage de répertoire", + "29"=> "Lien public", + "30"=> "Contrôle d'accès", + "31"=> "Lire", + "32"=> "Ecrire", + "33"=> "Notif.", + "34"=> "Utilisateur existant ou nouveau", + "35"=> "Libellé", + "36"=> "Le répertoire apparaîtra comme un dépôt pour les utilisateurs partagés avec le libellé suivant.", + "37"=> "Confirmer", + "38"=> "Surveiller le contenu du répertoire", + "39"=> "Surveiller l'activité sur ce fichier", + "40"=> "Invitations", + "41"=> "Envoyer des invitations par email aux utilisateurs avec qui vous partagez le fichier", + "42"=> "Un utilisateur de %s partage un lien avec vous", + "43"=> "Un utilisateur de %s vous invite à partager un dossier", + "44"=> "Partage %s", + "45"=> "Envoyer l'invitation", + "46"=> "Ouvrir le dépôt %s1 directement dans %s2", + "47"=> "Le statut de surveillance a été changé", + "48"=> "Vous n'êtes pas autorisé à accéder à cette donnée.", + "49"=> "créer l'utilisateur", + "50"=> "Element partagé", + "51"=> "Téléchargé", + "52"=> "Configuration", + "53"=> "non", + "54"=> "Avec...", + "55"=> "Partagé...", + "56"=> "Configurer le partage...", + "57"=> "fois", + "58"=> "Veuillez sélectionner au moins un droit!", + "59"=> "Page de téléchargement", + "60"=> "Lien de téléchargement direct", + "61"=> "Code HTML à insérer", + "62"=> "Adresse du minisite", + "63"=> "Nouveau workspace", + "64"=> "Pour les utilisateurs internes comme externes, le répertoire apparaîtra comme un nouveau workspace partagé.", + "65"=> "Minisite Public (pas d'authentification requise)", + "66"=> "Pour des utilisateurs publiques, le répertoire apparaîtra comme une liste de fichiers enrichie (avec prévisualisation), à une adresse unique.", + "67"=> "Minisite Privé (authentification requise)", + "68"=> "Le répertoire apparaît à une nouvelle adresse, mais nécessite une authentification des utilisateurs (internes comme externes).", + "69"=> "Configurer le minisite", + "70"=> "Utiliser les cases pour donner des droits aux utilisateurs lorsqu'ils accèdent au minisite. Si vous cochez 'Envoi' seulement, ceci peut servir de simple boite de réception.", + "71"=> "Droits", + "72"=> "Lister & Prévisualiser", + "73"=> "Télécharger", + "74"=> "Envoyer des fichiers", + "75"=> "Veuillez utiliser des entiers positifs pour les champs Expiration et Nombre de downloads!", + "76"=> "Merci d'activer les Cookies pour accèder à cette application", + "77"=> "Merci d'activer JavaScript pour accèder à cette application", + "78"=> "Attention, vous ne devez utiliser que des caractères alphanumériques standards pour les identifiants. L'identifiant '%CURRENT%' sera remplaçé par '%NEW%'", +); diff --git a/core/src/plugins/action.share/res/i18n/pt.php b/core/src/plugins/action.share/res/i18n/pt.php index bbf392edc0..b5f116f1bf 100644 --- a/core/src/plugins/action.share/res/i18n/pt.php +++ b/core/src/plugins/action.share/res/i18n/pt.php @@ -81,4 +81,4 @@ "76"=> "Por favor active as cookies no seu Navegador para poder aceder a esta aplicação", "77"=> "Por favor active o Javascript no seu Navegador para aceder a esta aplicação", "78"=> "ATENÇÃO: Só deve utilizar caracteres alfa-numéricos padrão para nomes de utilizador. O Identificador '%CURRENT%' será substituído por '%NEW%'", -); \ No newline at end of file +); diff --git a/core/src/plugins/action.share/res/minisite.php b/core/src/plugins/action.share/res/minisite.php index 73786b70af..fbc20a843e 100644 --- a/core/src/plugins/action.share/res/minisite.php +++ b/core/src/plugins/action.share/res/minisite.php @@ -1,15 +1,15 @@ - - AjaXplorer - + + AjaXplorer + - - + + - - - + + - + - +
    AJXP_REPOSITORY_LABEL
    - - \ No newline at end of file + + diff --git a/core/src/plugins/action.share/res/public_links.php b/core/src/plugins/action.share/res/public_links.php index 2bf4870fdc..d8e5107604 100644 --- a/core/src/plugins/action.share/res/public_links.php +++ b/core/src/plugins/action.share/res/public_links.php @@ -1,7 +1,7 @@ - - + + - - - -
    + + + +

    -
    +

    - '); } else { ?> @@ -160,7 +160,7 @@ $bgName = $varBase . $index; $bgAttName = $varBase . 'ATTRIBUTES_' . $index; $bgs = array(); - while(isSet($$bgName) && !empty($$bgName)){ + while (isSet($$bgName) && !empty($$bgName)) { $bgs[] = "background-image:url('".$$bgName."');" . (isSet($$bgAttName) ? $$bgAttName : ''); $index ++; $bgName = $varBase . $index; @@ -168,10 +168,10 @@ } echo 'backgrounds = ' . json_encode($bgs) . ';'; ?> - if(backgrounds.length){ + if (backgrounds.length) { var i = Math.floor( Math.random() * backgrounds.length); document.body.setAttribute("style", backgrounds[i]); } - - \ No newline at end of file + + diff --git a/core/src/plugins/action.skeleton/class.PluginSkeleton.php b/core/src/plugins/action.skeleton/class.PluginSkeleton.php index 65f1dcff96..83386fb821 100644 --- a/core/src/plugins/action.skeleton/class.PluginSkeleton.php +++ b/core/src/plugins/action.skeleton/class.PluginSkeleton.php @@ -26,13 +26,14 @@ * @package AjaXplorer_Plugins * @subpackage Action */ -class PluginSkeleton extends AJXP_Plugin { - +class PluginSkeleton extends AJXP_Plugin +{ /** * @param DOMNode $contribNode * @return void */ - public function parseSpecificContributions(&$contribNode){ + public function parseSpecificContributions(&$contribNode) + { if($contribNode->nodeName != "client_configs") return; // This demonstrate how the tight integration of XML, PHP and JS Client make plugins programming // very flexible. Here if the plugin configuration SHOW_CUSTOM_FOOTER is set to false, we @@ -41,9 +42,9 @@ public function parseSpecificContributions(&$contribNode){ $actionXpath=new DOMXPath($contribNode->ownerDocument); $footerTplNodeList = $actionXpath->query('template[@name="bottom"]', $contribNode); $footerTplNode = $footerTplNodeList->item(0); - if(!$this->getFilteredOption("SHOW_CUSTOM_FOOTER")){ + if (!$this->getFilteredOption("SHOW_CUSTOM_FOOTER")) { $contribNode->removeChild($footerTplNode); - }else{ + } else { $content = $this->getFilteredOption("CUSTOM_FOOTER_CONTENT"); $content = str_replace("\\n", "
    ", $content); $cdata = '
    '.$content.'
    '; @@ -59,30 +60,30 @@ public function parseSpecificContributions(&$contribNode){ * @param Array $fileVars * @return void */ - function receiveAction($action, $httpVars, $fileVars){ - if($action == "my_skeleton_button_frame"){ + public function receiveAction($action, $httpVars, $fileVars) + { + if ($action == "my_skeleton_button_frame") { header("Content-type:text/html"); print("

    This is a dynamically generated content. It is sent back to the client by the server, thus it can be the result of what you want : a query to a remote API, a constant string (like it is now), or any specific data stored by the application...

    "); print("

    Here the server sends back directly HTML that is displayed by the client, but other formats can be used when it comes to more structured data, allowing the server to stay focus on the data and the client to adapt the display :

    • JSON : use json_encode/json_decode on the PHP side, and transport.reponseJSON on the client side
    • XML : print your own XML on the php side, and use transport.responseXML on the client side.
    • The advantage of HTML can also be used to send javascript instruction to the client.

    "); } } - /** - * This is an example of filter that can be hooked to the AJXP_VarsFilter, - * for using your own custom variables in the repositories configurations. - * In this example, this variable does exactly what the current AJXP_USER variable do. - * Thus, once hooked, you can use CUSTOM_VARIABLE_USER in e.g. a repository PATH, and - * build this path dynamically depending on the current user logged. - * Contrary to other standards hooks like node.info, this cannot be added via XML manifest - * as it happen too early in the application, so it must be declared directly inside the conf.php - * - * @param String $value - */ - public static function filterVars(&$value){ - if(AuthService::getLoggedUser() != null){ - $value = str_replace("CUSTOM_VARIABLE_USER", AuthService::getLoggedUser()->getId(), $value); - } - } + /** + * This is an example of filter that can be hooked to the AJXP_VarsFilter, + * for using your own custom variables in the repositories configurations. + * In this example, this variable does exactly what the current AJXP_USER variable do. + * Thus, once hooked, you can use CUSTOM_VARIABLE_USER in e.g. a repository PATH, and + * build this path dynamically depending on the current user logged. + * Contrary to other standards hooks like node.info, this cannot be added via XML manifest + * as it happen too early in the application, so it must be declared directly inside the conf.php + * + * @param String $value + */ + public static function filterVars(&$value) + { + if (AuthService::getLoggedUser() != null) { + $value = str_replace("CUSTOM_VARIABLE_USER", AuthService::getLoggedUser()->getId(), $value); + } + } } - -?> \ No newline at end of file diff --git a/core/src/plugins/action.skeleton/manifest.xml b/core/src/plugins/action.skeleton/manifest.xml index 772700b0a2..b8e5e611a5 100644 --- a/core/src/plugins/action.skeleton/manifest.xml +++ b/core/src/plugins/action.skeleton/manifest.xml @@ -65,4 +65,4 @@ - \ No newline at end of file + diff --git a/core/src/plugins/action.skeleton/res/i18n/conf/en.php b/core/src/plugins/action.skeleton/res/i18n/conf/en.php index b5079f8251..f1900fc66a 100644 --- a/core/src/plugins/action.skeleton/res/i18n/conf/en.php +++ b/core/src/plugins/action.skeleton/res/i18n/conf/en.php @@ -28,4 +28,3 @@ "Button Target Url" => "Button Target Url", "The target URL of the button that will be added to the application" => "The target URL of the button that will be added to the application", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.skeleton/res/i18n/conf/fr.php b/core/src/plugins/action.skeleton/res/i18n/conf/fr.php index e9758e8591..5f44382c8f 100644 --- a/core/src/plugins/action.skeleton/res/i18n/conf/fr.php +++ b/core/src/plugins/action.skeleton/res/i18n/conf/fr.php @@ -28,4 +28,3 @@ "Button Target Url" => "Cible du bouton", "The target URL of the button that will be added to the application" => "URL du bouton ajouté à l'application.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.skeleton/res/i18n/conf/pt.php b/core/src/plugins/action.skeleton/res/i18n/conf/pt.php index 64f8b2bb5e..6eb98617dc 100644 --- a/core/src/plugins/action.skeleton/res/i18n/conf/pt.php +++ b/core/src/plugins/action.skeleton/res/i18n/conf/pt.php @@ -28,4 +28,3 @@ "Button Target Url" => "URL alvo do botão", "The target URL of the button that will be added to the application" => "URL alvo do botão que será adicionado à aplicação", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.skeleton/res/i18n/en.php b/core/src/plugins/action.skeleton/res/i18n/en.php index e9fc0e1123..920c45f564 100644 --- a/core/src/plugins/action.skeleton/res/i18n/en.php +++ b/core/src/plugins/action.skeleton/res/i18n/en.php @@ -1,32 +1,32 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); - -$mess = array( - "1" => "External Link", - "2" => "Link added by the action.skeleton plugin", - "3" => "Are you sure that you want to open %s in a new window?", - "4" => "Modal Link", - "5" => "Open the link in a modal dialog", - "6" => "Dynamic content", - "7" => "Loading content, please wait..." -); + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); + +$mess = array( + "1" => "External Link", + "2" => "Link added by the action.skeleton plugin", + "3" => "Are you sure that you want to open %s in a new window?", + "4" => "Modal Link", + "5" => "Open the link in a modal dialog", + "6" => "Dynamic content", + "7" => "Loading content, please wait..." +); diff --git a/core/src/plugins/action.skeleton/res/i18n/fr.php b/core/src/plugins/action.skeleton/res/i18n/fr.php index 76da42e35c..3a01750edb 100644 --- a/core/src/plugins/action.skeleton/res/i18n/fr.php +++ b/core/src/plugins/action.skeleton/res/i18n/fr.php @@ -27,4 +27,3 @@ "6" => "Contenu dynamique", "7" => "Chargement du contenu, veuillez patienter...", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.timestamp/class.TimestampCreator.php b/core/src/plugins/action.timestamp/class.TimestampCreator.php index 76c449ec74..9ff2058453 100644 --- a/core/src/plugins/action.timestamp/class.TimestampCreator.php +++ b/core/src/plugins/action.timestamp/class.TimestampCreator.php @@ -9,106 +9,103 @@ class TimestampCreator extends AJXP_Plugin { - function switchAction($action, $httpVars, $fileVars){ - - $mess = ConfService::getMessages(); + public function switchAction($action, $httpVars, $fileVars) + { + $mess = ConfService::getMessages(); $timestamp_url = $this->getFilteredOption("TIMESTAMP_URL"); $timestamp_login = $this->getFilteredOption("USER"); $timestamp_password = $this->getFilteredOption("PASS"); //Check if the configuration has been initiated - if(empty($timestamp_url) || empty($timestamp_login) || !empty($timestamp_password) ){ - throw new AJXP_Exception($mess["timestamp.4"]); - AJXP_Logger::logAction("error", "TimeStamp : configuration is needed"); - return false; - } - - - //Check if after being initiated, conf. fields have some values - if(strlen($timestamp_url)<2 || strlen($timestamp_login)<2 || strlen($timestamp_password)<2 ){ - throw new AJXP_Exception($mess["timestamp.4"]); - AJXP_Logger::logAction("error", "TimeStamp : configuration is incorrect"); - return false; - } - - //Get active repository - $repository = ConfService::getRepository(); - if(!$repository->detectStreamWrapper(true)){ - return false; - } - - //Retreive file info - $streamData = $repository->streamData; - $this->streamData = $streamData; - $destStreamURL = $streamData["protocol"]."://".$repository->getId(); - $fileName = AJXP_Utils::decodeSecureMagic($httpVars["file"]); - $fileUrl = $destStreamURL.AJXP_Utils::decodeSecureMagic($httpVars["file"]); - $file = call_user_func(array($this->streamData["classname"], "getRealFSReference"), $fileUrl, true); - - //Hash the file, to send it to Universign - $hashedDataToTimestamp = hash_file('sha256', $file); - - //Check that a tokken is not going to be timestamped ! - if(substr("$file", -4)!='.ers') { - if(file_exists($file.'.ers')) { - throw new AJXP_Exception($mess["timestamp.1"]); - return false; - } - else { - //Prepare the query that will be sent to Universign - $dataToSend = array ('hashAlgo' => 'SHA256', 'withCert' => 'true', 'hashValue' => $hashedDataToTimestamp); - $dataQuery = http_build_query($dataToSend); - - //Check if allow_url_fopen is allowed on the server. If not, it will use cUrl - if(ini_get('allow_url_fopen')) { - $context_options = array ( - 'http' => array ( - 'method' => 'POST', - 'header'=> "Content-type: application/x-www-form-urlencoded\r\n" - ."Content-Length: " . strlen($dataQuery) . "\r\n" - ."Authorization: Basic ".base64_encode($timestamp_login.':'.$timestamp_password)."\r\n", - 'content' => $dataQuery - ) - ); - - //Get the result from Universign - $context = stream_context_create($context_options); - $fp = fopen($timestamp_url, 'r', false, $context); - $tsp = stream_get_contents($fp); - } - //Use Curl if allow_url_fopen is not available - else - { - - $timestamp_header = array ("Content-type: application/x-www-form-urlencoded", "Content-Length: " . strlen($dataQuery), "Authorization: Basic ".base64_encode($timestamp_login.':'.$timestamp_password)); - $timeout = 5; - $ch = curl_init($timestamp_url); - curl_setopt($ch, CURLOPT_POSTFIELDS, $dataQuery ); - curl_setopt($ch,CURLOPT_HTTPHEADER,$timestamp_header ); - curl_setopt($ch, CURLOPT_POST, 1); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + if (empty($timestamp_url) || empty($timestamp_login) || !empty($timestamp_password) ) { + throw new AJXP_Exception($mess["timestamp.4"]); + AJXP_Logger::logAction("error", "TimeStamp : configuration is needed"); + return false; + } + + + //Check if after being initiated, conf. fields have some values + if (strlen($timestamp_url)<2 || strlen($timestamp_login)<2 || strlen($timestamp_password)<2 ) { + throw new AJXP_Exception($mess["timestamp.4"]); + AJXP_Logger::logAction("error", "TimeStamp : configuration is incorrect"); + return false; + } + + //Get active repository + $repository = ConfService::getRepository(); + if (!$repository->detectStreamWrapper(true)) { + return false; + } + + //Retreive file info + $streamData = $repository->streamData; + $this->streamData = $streamData; + $destStreamURL = $streamData["protocol"]."://".$repository->getId(); + $fileName = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + $fileUrl = $destStreamURL.AJXP_Utils::decodeSecureMagic($httpVars["file"]); + $file = call_user_func(array($this->streamData["classname"], "getRealFSReference"), $fileUrl, true); + + //Hash the file, to send it to Universign + $hashedDataToTimestamp = hash_file('sha256', $file); + + //Check that a tokken is not going to be timestamped ! + if (substr("$file", -4)!='.ers') { + if (file_exists($file.'.ers')) { + throw new AJXP_Exception($mess["timestamp.1"]); + return false; + } else { + //Prepare the query that will be sent to Universign + $dataToSend = array ('hashAlgo' => 'SHA256', 'withCert' => 'true', 'hashValue' => $hashedDataToTimestamp); + $dataQuery = http_build_query($dataToSend); + + //Check if allow_url_fopen is allowed on the server. If not, it will use cUrl + if (ini_get('allow_url_fopen')) { + $context_options = array ( + 'http' => array ( + 'method' => 'POST', + 'header'=> "Content-type: application/x-www-form-urlencoded\r\n" + ."Content-Length: " . strlen($dataQuery) . "\r\n" + ."Authorization: Basic ".base64_encode($timestamp_login.':'.$timestamp_password)."\r\n", + 'content' => $dataQuery + ) + ); + + //Get the result from Universign + $context = stream_context_create($context_options); + $fp = fopen($timestamp_url, 'r', false, $context); + $tsp = stream_get_contents($fp); + } + //Use Curl if allow_url_fopen is not available + else { + + $timestamp_header = array ("Content-type: application/x-www-form-urlencoded", "Content-Length: " . strlen($dataQuery), "Authorization: Basic ".base64_encode($timestamp_login.':'.$timestamp_password)); + $timeout = 5; + $ch = curl_init($timestamp_url); + curl_setopt($ch, CURLOPT_POSTFIELDS, $dataQuery ); + curl_setopt($ch,CURLOPT_HTTPHEADER,$timestamp_header ); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //Get the result from Universign - $tsp=curl_exec($ch); - curl_close($ch); - } - - //Save the result to a file - file_put_contents( $file.'.ers', $tsp); - - //Send the succesful message - AJXP_Logger::logAction("TimeStamp", array("files"=>$file, "destination"=>$file.'.ers')); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::reloadDataNode(); - AJXP_XMLWriter::sendMessage($mess["timestamp.3"].$fileName, null); - AJXP_XMLWriter::close(); - } - - } - else{ - throw new AJXP_Exception($mess["timestamp.2"]); - return false; - } - } + $tsp=curl_exec($ch); + curl_close($ch); + } + + //Save the result to a file + file_put_contents( $file.'.ers', $tsp); + + //Send the succesful message + AJXP_Logger::logAction("TimeStamp", array("files"=>$file, "destination"=>$file.'.ers')); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::reloadDataNode(); + AJXP_XMLWriter::sendMessage($mess["timestamp.3"].$fileName, null); + AJXP_XMLWriter::close(); + } + + } else { + throw new AJXP_Exception($mess["timestamp.2"]); + return false; + } + } } diff --git a/core/src/plugins/action.timestamp/i18n/conf/en.php b/core/src/plugins/action.timestamp/i18n/conf/en.php index 3f3e072121..fa5ce1e82f 100644 --- a/core/src/plugins/action.timestamp/i18n/conf/en.php +++ b/core/src/plugins/action.timestamp/i18n/conf/en.php @@ -29,4 +29,3 @@ "User account" => "User account", "User Password" => "User Password", ); -?> diff --git a/core/src/plugins/action.timestamp/i18n/conf/fr.php b/core/src/plugins/action.timestamp/i18n/conf/fr.php index 16f6b1d147..c6e184ed61 100644 --- a/core/src/plugins/action.timestamp/i18n/conf/fr.php +++ b/core/src/plugins/action.timestamp/i18n/conf/fr.php @@ -30,4 +30,3 @@ "User Password" => "Mot de passe utilisateur", "Timestamp" => "Timestamp", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.timestamp/i18n/en.php b/core/src/plugins/action.timestamp/i18n/en.php index 1a2037cb6c..f7a2f00491 100644 --- a/core/src/plugins/action.timestamp/i18n/en.php +++ b/core/src/plugins/action.timestamp/i18n/en.php @@ -1,8 +1,7 @@ - "Warning, a timestamp token is already attached to this file. Delete the token manuallyto be able to add a new one", "2" => "Waring, you can't add a timestamp to a token", "3" => "Timestamp token has already been created for the file ", "4" => "WARNING : Configuration problem, please contact the system administrator as soon as possible.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.timestamp/i18n/fr.php b/core/src/plugins/action.timestamp/i18n/fr.php index a034872843..ab2e1d0bf0 100644 --- a/core/src/plugins/action.timestamp/i18n/fr.php +++ b/core/src/plugins/action.timestamp/i18n/fr.php @@ -1,8 +1,7 @@ - "Attention, Ce fichier a déjà été horodaté. Veuillez manuellement supprimer le jeton pour pouvoir horodater ce fichier à nouveau.", "2" => "Attention, il n'est pas possible d'horodater un jeton d'horodatage", "3" => "Le jeton d'horodatage à ete créé pour le fichier ", "4" => "Problème de configuration. Merci de contacter l'administrateur du système de toute urgence.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.timestamp/manifest.xml b/core/src/plugins/action.timestamp/manifest.xml index af36d2736f..f6948c4026 100644 --- a/core/src/plugins/action.timestamp/manifest.xml +++ b/core/src/plugins/action.timestamp/manifest.xml @@ -17,7 +17,7 @@ - + @@ -63,7 +63,7 @@ }; modal.showDialogForm('Horodater', 'timestamp_form', onLoad, onok); - + ]]> @@ -76,7 +76,7 @@ - + diff --git a/core/src/plugins/action.updater/class.AjaXplorerUpgrader.php b/core/src/plugins/action.updater/class.AjaXplorerUpgrader.php index 0b19428fa9..8efe256d2a 100644 --- a/core/src/plugins/action.updater/class.AjaXplorerUpgrader.php +++ b/core/src/plugins/action.updater/class.AjaXplorerUpgrader.php @@ -1,746 +1,752 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); - - -/** - * @package AjaXplorer_Plugins - * @subpackage Action - */ -class AjaXplorerUpgrader { - - private $archiveURL; - private $archiveHash; - private $archiveHashMethod; - private $markedFiles; - - private $debugMode = FALSE; - private $cleanFile = "UPGRADE/CLEAN-FILES"; - private $additionalScript = "UPGRADE/PHP-SCRIPT"; - private $releaseNote = "UPGRADE/NOTE"; - private $htmlInstructions = "UPGRADE/NOTE-HTML"; - private $dbUpgrade = "UPGRADE/DB-UPGRADE"; - private $installPath; - private static $context = null; - - private $archive; - private $workingFolder; - private $steps; - public $step = 0; - - public $error = null; - public $result = ""; - public $currentStepTitle; - - public function __construct($archiveURL, $hash, $method, $backupFiles = array()){ - $this->archiveURL = $archiveURL; - $this->archiveHash = $hash; - $this->archiveHashMethod = $method; - $this->markedFiles = $backupFiles; - - $this->installPath = AJXP_INSTALL_PATH; - if($this->debugMode){ - @mkdir(AJXP_INSTALL_PATH."/upgrade_test"); - $this->installPath = AJXP_INSTALL_PATH."/upgrade_test"; - } - - $this->workingFolder = AJXP_DATA_PATH."/tmp/update"; - $this->steps = array( - "checkDownloadFolder" => "Checking download permissions", - "downloadArchive" => "Downloading upgrade archive", - "checkArchiveIntegrity" => "Checking archive integrity", - "checkTargetFolder" => "Checking folders permissions", - "extractArchive" => "Extracting Archive", - "backupMarkedFiles" => "Backuping your modified files", - "copyCodeFiles" => "Copying core source files", - "restoreMarkedFiles" => "Restoring your modified files", - "duplicateConfFiles" => "Copying configuration files", - "cleanUnusedFiles" => "Deleting unused files", - "upgradeDB" => "Upgrading database", - "specificTask" => "Running specific upgrade task", - "updateVersion" => "Everything went ok, upgrading version!", - "clearCache" => "Clearing plugins cache", - "displayNote" => "Release note : ", - "displayUpgradeInstructions"=> "Upgrade instructions", - ); - - } - - public static function configureProxy($proxyHost, $proxyUser, $proxyPass){ - $proxy = array( 'http' => array( 'proxy' => 'tcp://'.$proxyHost, 'request_fulluri' => true ) ); - if(!empty($proxyUser) && !empty($proxyPass)) { - $auth = base64_encode($proxyUser.":".$proxyPass); - $proxy['http']['header'] = "Proxy-Authorization: Basic $auth"; - } - self::$context = stream_context_create($proxy); - } - - static function getUpgradePath($url, $format = "php", $channel="stable"){ - if(isSet(self::$context)){ - $json = file_get_contents($url."?channel=".$channel."&version=".AJXP_VERSION, null, self::$context); - }else{ - $json = AJXP_Utils::getRemoteContent($url."?channel=".$channel."&version=".AJXP_VERSION); - } - if($format == "php") return json_decode($json, true); - else return $json; - } - - function hasNextStep(){ - if($this->step < count($this->steps) && $this->error == NULL){ - $stepValues = array_values($this->steps); - $this->currentStepTitle = $stepValues[$this->step]; - return true; - } - return false; - } - - function execute(){ - $stepKeys = array_keys($this->steps); - try{ - if(method_exists($this, $stepKeys[$this->step])){ - $this->result = call_user_func(array($this, $stepKeys[$this->step])); - }else{ - $this->result = "Skipping step, method not found"; - } - }catch(Exception $e){ - $this->error = $e->getMessage(); - } - $this->step ++; - } - - function checkDownloadFolder(){ - if(!is_dir($this->workingFolder)){ - $t = @mkdir($this->workingFolder, 0755, true); - if($t === false) throw new Exception("Cannot create target folder for downloading upgrade archive!"); - } - return "OK"; - } - - function checkTargetFolder(){ - if(!is_writable(AJXP_INSTALL_PATH)){ - throw new Exception("The root install path is not writeable, no file will be copied! - The archive is available on your server, you can copy its manually to override the current installation."); - } - return "OK"; - } - - function downloadArchive(){ - $this->archive = $this->workingFolder."/".basename($this->archiveURL); - if($this->debugMode && is_file($this->archive)) { - return "Already downloaded"; - } - $content = AJXP_Utils::getRemoteContent($this->archiveURL, null, self::$context); - if($content === false || strlen($content) == 0){ - throw new Exception("Error while downloading"); - } - file_put_contents($this->archive, $content); - return "File saved in ".$this->archive; - } - - function extractArchive(){ - require_once(AJXP_BIN_FOLDER . "/pclzip.lib.php"); - $archive = new PclZip($this->archive); - $result = $archive->extract(PCLZIP_OPT_PATH, $this->workingFolder); - if($result <= 0){ - throw new Exception($archive->errorInfo(true)); - }else{ - // Check that there is a new folder without zip extension - if(is_dir($this->workingFolder."/".substr(basename($this->archive), 0, -4)) ){ - $this->workingFolder = $this->workingFolder."/".substr(basename($this->archive), 0, -4); - } - return "Extracted folder ".$this->workingFolder; - } - - } - - function checkArchiveIntegrity(){ - if(!is_file($this->archive)){ - throw new Exception("Cannot find archive file!"); - } - $result = hash_file($this->archiveHashMethod, $this->archive); - if($result != $this->archiveHash){ - throw new Exception("Warning the archive seems corrupted, you should re-download it!"); - } - return "Hash is ok ($this->archiveHash)"; - } - - function backupMarkedFiles(){ - - $targetFolder = $this->installPath; - if(!is_array($this->markedFiles) || !count($this->markedFiles)){ - return "Nothing to do"; - } - foreach($this->markedFiles as $index => $file){ - $file = trim($file); - if(!empty($file) && is_file($targetFolder."/".$file)){ - $newName = $file.".orig-".date("Ymd"); - copy($targetFolder."/".$file, $targetFolder."/".$newName); - }else{ - unset($this->markedFiles[$index]); - } - } - if(!count($this->markedFiles)){ - return "Nothing to do"; - } - return "Backup of ".count($this->markedFiles)." file(s) marked as preserved."; - } - - function copyCodeFiles(){ - // CORE & PLUGINS - $targetFolder = $this->installPath; - self::copy_r($this->workingFolder."/core", $targetFolder."/core"); - self::copy_r($this->workingFolder."/plugins", $targetFolder."/plugins"); - $rootFiles = glob($this->workingFolder."/*.php"); - if($rootFiles !== false){ - foreach($rootFiles as $file){ - copy($file, $targetFolder."/".basename($file)); - } - return "Upgraded core, plugins and base access points."; - }else{ - return "Upgrade core and plugins. Nothing to do at the base"; - } - } - - function restoreMarkedFiles(){ - - if(!count($this->markedFiles)){ - return "Nothing to do"; - } - $targetFolder = $this->installPath; - foreach($this->markedFiles as $file){ - $bakupName = $file.".orig-".date("Ymd"); - $newName = $file.".new-".date("Ymd"); - if(is_file($targetFolder."/".$file) && is_file($targetFolder."/".$bakupName)){ - copy($targetFolder."/".$file, $targetFolder."/".$newName); - copy($targetFolder."/".$bakupName, $targetFolder."/".$file); - unlink($targetFolder."/".$bakupName); - } - } - return "Restoration of ".count($this->markedFiles)." file(s) marked as preserved."; - } - - - function duplicateConfFiles(){ - $confFiles = glob($this->workingFolder."/conf/*.php"); - if($confFiles !== false){ - foreach($confFiles as $file){ - $newFileName = $this->installPath."/conf/".basename($file).".new-".date("Ymd"); - copy($file, $newFileName); - } - } - return "Successfully copied ".count($confFiles)." files inside config folder (not overriden, please review them)"; - } - - - function cleanUnusedFiles(){ - - if(!is_file($this->workingFolder."/".$this->cleanFile)) return "Nothing to do."; - $deleted = array(); - foreach(file($this->workingFolder."/".$this->cleanFile) as $file){ - $file = trim($file); - if(is_file($this->installPath."/".$file)){ - if(in_array($file, $this->markedFiles)){ - rename($this->installPath."/".$file, $this->installPath."/".$file.".unused"); - }else{ - unlink($this->installPath."/".$file); - } - $deleted[] = $file; - } - } - return "Deleted (or backedup) following files : ".implode(", ",$deleted); - - } - - function upgradeDB(){ - - if(!is_file($this->workingFolder."/".$this->dbUpgrade.".sql")) return "Nothing to do."; - $confDriver = ConfService::getConfStorageImpl(); - $authDriver = ConfService::getAuthDriverImpl(); - $logger = AJXP_Logger::getInstance(); - if(is_a($confDriver, "sqlConfDriver")){ - $test = AJXP_Utils::cleanDibiDriverParameters($confDriver->getOption("SQL_DRIVER")); - if(!is_array($test) || !isSet($test["driver"])) return "Nothing to do"; - $type = $test["driver"]; - $file = strpos($test["driver"], "sqlite") === 0 ? $this->dbUpgrade.".sqlite" : $this->dbUpgrade. ".sql"; - $sqlInstructions = file_get_contents($this->workingFolder."/".$file); - - $parts = array_map("trim", explode("/* SEPARATOR */", $sqlInstructions)); - $results = array(); - $errors = array(); - - require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); - dibi::connect($test); - dibi::begin(); - foreach($parts as $sqlPart){ - if(empty($sqlPart)) continue; - try{ - dibi::nativeQuery($sqlPart); - $results[] = $sqlPart; - }catch (DibiException $e){ - $errors[] = $sqlPart. " (". $e->getMessage().")"; - } - } - dibi::commit(); - dibi::disconnect(); - - if(!count($errors)){ - return "Database successfully upgraded"; - }else{ - return "Database upgrade failed.
    The following statements were executed :
    ".implode("
    ", $results).",

    The following statements failed :
    ".implode("
    ", $errors)."

    You should manually upgrade your DB."; - } - - } - - } - - function specificTask(){ - - if(!is_file($this->workingFolder."/".$this->additionalScript)) return "Nothing to do."; - include($this->workingFolder."/".$this->additionalScript); - return "Executed specific upgrade task."; - - } - - function updateVersion(){ - // Finally copy VERSION file - if(!is_file($this->workingFolder."/conf/VERSION")){ - return "No VERSION file in archive"; - } - copy($this->workingFolder."/conf/VERSION", $this->installPath."/conf/VERSION"); - $vCont = file_get_contents($this->installPath."/conf/VERSION"); - list($v, $date) = explode("__", $vCont); - return "Version upgraded to ".$v." ($date)"; - } - - function clearCache(){ - @unlink(AJXP_PLUGINS_CACHE_FILE); - @unlink(AJXP_PLUGINS_REQUIRES_FILE); - @unlink(AJXP_PLUGINS_MESSAGES_FILE); - $i18nFiles = glob(dirname(AJXP_PLUGINS_MESSAGES_FILE)."/i18n/*.ser"); - if(is_array($i18nFiles)){ - foreach($i18nFiles as $file){ - @unlink($file); - } - } - return "Ok"; - } - - function displayNote(){ - if(is_file($this->workingFolder."/".$this->releaseNote)){ - return nl2br(file_get_contents($this->workingFolder."/".$this->releaseNote)); - } - } - - function displayUpgradeInstructions(){ - if(is_file($this->workingFolder."/".$this->htmlInstructions)){ - return "
    ".file_get_contents($this->workingFolder."/".$this->htmlInstructions)." -

    Upgrade report

    -
    "; - } - } - - - public static function upgradeFrom324($oldLocation, $dryRun = true){ - - $mess = ConfService::getMessages(); - $logFile = AJXP_CACHE_DIR."/import_from_324.log"; - if($dryRun){ - print("".$mess["updater.10"]."

    "); - } - - $itemsToCopy = array( - array( - "mask" => "public/*.php", - "target" => "data/public" - ), - array( - "mask" => "public/.ajxp_publiclet_counters.ser", - "target" => "data/public" - ), - array( - "mask" => "server/logs/*.txt", - "target" => "data/logs" - ), - array( - "mask" => "server/conf/repo.ser", - "target" => "data/plugins/conf.serial" - ), - array( - "mask" => "server/conf/aliases.ser", - "target" => "data/plugins/conf.serial" - ), - array( - "mask" => "server/users/*", - "target" => "data/plugins/auth.serial" - ) - ); - - $configToPluginsConf = array( - array( - "type" => "constant", - "name" => "ENABLE_USERS", - "target" => "core.auth/ENABLE_USERS" - ), - array( - "type" => "constant", - "name" => "ALLOW_GUEST_BROWSING", - "target" => "core.auth/ALLOW_GUEST_BROWSING" - ), - array( - "type" => "constant", - "name" => "AJXP_PASSWORD_MINLENGTH", - "target" => "core.auth/PASSWORD_MINLENGTH" - ), - array( - "type" => "variable", - "name" => "AJXP_SESSION_SET_CREDENTIALS", - "target" => "core.auth/SESSION_SET_CREDENTIALS" - ), - array( - "type" => "constant", - "name" => "PUBLIC_DOWNLOAD_FOLDER", - "target" => "core.ajaxplorer/PUBLIC_DOWNLOAD_FOLDER" - ), - array( - "type" => "constant", - "name" => "PUBLIC_DOWNLOAD_URL", - "target" => "core.ajaxplorer/PUBLIC_DOWNLOAD_URL" - ), - array( - "type" => "variable", - "name" => "default_language", - "target" => "core.ajaxplorer/DEFAULT_LANGUAGE" - ), - array( - "type" => "constant", - "name" => "GZIP_DOWNLOAD", - "target" => "core.ajaxplorer/GZIP_COMPRESSION" - ), - array( - "type" => "constant", - "name" => "GZIP_LIMIT", - "target" => "core.ajaxplorer/GZIP_LIMIT" - ), - array( - "type" => "constant", - "name" => "DISABLE_ZIP_CREATION", - "target" => "core.ajaxplorer/ZIP_CREATION", - "modifier" => "NOT" - ), - array( - "type" => "constant", - "name" => "AJXP_WEBDAV_ENABLE", - "target" => "core.ajaxplorer/WEBDAV_ENABLE" - ), - array( - "type" => "constant", - "name" => "AJXP_WEBDAV_BASEURI", - "target" => "core.ajaxplorer/WEBDAV_BASEURI" - ), - array( - "type" => "constant", - "name" => "AJXP_WEBDAV_BASEHOST", - "target" => "core.ajaxplorer/WEBDAV_BASEHOST" - ), - array( - "type" => "constant", - "name" => "AJXP_WEBDAV_DIGESTREALM", - "target" => "core.ajaxplorer/WEBDAV_DIGESTREALM" - ), - array( - "type" => "variable", - "name" => "webmaster_email", - "target" => "core.ajaxplorer/WEBMASTER_EMAIL" - ), - array( - "type" => "variable", - "name" => "max_caracteres", - "target" => "core.ajaxplorer/NODENAME_MAX_LENGTH" - ), - array( - "type" => "variable", - "name" => "customTitle", - "target" => "core.ajaxplorer/APPLICATION_TITLE" - ), - array( - "type" => "constant", - "name" => "HTTPS_POLICY_FILE", - "target" => "uploader.flex/HTTPS_POLICY_FILE" - ), - array( - "type" => "variable", - "name" => "upload_max_number", - "target" => "core.uploader/UPLOAD_MAX_NUMBER" - ), - array( - "type" => "variable", - "name" => "upload_max_size_per_file", - "target" => "core.uploader/UPLOAD_MAX_SIZE" - ), - array( - "type" => "variable", - "name" => "upload_max_size_total", - "target" => "core.uploader/UPLOAD_MAX_SIZE_TOTAL" - ), - array( - "type" => "constant", - "name" => "AJXP_CLIENT_TIMEOUT_TIME", - "target" => "gui.ajax/CLIENT_TIMEOUT_TIME" - ), - array( - "type" => "constant", - "name" => "AJXP_CLIENT_TIMEOUT_WARN_BEFORE", - "target" => "gui.ajax/CLIENT_TIMEOUT_WARN" - ), - array( - "type" => "constant", - "name" => "GOOGLE_ANALYTICS_ID", - "target" => "gui.ajax/GOOGLE_ANALYTICS_ID" - ), - array( - "type" => "constant", - "name" => "GOOGLE_ANALYTICS_DOMAIN", - "target" => "gui.ajax/GOOGLE_ANALYTICS_DOMAIN" - ), - array( - "type" => "constant", - "name" => "GOOGLE_ANALYTICS_EVENT", - "target" => "gui.ajax/GOOGLE_ANALYTICS_EVENT" - ), - array( - "type" => "variable", - "name" => "customTitleFontSize", - "target" => "gui.ajax/CUSTOM_FONT_SIZE" - ), - array( - "type" => "variable", - "name" => "customIcon", - "target" => "gui.ajax/CUSTOM_ICON" - ), - array( - "type" => "variable", - "name" => "customIconWidth", - "target" => "gui.ajax/CUSTOM_ICON_WIDTH" - ), - array( - "type" => "variable", - "name" => "welcomeCustomMessage", - "target" => "gui.ajax/CUSTOM_WELCOME_MESSAGE" - ), - ); - - if(!$dryRun){ - $logFileHandle = fopen($logFile, "w"); - } - - foreach($itemsToCopy as $item){ - $files = glob($oldLocation."/".$item["mask"]); - if($files === false) continue; - foreach ($files as $fileOrFolder){ - $target = AJXP_INSTALL_PATH."/".$item["target"]; - if(is_file($fileOrFolder)){ - $l = "Copy $fileOrFolder to ".$target."/".basename($fileOrFolder)."\n"; - if($dryRun) { - print(nl2br($l)); - }else { - copy($fileOrFolder, $target."/".basename($fileOrFolder)); - fwrite($logFileHandle, $l); - } - - }else{ - $l= "Copy recursively ".$fileOrFolder." to ".$target."/".basename($fileOrFolder)."\n"; - if($dryRun) { - print(nl2br($l)); - }else { - self::copy_r($fileOrFolder, $target."/".basename($fileOrFolder)); - fwrite($logFileHandle, $l); - } - } - } - } - - // FILTER THE CONF FILE TO REMOVE ALL CONSTANTS - $originalConfdir = $oldLocation."/server/conf"; - $lines = file($originalConfdir."/conf.php"); - $filteredLines = array(); - $mutedConstants = array(); - foreach($lines as $line){ - if(preg_match('/define\("(.*)", (.*)\);/', $line, $matches)){ - //var_dump($matches); - $value = trim($matches[2]); - if(!empty($value)){ - if($value[0] == "\""){ - $strValue = substr($value, 1, strlen($value)-2); - if(!empty($strValue)){ - $mutedConstants[$matches[1]] = $strValue; - } - }else if($value == "true"){ - $mutedConstants[$matches[1]] = true; - }else if($value == "false"){ - $mutedConstants[$matches[1]] = false; - }else if(is_numeric($value)){ - $mutedConstants[$matches[1]] = intval($value); - }else{ - eval("\$res = $value;"); - $mutedConstants[$matches[1]] = $res; - } - } - $filteredLines[] = "//".$line; - }else{ - $filteredLines[] = $line; - } - } - if(!$dryRun){ - fwrite($logFileHandle, "Writing alternate version of conf.php without constants."); - } - file_put_contents($originalConfdir."/muted_conf.php", implode("", $filteredLines)); - - // NOW IMPORT THE MODIFIED CONF FILE AND GATHER ALL DATA - include $originalConfdir."/muted_conf.php"; - $allOptions = array(); - foreach ($configToPluginsConf as $localConfig){ - $localConfigName = $localConfig["name"]; - if($localConfig["type"] == "constant" && isset($mutedConstants[$localConfigName])){ - $localConfig["value"] = $mutedConstants[$localConfigName]; - }else if($localConfig["type"] == "variable" && isSet( $$localConfigName )){ - $localConfig["value"] = $$localConfigName; - } - if(!isSet($localConfig["value"]) || empty($localConfig["value"])) continue; - $l = "Should set ".$localConfig["target"]." to value ".$localConfig["value"]."\n"; - if($dryRun){ - $value = AJXP_Utils::xmlEntities($localConfig["value"]); - list($pluginId, $pluginOptionName) = explode("/", $localConfig["target"]); - $plug = AJXP_PluginsService::getInstance()->getPluginById($pluginId); - $options = $plug->getConfigs(); - $options[$pluginOptionName] = $value; - print(nl2br($l)); - } else{ - list($pluginId, $pluginOptionName) = explode("/", $localConfig["target"]); - $confStorage = ConfService::getConfStorageImpl(); - $value = AJXP_Utils::xmlEntities($localConfig["value"]); - if(!isSet($allOptions[$pluginId])){ - $plug = AJXP_PluginsService::getInstance()->getPluginById($pluginId); - $allOptions[$pluginId] = $plug->getConfigs(); - }else{ - $allOptions[$pluginId][$pluginOptionName] = $value; - } - fwrite($logFileHandle, $l); - } - } - if(!$dryRun && count($allOptions)){ - foreach ($allOptions as $pId => $pOptions){ - $confStorage->savePluginConfig($pId, $pOptions); - } - @unlink(AJXP_PLUGINS_CACHE_FILE); - @unlink(AJXP_PLUGINS_REQUIRES_FILE); - @unlink(AJXP_PLUGINS_MESSAGES_FILE); - } - - foreach($REPOSITORIES as $localRepoKey => $localRepoDef){ - $localRepoString = '$REPOSITORIES['.(is_numeric($localRepoKey)?$localRepoKey:'"'.$localRepoKey.'"').'] = '.str_replace(array("'", "\\\\"), array("\"","\\"), var_export($localRepoDef, true)).';'; - $l = "Will print this to bootstrap_repositories : \n". $localRepoString; - if($dryRun) { - print(nl2br($l)); - }else{ - file_put_contents($originalConfdir."/bootstrap_repositories.php", $localRepoString); - fwrite($logFileHandle, $l); - } - } - - if(!$dryRun){ - fclose($logFileHandle); - print("The operation is finished, all actions are logged in $logFile. Nothing was touch on your previous installation, please note that the repositories are not moved.
    You should now logout, clear your browser cache, and refresh this page. Then you will log in with your previous users ids.
    "); - } - - } - - public static function migrateMetaSerialPlugin($repositoryId, $dryRun){ - - $repo = ConfService::getRepositoryById($repositoryId); - if($repo == null) throw new Exception("Cannot find repository!"); - $sources = $repo->getOption("META_SOURCES"); - if(!isSet($sources["meta.serial"])) { - //throw new Exception("This repository does not have the meta.serial plugin!"); - $sources["meta.serial"] = array( - "meta_file_name" => ".ajxp_meta", - "meta_fields" => "comment_field,css_label", - "meta_labels" => "Comment,Label" - ); - } - if($repo->hasParent()) { - throw new Exception("This repository is defined by a template or is shared, you should upgrade the parent instead!"); - } - $oldMetaFileName = $sources["meta.serial"]["meta_file_name"]; - - $sources["metastore.serial"] = array("METADATA_FILE" => $oldMetaFileName, "UPGRADE_FROM_METASERIAL" => true); - $sources["meta.user"] = array( - "meta_fields" => $sources["meta.serial"]["meta_fields"], - "meta_labels" => $sources["meta.serial"]["meta_labels"], - "meta_visibility" => $sources["meta.serial"]["meta_visibility"] - ); - unset($sources["meta.serial"]); - $oldId = $repo->getId(); - $repo->addOption("META_SOURCES", $sources); - $log = print_r($sources, true); - if(!$dryRun){ - ConfService::replaceRepository($oldId, $repo); - } - print("Will replace the META_SOURCES options with the following :
    ".($log)."
    "); - - } - - public static function copy_r( $path, $dest ) - { - if( is_dir($path) ) - { - @mkdir( $dest ); - $objects = scandir($path); - if( sizeof($objects) > 0 ) - { - foreach( $objects as $file ) - { - if( $file == "." || $file == ".." ) - continue; - // go on - if( is_dir( $path.DIRECTORY_SEPARATOR.$file ) ) - { - self::copy_r( $path.DIRECTORY_SEPARATOR.$file, $dest.DIRECTORY_SEPARATOR.$file ); - } - else - { - copy( $path.DIRECTORY_SEPARATOR.$file, $dest.DIRECTORY_SEPARATOR.$file ); - } - } - } - return true; - } - elseif( is_file($path) ) - { - return copy($path, $dest); - } - else - { - return false; - } - } - -} + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); + + +/** + * @package AjaXplorer_Plugins + * @subpackage Action + */ +class AjaXplorerUpgrader +{ + private $archiveURL; + private $archiveHash; + private $archiveHashMethod; + private $markedFiles; + + private $debugMode = FALSE; + private $cleanFile = "UPGRADE/CLEAN-FILES"; + private $additionalScript = "UPGRADE/PHP-SCRIPT"; + private $releaseNote = "UPGRADE/NOTE"; + private $htmlInstructions = "UPGRADE/NOTE-HTML"; + private $dbUpgrade = "UPGRADE/DB-UPGRADE"; + private $installPath; + private static $context = null; + + private $archive; + private $workingFolder; + private $steps; + public $step = 0; + + public $error = null; + public $result = ""; + public $currentStepTitle; + + public function __construct($archiveURL, $hash, $method, $backupFiles = array()) + { + $this->archiveURL = $archiveURL; + $this->archiveHash = $hash; + $this->archiveHashMethod = $method; + $this->markedFiles = $backupFiles; + + $this->installPath = AJXP_INSTALL_PATH; + if ($this->debugMode) { + @mkdir(AJXP_INSTALL_PATH."/upgrade_test"); + $this->installPath = AJXP_INSTALL_PATH."/upgrade_test"; + } + + $this->workingFolder = AJXP_DATA_PATH."/tmp/update"; + $this->steps = array( + "checkDownloadFolder" => "Checking download permissions", + "downloadArchive" => "Downloading upgrade archive", + "checkArchiveIntegrity" => "Checking archive integrity", + "checkTargetFolder" => "Checking folders permissions", + "extractArchive" => "Extracting Archive", + "backupMarkedFiles" => "Backuping your modified files", + "copyCodeFiles" => "Copying core source files", + "restoreMarkedFiles" => "Restoring your modified files", + "duplicateConfFiles" => "Copying configuration files", + "cleanUnusedFiles" => "Deleting unused files", + "upgradeDB" => "Upgrading database", + "specificTask" => "Running specific upgrade task", + "updateVersion" => "Everything went ok, upgrading version!", + "clearCache" => "Clearing plugins cache", + "displayNote" => "Release note : ", + "displayUpgradeInstructions"=> "Upgrade instructions", + ); + + } + + public static function configureProxy($proxyHost, $proxyUser, $proxyPass) + { + $proxy = array( 'http' => array( 'proxy' => 'tcp://'.$proxyHost, 'request_fulluri' => true ) ); + if (!empty($proxyUser) && !empty($proxyPass)) { + $auth = base64_encode($proxyUser.":".$proxyPass); + $proxy['http']['header'] = "Proxy-Authorization: Basic $auth"; + } + self::$context = stream_context_create($proxy); + } + + public static function getUpgradePath($url, $format = "php", $channel="stable") + { + if (isSet(self::$context)) { + $json = file_get_contents($url."?channel=".$channel."&version=".AJXP_VERSION, null, self::$context); + } else { + $json = AJXP_Utils::getRemoteContent($url."?channel=".$channel."&version=".AJXP_VERSION); + } + if($format == "php") return json_decode($json, true); + else return $json; + } + + public function hasNextStep() + { + if ($this->step < count($this->steps) && $this->error == NULL) { + $stepValues = array_values($this->steps); + $this->currentStepTitle = $stepValues[$this->step]; + return true; + } + return false; + } + + public function execute() + { + $stepKeys = array_keys($this->steps); + try { + if (method_exists($this, $stepKeys[$this->step])) { + $this->result = call_user_func(array($this, $stepKeys[$this->step])); + } else { + $this->result = "Skipping step, method not found"; + } + } catch (Exception $e) { + $this->error = $e->getMessage(); + } + $this->step ++; + } + + public function checkDownloadFolder() + { + if (!is_dir($this->workingFolder)) { + $t = @mkdir($this->workingFolder, 0755, true); + if($t === false) throw new Exception("Cannot create target folder for downloading upgrade archive!"); + } + return "OK"; + } + + public function checkTargetFolder() + { + if (!is_writable(AJXP_INSTALL_PATH)) { + throw new Exception("The root install path is not writeable, no file will be copied! + The archive is available on your server, you can copy its manually to override the current installation."); + } + return "OK"; + } + + public function downloadArchive() + { + $this->archive = $this->workingFolder."/".basename($this->archiveURL); + if ($this->debugMode && is_file($this->archive)) { + return "Already downloaded"; + } + $content = AJXP_Utils::getRemoteContent($this->archiveURL, null, self::$context); + if ($content === false || strlen($content) == 0) { + throw new Exception("Error while downloading"); + } + file_put_contents($this->archive, $content); + return "File saved in ".$this->archive; + } + + public function extractArchive() + { + require_once(AJXP_BIN_FOLDER . "/pclzip.lib.php"); + $archive = new PclZip($this->archive); + $result = $archive->extract(PCLZIP_OPT_PATH, $this->workingFolder); + if ($result <= 0) { + throw new Exception($archive->errorInfo(true)); + } else { + // Check that there is a new folder without zip extension + if (is_dir($this->workingFolder."/".substr(basename($this->archive), 0, -4)) ) { + $this->workingFolder = $this->workingFolder."/".substr(basename($this->archive), 0, -4); + } + return "Extracted folder ".$this->workingFolder; + } + + } + + public function checkArchiveIntegrity() + { + if (!is_file($this->archive)) { + throw new Exception("Cannot find archive file!"); + } + $result = hash_file($this->archiveHashMethod, $this->archive); + if ($result != $this->archiveHash) { + throw new Exception("Warning the archive seems corrupted, you should re-download it!"); + } + return "Hash is ok ($this->archiveHash)"; + } + + public function backupMarkedFiles() + { + $targetFolder = $this->installPath; + if (!is_array($this->markedFiles) || !count($this->markedFiles)) { + return "Nothing to do"; + } + foreach ($this->markedFiles as $index => $file) { + $file = trim($file); + if (!empty($file) && is_file($targetFolder."/".$file)) { + $newName = $file.".orig-".date("Ymd"); + copy($targetFolder."/".$file, $targetFolder."/".$newName); + } else { + unset($this->markedFiles[$index]); + } + } + if (!count($this->markedFiles)) { + return "Nothing to do"; + } + return "Backup of ".count($this->markedFiles)." file(s) marked as preserved."; + } + + public function copyCodeFiles() + { + // CORE & PLUGINS + $targetFolder = $this->installPath; + self::copy_r($this->workingFolder."/core", $targetFolder."/core"); + self::copy_r($this->workingFolder."/plugins", $targetFolder."/plugins"); + $rootFiles = glob($this->workingFolder."/*.php"); + if ($rootFiles !== false) { + foreach ($rootFiles as $file) { + copy($file, $targetFolder."/".basename($file)); + } + return "Upgraded core, plugins and base access points."; + } else { + return "Upgrade core and plugins. Nothing to do at the base"; + } + } + + public function restoreMarkedFiles() + { + if (!count($this->markedFiles)) { + return "Nothing to do"; + } + $targetFolder = $this->installPath; + foreach ($this->markedFiles as $file) { + $bakupName = $file.".orig-".date("Ymd"); + $newName = $file.".new-".date("Ymd"); + if (is_file($targetFolder."/".$file) && is_file($targetFolder."/".$bakupName)) { + copy($targetFolder."/".$file, $targetFolder."/".$newName); + copy($targetFolder."/".$bakupName, $targetFolder."/".$file); + unlink($targetFolder."/".$bakupName); + } + } + return "Restoration of ".count($this->markedFiles)." file(s) marked as preserved."; + } + + + public function duplicateConfFiles() + { + $confFiles = glob($this->workingFolder."/conf/*.php"); + if ($confFiles !== false) { + foreach ($confFiles as $file) { + $newFileName = $this->installPath."/conf/".basename($file).".new-".date("Ymd"); + copy($file, $newFileName); + } + } + return "Successfully copied ".count($confFiles)." files inside config folder (not overriden, please review them)"; + } + + + public function cleanUnusedFiles() + { + if(!is_file($this->workingFolder."/".$this->cleanFile)) return "Nothing to do."; + $deleted = array(); + foreach (file($this->workingFolder."/".$this->cleanFile) as $file) { + $file = trim($file); + if (is_file($this->installPath."/".$file)) { + if (in_array($file, $this->markedFiles)) { + rename($this->installPath."/".$file, $this->installPath."/".$file.".unused"); + } else { + unlink($this->installPath."/".$file); + } + $deleted[] = $file; + } + } + return "Deleted (or backedup) following files : ".implode(", ",$deleted); + + } + + public function upgradeDB() + { + if(!is_file($this->workingFolder."/".$this->dbUpgrade.".sql")) return "Nothing to do."; + $confDriver = ConfService::getConfStorageImpl(); + $authDriver = ConfService::getAuthDriverImpl(); + $logger = AJXP_Logger::getInstance(); + if (is_a($confDriver, "sqlConfDriver")) { + $test = AJXP_Utils::cleanDibiDriverParameters($confDriver->getOption("SQL_DRIVER")); + if(!is_array($test) || !isSet($test["driver"])) return "Nothing to do"; + $type = $test["driver"]; + $file = strpos($test["driver"], "sqlite") === 0 ? $this->dbUpgrade.".sqlite" : $this->dbUpgrade. ".sql"; + $sqlInstructions = file_get_contents($this->workingFolder."/".$file); + + $parts = array_map("trim", explode("/* SEPARATOR */", $sqlInstructions)); + $results = array(); + $errors = array(); + + require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); + dibi::connect($test); + dibi::begin(); + foreach ($parts as $sqlPart) { + if(empty($sqlPart)) continue; + try { + dibi::nativeQuery($sqlPart); + $results[] = $sqlPart; + } catch (DibiException $e) { + $errors[] = $sqlPart. " (". $e->getMessage().")"; + } + } + dibi::commit(); + dibi::disconnect(); + + if (!count($errors)) { + return "Database successfully upgraded"; + } else { + return "Database upgrade failed.
    The following statements were executed :
    ".implode("
    ", $results).",

    The following statements failed :
    ".implode("
    ", $errors)."

    You should manually upgrade your DB."; + } + + } + + } + + public function specificTask() + { + if(!is_file($this->workingFolder."/".$this->additionalScript)) return "Nothing to do."; + include($this->workingFolder."/".$this->additionalScript); + return "Executed specific upgrade task."; + + } + + public function updateVersion() + { + // Finally copy VERSION file + if (!is_file($this->workingFolder."/conf/VERSION")) { + return "No VERSION file in archive"; + } + copy($this->workingFolder."/conf/VERSION", $this->installPath."/conf/VERSION"); + $vCont = file_get_contents($this->installPath."/conf/VERSION"); + list($v, $date) = explode("__", $vCont); + return "Version upgraded to ".$v." ($date)"; + } + + public function clearCache() + { + @unlink(AJXP_PLUGINS_CACHE_FILE); + @unlink(AJXP_PLUGINS_REQUIRES_FILE); + @unlink(AJXP_PLUGINS_MESSAGES_FILE); + $i18nFiles = glob(dirname(AJXP_PLUGINS_MESSAGES_FILE)."/i18n/*.ser"); + if (is_array($i18nFiles)) { + foreach ($i18nFiles as $file) { + @unlink($file); + } + } + return "Ok"; + } + + public function displayNote() + { + if (is_file($this->workingFolder."/".$this->releaseNote)) { + return nl2br(file_get_contents($this->workingFolder."/".$this->releaseNote)); + } + } + + public function displayUpgradeInstructions() + { + if (is_file($this->workingFolder."/".$this->htmlInstructions)) { + return "
    ".file_get_contents($this->workingFolder."/".$this->htmlInstructions)." +

    Upgrade report

    +
    "; + } + } + + + public static function upgradeFrom324($oldLocation, $dryRun = true) + { + $mess = ConfService::getMessages(); + $logFile = AJXP_CACHE_DIR."/import_from_324.log"; + if ($dryRun) { + print("".$mess["updater.10"]."

    "); + } + + $itemsToCopy = array( + array( + "mask" => "public/*.php", + "target" => "data/public" + ), + array( + "mask" => "public/.ajxp_publiclet_counters.ser", + "target" => "data/public" + ), + array( + "mask" => "server/logs/*.txt", + "target" => "data/logs" + ), + array( + "mask" => "server/conf/repo.ser", + "target" => "data/plugins/conf.serial" + ), + array( + "mask" => "server/conf/aliases.ser", + "target" => "data/plugins/conf.serial" + ), + array( + "mask" => "server/users/*", + "target" => "data/plugins/auth.serial" + ) + ); + + $configToPluginsConf = array( + array( + "type" => "constant", + "name" => "ENABLE_USERS", + "target" => "core.auth/ENABLE_USERS" + ), + array( + "type" => "constant", + "name" => "ALLOW_GUEST_BROWSING", + "target" => "core.auth/ALLOW_GUEST_BROWSING" + ), + array( + "type" => "constant", + "name" => "AJXP_PASSWORD_MINLENGTH", + "target" => "core.auth/PASSWORD_MINLENGTH" + ), + array( + "type" => "variable", + "name" => "AJXP_SESSION_SET_CREDENTIALS", + "target" => "core.auth/SESSION_SET_CREDENTIALS" + ), + array( + "type" => "constant", + "name" => "PUBLIC_DOWNLOAD_FOLDER", + "target" => "core.ajaxplorer/PUBLIC_DOWNLOAD_FOLDER" + ), + array( + "type" => "constant", + "name" => "PUBLIC_DOWNLOAD_URL", + "target" => "core.ajaxplorer/PUBLIC_DOWNLOAD_URL" + ), + array( + "type" => "variable", + "name" => "default_language", + "target" => "core.ajaxplorer/DEFAULT_LANGUAGE" + ), + array( + "type" => "constant", + "name" => "GZIP_DOWNLOAD", + "target" => "core.ajaxplorer/GZIP_COMPRESSION" + ), + array( + "type" => "constant", + "name" => "GZIP_LIMIT", + "target" => "core.ajaxplorer/GZIP_LIMIT" + ), + array( + "type" => "constant", + "name" => "DISABLE_ZIP_CREATION", + "target" => "core.ajaxplorer/ZIP_CREATION", + "modifier" => "NOT" + ), + array( + "type" => "constant", + "name" => "AJXP_WEBDAV_ENABLE", + "target" => "core.ajaxplorer/WEBDAV_ENABLE" + ), + array( + "type" => "constant", + "name" => "AJXP_WEBDAV_BASEURI", + "target" => "core.ajaxplorer/WEBDAV_BASEURI" + ), + array( + "type" => "constant", + "name" => "AJXP_WEBDAV_BASEHOST", + "target" => "core.ajaxplorer/WEBDAV_BASEHOST" + ), + array( + "type" => "constant", + "name" => "AJXP_WEBDAV_DIGESTREALM", + "target" => "core.ajaxplorer/WEBDAV_DIGESTREALM" + ), + array( + "type" => "variable", + "name" => "webmaster_email", + "target" => "core.ajaxplorer/WEBMASTER_EMAIL" + ), + array( + "type" => "variable", + "name" => "max_caracteres", + "target" => "core.ajaxplorer/NODENAME_MAX_LENGTH" + ), + array( + "type" => "variable", + "name" => "customTitle", + "target" => "core.ajaxplorer/APPLICATION_TITLE" + ), + array( + "type" => "constant", + "name" => "HTTPS_POLICY_FILE", + "target" => "uploader.flex/HTTPS_POLICY_FILE" + ), + array( + "type" => "variable", + "name" => "upload_max_number", + "target" => "core.uploader/UPLOAD_MAX_NUMBER" + ), + array( + "type" => "variable", + "name" => "upload_max_size_per_file", + "target" => "core.uploader/UPLOAD_MAX_SIZE" + ), + array( + "type" => "variable", + "name" => "upload_max_size_total", + "target" => "core.uploader/UPLOAD_MAX_SIZE_TOTAL" + ), + array( + "type" => "constant", + "name" => "AJXP_CLIENT_TIMEOUT_TIME", + "target" => "gui.ajax/CLIENT_TIMEOUT_TIME" + ), + array( + "type" => "constant", + "name" => "AJXP_CLIENT_TIMEOUT_WARN_BEFORE", + "target" => "gui.ajax/CLIENT_TIMEOUT_WARN" + ), + array( + "type" => "constant", + "name" => "GOOGLE_ANALYTICS_ID", + "target" => "gui.ajax/GOOGLE_ANALYTICS_ID" + ), + array( + "type" => "constant", + "name" => "GOOGLE_ANALYTICS_DOMAIN", + "target" => "gui.ajax/GOOGLE_ANALYTICS_DOMAIN" + ), + array( + "type" => "constant", + "name" => "GOOGLE_ANALYTICS_EVENT", + "target" => "gui.ajax/GOOGLE_ANALYTICS_EVENT" + ), + array( + "type" => "variable", + "name" => "customTitleFontSize", + "target" => "gui.ajax/CUSTOM_FONT_SIZE" + ), + array( + "type" => "variable", + "name" => "customIcon", + "target" => "gui.ajax/CUSTOM_ICON" + ), + array( + "type" => "variable", + "name" => "customIconWidth", + "target" => "gui.ajax/CUSTOM_ICON_WIDTH" + ), + array( + "type" => "variable", + "name" => "welcomeCustomMessage", + "target" => "gui.ajax/CUSTOM_WELCOME_MESSAGE" + ), + ); + + if (!$dryRun) { + $logFileHandle = fopen($logFile, "w"); + } + + foreach ($itemsToCopy as $item) { + $files = glob($oldLocation."/".$item["mask"]); + if($files === false) continue; + foreach ($files as $fileOrFolder) { + $target = AJXP_INSTALL_PATH."/".$item["target"]; + if (is_file($fileOrFolder)) { + $l = "Copy $fileOrFolder to ".$target."/".basename($fileOrFolder)."\n"; + if ($dryRun) { + print(nl2br($l)); + } else { + copy($fileOrFolder, $target."/".basename($fileOrFolder)); + fwrite($logFileHandle, $l); + } + + } else { + $l= "Copy recursively ".$fileOrFolder." to ".$target."/".basename($fileOrFolder)."\n"; + if ($dryRun) { + print(nl2br($l)); + } else { + self::copy_r($fileOrFolder, $target."/".basename($fileOrFolder)); + fwrite($logFileHandle, $l); + } + } + } + } + + // FILTER THE CONF FILE TO REMOVE ALL CONSTANTS + $originalConfdir = $oldLocation."/server/conf"; + $lines = file($originalConfdir."/conf.php"); + $filteredLines = array(); + $mutedConstants = array(); + foreach ($lines as $line) { + if (preg_match('/define\("(.*)", (.*)\);/', $line, $matches)) { + //var_dump($matches); + $value = trim($matches[2]); + if (!empty($value)) { + if ($value[0] == "\"") { + $strValue = substr($value, 1, strlen($value)-2); + if (!empty($strValue)) { + $mutedConstants[$matches[1]] = $strValue; + } + } else if ($value == "true") { + $mutedConstants[$matches[1]] = true; + } else if ($value == "false") { + $mutedConstants[$matches[1]] = false; + } else if (is_numeric($value)) { + $mutedConstants[$matches[1]] = intval($value); + } else { + eval("\$res = $value;"); + $mutedConstants[$matches[1]] = $res; + } + } + $filteredLines[] = "//".$line; + } else { + $filteredLines[] = $line; + } + } + if (!$dryRun) { + fwrite($logFileHandle, "Writing alternate version of conf.php without constants."); + } + file_put_contents($originalConfdir."/muted_conf.php", implode("", $filteredLines)); + + // NOW IMPORT THE MODIFIED CONF FILE AND GATHER ALL DATA + include $originalConfdir."/muted_conf.php"; + $allOptions = array(); + foreach ($configToPluginsConf as $localConfig) { + $localConfigName = $localConfig["name"]; + if ($localConfig["type"] == "constant" && isset($mutedConstants[$localConfigName])) { + $localConfig["value"] = $mutedConstants[$localConfigName]; + } else if ($localConfig["type"] == "variable" && isSet( $$localConfigName )) { + $localConfig["value"] = $$localConfigName; + } + if(!isSet($localConfig["value"]) || empty($localConfig["value"])) continue; + $l = "Should set ".$localConfig["target"]." to value ".$localConfig["value"]."\n"; + if ($dryRun) { + $value = AJXP_Utils::xmlEntities($localConfig["value"]); + list($pluginId, $pluginOptionName) = explode("/", $localConfig["target"]); + $plug = AJXP_PluginsService::getInstance()->getPluginById($pluginId); + $options = $plug->getConfigs(); + $options[$pluginOptionName] = $value; + print(nl2br($l)); + } else { + list($pluginId, $pluginOptionName) = explode("/", $localConfig["target"]); + $confStorage = ConfService::getConfStorageImpl(); + $value = AJXP_Utils::xmlEntities($localConfig["value"]); + if (!isSet($allOptions[$pluginId])) { + $plug = AJXP_PluginsService::getInstance()->getPluginById($pluginId); + $allOptions[$pluginId] = $plug->getConfigs(); + } else { + $allOptions[$pluginId][$pluginOptionName] = $value; + } + fwrite($logFileHandle, $l); + } + } + if (!$dryRun && count($allOptions)) { + foreach ($allOptions as $pId => $pOptions) { + $confStorage->savePluginConfig($pId, $pOptions); + } + @unlink(AJXP_PLUGINS_CACHE_FILE); + @unlink(AJXP_PLUGINS_REQUIRES_FILE); + @unlink(AJXP_PLUGINS_MESSAGES_FILE); + } + + foreach ($REPOSITORIES as $localRepoKey => $localRepoDef) { + $localRepoString = '$REPOSITORIES['.(is_numeric($localRepoKey)?$localRepoKey:'"'.$localRepoKey.'"').'] = '.str_replace(array("'", "\\\\"), array("\"","\\"), var_export($localRepoDef, true)).';'; + $l = "Will print this to bootstrap_repositories : \n". $localRepoString; + if ($dryRun) { + print(nl2br($l)); + } else { + file_put_contents($originalConfdir."/bootstrap_repositories.php", $localRepoString); + fwrite($logFileHandle, $l); + } + } + + if (!$dryRun) { + fclose($logFileHandle); + print("The operation is finished, all actions are logged in $logFile. Nothing was touch on your previous installation, please note that the repositories are not moved.
    You should now logout, clear your browser cache, and refresh this page. Then you will log in with your previous users ids.
    "); + } + + } + + public static function migrateMetaSerialPlugin($repositoryId, $dryRun) + { + $repo = ConfService::getRepositoryById($repositoryId); + if($repo == null) throw new Exception("Cannot find repository!"); + $sources = $repo->getOption("META_SOURCES"); + if (!isSet($sources["meta.serial"])) { + //throw new Exception("This repository does not have the meta.serial plugin!"); + $sources["meta.serial"] = array( + "meta_file_name" => ".ajxp_meta", + "meta_fields" => "comment_field,css_label", + "meta_labels" => "Comment,Label" + ); + } + if ($repo->hasParent()) { + throw new Exception("This repository is defined by a template or is shared, you should upgrade the parent instead!"); + } + $oldMetaFileName = $sources["meta.serial"]["meta_file_name"]; + + $sources["metastore.serial"] = array("METADATA_FILE" => $oldMetaFileName, "UPGRADE_FROM_METASERIAL" => true); + $sources["meta.user"] = array( + "meta_fields" => $sources["meta.serial"]["meta_fields"], + "meta_labels" => $sources["meta.serial"]["meta_labels"], + "meta_visibility" => $sources["meta.serial"]["meta_visibility"] + ); + unset($sources["meta.serial"]); + $oldId = $repo->getId(); + $repo->addOption("META_SOURCES", $sources); + $log = print_r($sources, true); + if (!$dryRun) { + ConfService::replaceRepository($oldId, $repo); + } + print("Will replace the META_SOURCES options with the following :
    ".($log)."
    "); + + } + + public static function copy_r( $path, $dest ) + { + if ( is_dir($path) ) { + @mkdir( $dest ); + $objects = scandir($path); + if ( sizeof($objects) > 0 ) { + foreach ($objects as $file) { + if( $file == "." || $file == ".." ) + continue; + // go on + if ( is_dir( $path.DIRECTORY_SEPARATOR.$file ) ) { + self::copy_r( $path.DIRECTORY_SEPARATOR.$file, $dest.DIRECTORY_SEPARATOR.$file ); + } else { + copy( $path.DIRECTORY_SEPARATOR.$file, $dest.DIRECTORY_SEPARATOR.$file ); + } + } + } + return true; + } elseif ( is_file($path) ) { + return copy($path, $dest); + } else { + return false; + } + } + +} diff --git a/core/src/plugins/action.updater/class.UpdateController.php b/core/src/plugins/action.updater/class.UpdateController.php index 1ab9be835c..fa7e631617 100644 --- a/core/src/plugins/action.updater/class.UpdateController.php +++ b/core/src/plugins/action.updater/class.UpdateController.php @@ -1,153 +1,156 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * @package AjaXplorer_Plugins - * @subpackage Action - */ -class UpdateController extends AJXP_Plugin { - - public function init($options){ - parent::init($options); - $u = AuthService::getLoggedUser(); - if($u == null) return; - if($u->getGroupPath() != "/"){ - $this->enabled = false; - } - } - - /** - * Parse - * @param DOMNode $contribNode - */ - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($this->pluginConf["ENABLE_324_IMPORT"] == true) return; - - if($contribNode->nodeName != "actions") return ; - $actionXpath=new DOMXPath($contribNode->ownerDocument); - $compressNodeList = $actionXpath->query('action[@name="import_from_324"]', $contribNode); - if(!$compressNodeList->length) return ; - unset($this->actions["import_from_324"]); - $compressNode = $compressNodeList->item(0); - $contribNode->removeChild($compressNode); - - $compressNodeList = $actionXpath->query('action[@name="migrate_metaserial"]', $contribNode); - if(!$compressNodeList->length) return ; - unset($this->actions["import_from_324"]); - $compressNode = $compressNodeList->item(0); - $contribNode->removeChild($compressNode); - } - - function switchAction($action, $httpVars, $fileVars){ - if(!isSet($this->actions[$action])) return; - $loggedUser = AuthService::getLoggedUser(); - if(AuthService::usersEnabled() && !$loggedUser->isAdmin()) return ; - require_once(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/action.updater/class.AjaXplorerUpgrader.php"); - if(!empty($this->pluginConf["PROXY_HOST"])){ - AjaXplorerUpgrader::configureProxy( - $this->pluginConf["PROXY_HOST"], - $this->pluginConf["PROXY_USER"], - $this->pluginConf["PROXY_PASS"] - ); - } - - switch ($action){ - - - case "import_from_324": - - $dryRun = !isSet($httpVars["real_run"]); - AjaXplorerUpgrader::upgradeFrom324($httpVars["previous_location"], $dryRun); - - break; - - case "migrate_metaserial": - - $dryRun = !isSet($httpVars["real_run"]); - AjaXplorerUpgrader::migrateMetaSerialPlugin($httpVars["repository_id"], $dryRun); - - break; - - case "get_upgrade_path": - - header("Content-type: application/json"); - print AjaXplorerUpgrader::getUpgradePath($this->pluginConf["UPDATE_SITE"], "json", $this->pluginConf["UPDATE_CHANNEL"]); - - break; - - case "perform_upgrade" : - - AJXP_Utils::safeIniSet("output_buffering", "Off"); - if(AJXP_PACKAGING != "zip"){ - print "Your installation is managed directly via os packages, you should not upgrade manually."; - break; - } - $res = AjaXplorerUpgrader::getUpgradePath($this->pluginConf["UPDATE_SITE"], "php", $this->pluginConf["UPDATE_CHANNEL"]); - if(!count($res["packages"])){ - print("No update is necessary!"); - break; - } - include(dirname(__FILE__)."/output_head.html"); - foreach($res["packages"] as $index => $zipPackage){ - print("
    Applying upgrade ".basename($zipPackage)."
    "); - $u = new AjaXplorerUpgrader( - $zipPackage, - $res["hashes"][$index], - $res["hash_method"], - explode(",",$this->pluginConf["PRESERVE_FILES"]) - ); - $errors = false; - while($u->hasNextStep()){ - set_time_limit(180); - print("
    ".$u->currentStepTitle."
    "); - $u->execute(); - if($u->error != null){ - print("
    - Error : ".$u->error."
    "); - $errors = true; - break; - }else{ - print("
    - ".$u->result."
    "); - } - print("
    "); - // FLUSH OUTPUT, SCROLL DOWN - print str_repeat(' ',300); - print(''); - flush(); - sleep(0.5); - } - if($errors) break; - } - print(''); - print str_repeat(' ',300); - flush(); - - - break; - - - } - - } - -} + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * @package AjaXplorer_Plugins + * @subpackage Action + */ +class UpdateController extends AJXP_Plugin +{ + public function init($options) + { + parent::init($options); + $u = AuthService::getLoggedUser(); + if($u == null) return; + if ($u->getGroupPath() != "/") { + $this->enabled = false; + } + } + + /** + * Parse + * @param DOMNode $contribNode + */ + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if($this->pluginConf["ENABLE_324_IMPORT"] == true) return; + + if($contribNode->nodeName != "actions") return ; + $actionXpath=new DOMXPath($contribNode->ownerDocument); + $compressNodeList = $actionXpath->query('action[@name="import_from_324"]', $contribNode); + if(!$compressNodeList->length) return ; + unset($this->actions["import_from_324"]); + $compressNode = $compressNodeList->item(0); + $contribNode->removeChild($compressNode); + + $compressNodeList = $actionXpath->query('action[@name="migrate_metaserial"]', $contribNode); + if(!$compressNodeList->length) return ; + unset($this->actions["import_from_324"]); + $compressNode = $compressNodeList->item(0); + $contribNode->removeChild($compressNode); + } + + public function switchAction($action, $httpVars, $fileVars) + { + if(!isSet($this->actions[$action])) return; + $loggedUser = AuthService::getLoggedUser(); + if(AuthService::usersEnabled() && !$loggedUser->isAdmin()) return ; + require_once(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/action.updater/class.AjaXplorerUpgrader.php"); + if (!empty($this->pluginConf["PROXY_HOST"])) { + AjaXplorerUpgrader::configureProxy( + $this->pluginConf["PROXY_HOST"], + $this->pluginConf["PROXY_USER"], + $this->pluginConf["PROXY_PASS"] + ); + } + + switch ($action) { + + + case "import_from_324": + + $dryRun = !isSet($httpVars["real_run"]); + AjaXplorerUpgrader::upgradeFrom324($httpVars["previous_location"], $dryRun); + + break; + + case "migrate_metaserial": + + $dryRun = !isSet($httpVars["real_run"]); + AjaXplorerUpgrader::migrateMetaSerialPlugin($httpVars["repository_id"], $dryRun); + + break; + + case "get_upgrade_path": + + header("Content-type: application/json"); + print AjaXplorerUpgrader::getUpgradePath($this->pluginConf["UPDATE_SITE"], "json", $this->pluginConf["UPDATE_CHANNEL"]); + + break; + + case "perform_upgrade" : + + AJXP_Utils::safeIniSet("output_buffering", "Off"); + if (AJXP_PACKAGING != "zip") { + print "Your installation is managed directly via os packages, you should not upgrade manually."; + break; + } + $res = AjaXplorerUpgrader::getUpgradePath($this->pluginConf["UPDATE_SITE"], "php", $this->pluginConf["UPDATE_CHANNEL"]); + if (!count($res["packages"])) { + print("No update is necessary!"); + break; + } + include(dirname(__FILE__)."/output_head.html"); + foreach ($res["packages"] as $index => $zipPackage) { + print("
    Applying upgrade ".basename($zipPackage)."
    "); + $u = new AjaXplorerUpgrader( + $zipPackage, + $res["hashes"][$index], + $res["hash_method"], + explode(",",$this->pluginConf["PRESERVE_FILES"]) + ); + $errors = false; + while ($u->hasNextStep()) { + set_time_limit(180); + print("
    ".$u->currentStepTitle."
    "); + $u->execute(); + if ($u->error != null) { + print("
    - Error : ".$u->error."
    "); + $errors = true; + break; + } else { + print("
    - ".$u->result."
    "); + } + print("
    "); + // FLUSH OUTPUT, SCROLL DOWN + print str_repeat(' ',300); + print(''); + flush(); + sleep(0.5); + } + if($errors) break; + } + print(''); + print str_repeat(' ',300); + flush(); + + + break; + + + } + + } + +} diff --git a/core/src/plugins/action.updater/i18n/conf/en.php b/core/src/plugins/action.updater/i18n/conf/en.php index 9f41d5e3c5..e23c966868 100644 --- a/core/src/plugins/action.updater/i18n/conf/en.php +++ b/core/src/plugins/action.updater/i18n/conf/en.php @@ -30,4 +30,3 @@ "Update Channel" => "Update Channel", "Check stable or dev channel" => "Check stable or dev channel", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.updater/i18n/conf/fr.php b/core/src/plugins/action.updater/i18n/conf/fr.php index 4c550d4551..79f124dac0 100644 --- a/core/src/plugins/action.updater/i18n/conf/fr.php +++ b/core/src/plugins/action.updater/i18n/conf/fr.php @@ -30,4 +30,3 @@ "Update Channel" => "Canal", "Check stable or dev channel" => "Canal stable ou développement", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.updater/i18n/conf/pt.php b/core/src/plugins/action.updater/i18n/conf/pt.php index 4778300c9f..9e16447265 100644 --- a/core/src/plugins/action.updater/i18n/conf/pt.php +++ b/core/src/plugins/action.updater/i18n/conf/pt.php @@ -30,4 +30,3 @@ "Update Channel" => "Canal de Actualizações", "Check stable or dev channel" => "Seleccione o canal Estável ou Dev", ); -?> \ No newline at end of file diff --git a/core/src/plugins/action.updater/i18n/en.php b/core/src/plugins/action.updater/i18n/en.php index b4136398d4..7a4b3d3c49 100644 --- a/core/src/plugins/action.updater/i18n/en.php +++ b/core/src/plugins/action.updater/i18n/en.php @@ -1,39 +1,39 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); - -$mess = array( - "1" => "Upgrade", - "2" => "Automatic version upgrade", - "3" => "Click on the button to start automatic upgrade procedure. Please check that the application folder is writeable before launching upgrade.", - "4" => "Start Upgrade", - "5" => "From 3.2.4", - "6" => "Import configuration data from 3.2.4", - "7" => "Simulate the data import", - "8" => "Enter full path (from server root) to the previous location, then run the simulation", - "9" => "Run real import now", - "10"=> "This is a 'dry-run'. Please review the logs of all actions that will be performed, and if it's ok for you press 'Run real import now'", - "11"=> "Migrate meta.serial", - "12"=> "Old meta.serial plugin was removed and split into metastore.serial and meta.user", - "13"=> "Simulate migration", - "14"=> "Run migration now", -); \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); + +$mess = array( + "1" => "Upgrade", + "2" => "Automatic version upgrade", + "3" => "Click on the button to start automatic upgrade procedure. Please check that the application folder is writeable before launching upgrade.", + "4" => "Start Upgrade", + "5" => "From 3.2.4", + "6" => "Import configuration data from 3.2.4", + "7" => "Simulate the data import", + "8" => "Enter full path (from server root) to the previous location, then run the simulation", + "9" => "Run real import now", + "10"=> "This is a 'dry-run'. Please review the logs of all actions that will be performed, and if it's ok for you press 'Run real import now'", + "11"=> "Migrate meta.serial", + "12"=> "Old meta.serial plugin was removed and split into metastore.serial and meta.user", + "13"=> "Simulate migration", + "14"=> "Run migration now", +); diff --git a/core/src/plugins/action.updater/i18n/pt.php b/core/src/plugins/action.updater/i18n/pt.php index df9fd46e9c..444f2774bf 100644 --- a/core/src/plugins/action.updater/i18n/pt.php +++ b/core/src/plugins/action.updater/i18n/pt.php @@ -20,7 +20,7 @@ */ defined('AJXP_EXEC') or die( 'Access not allowed'); - + $mess = array( "1" => "Actualizar", "2" => "Actualizar para novas versões automaticamente", @@ -36,4 +36,4 @@ "12"=> "Os dados meta.serial antigos do plugin foram removidos e divididos entre metastore.serial e meta.user", "13"=> "Simular Migração", "14"=> "Correr Migração agora", -); \ No newline at end of file +); diff --git a/core/src/plugins/action.updater/manifest.xml b/core/src/plugins/action.updater/manifest.xml index 026017d798..af224b618f 100644 --- a/core/src/plugins/action.updater/manifest.xml +++ b/core/src/plugins/action.updater/manifest.xml @@ -189,4 +189,4 @@ - \ No newline at end of file + diff --git a/core/src/plugins/auth.basic_http/class.basic_httpAuthDriver.php b/core/src/plugins/auth.basic_http/class.basic_httpAuthDriver.php index 4c6ed094a9..c5067bcec0 100644 --- a/core/src/plugins/auth.basic_http/class.basic_httpAuthDriver.php +++ b/core/src/plugins/auth.basic_http/class.basic_httpAuthDriver.php @@ -25,36 +25,39 @@ * @package AjaXplorer_Plugins * @subpackage Auth */ -class basic_httpAuthDriver extends serialAuthDriver { - - function usersEditable(){ - return false; - } - function passwordsEditable(){ - return false; - } - - function preLogUser($sessionId){ - $localHttpLogin = $_SERVER["REMOTE_USER"]; - if(!isSet($localHttpLogin)) return ; +class basic_httpAuthDriver extends serialAuthDriver +{ + public function usersEditable() + { + return false; + } + public function passwordsEditable() + { + return false; + } + + public function preLogUser($sessionId) + { + $localHttpLogin = $_SERVER["REMOTE_USER"]; + if(!isSet($localHttpLogin)) return ; $localHttpPassw = (isset($_SERVER['PHP_AUTH_PW'])) ? $_SERVER['PHP_AUTH_PW'] : md5(microtime(true)) ; - if($this->autoCreateUser()){ - if(!$this->userExists($localHttpLogin)){ - $this->createUser($localHttpLogin, $localHttpPassw); - } - AuthService::logUser($localHttpLogin, $localHttpPassw, true); - }else{ - // If not auto-create but the user exists, log him. - if($this->userExists($localHttpLogin)){ - AuthService::logUser($localHttpLogin, "", true); - } - } - + if ($this->autoCreateUser()) { + if (!$this->userExists($localHttpLogin)) { + $this->createUser($localHttpLogin, $localHttpPassw); + } + AuthService::logUser($localHttpLogin, $localHttpPassw, true); + } else { + // If not auto-create but the user exists, log him. + if ($this->userExists($localHttpLogin)) { + AuthService::logUser($localHttpLogin, "", true); + } + } - } - function getLogoutRedirect(){ - return AJXP_VarsFilter::filter($this->getOption("LOGOUT_URL")); + + } + public function getLogoutRedirect() + { + return AJXP_VarsFilter::filter($this->getOption("LOGOUT_URL")); } } -?> \ No newline at end of file diff --git a/core/src/plugins/auth.basic_http/i18n/conf/en.php b/core/src/plugins/auth.basic_http/i18n/conf/en.php index 3510b17898..2f57ee7d40 100644 --- a/core/src/plugins/auth.basic_http/i18n/conf/en.php +++ b/core/src/plugins/auth.basic_http/i18n/conf/en.php @@ -24,4 +24,3 @@ "Users" => "Users", "The users list" => "The users list", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.basic_http/i18n/conf/fr.php b/core/src/plugins/auth.basic_http/i18n/conf/fr.php index 642d3020c4..b320fc049e 100644 --- a/core/src/plugins/auth.basic_http/i18n/conf/fr.php +++ b/core/src/plugins/auth.basic_http/i18n/conf/fr.php @@ -24,4 +24,3 @@ "Users" => "Utilisateurs", "The users list" => "Liste des utilisateurs", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.basic_http/i18n/conf/pt.php b/core/src/plugins/auth.basic_http/i18n/conf/pt.php index ce1cc8c21d..c30f0827ef 100644 --- a/core/src/plugins/auth.basic_http/i18n/conf/pt.php +++ b/core/src/plugins/auth.basic_http/i18n/conf/pt.php @@ -24,4 +24,3 @@ "Users" => "Utilizadores", "The users list" => "Lista de Utilizadores", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.basic_http/manifest.xml b/core/src/plugins/auth.basic_http/manifest.xml index 86f097a30b..f64679b657 100644 --- a/core/src/plugins/auth.basic_http/manifest.xml +++ b/core/src/plugins/auth.basic_http/manifest.xml @@ -42,5 +42,5 @@ - - \ No newline at end of file + + diff --git a/core/src/plugins/auth.cas/CAS.php b/core/src/plugins/auth.cas/CAS.php index 8127672682..d5a01af90e 100644 --- a/core/src/plugins/auth.cas/CAS.php +++ b/core/src/plugins/auth.cas/CAS.php @@ -34,14 +34,14 @@ // hack by Vangelis Haniotakis to handle the absence of $_SERVER['REQUEST_URI'] in IIS // if (php_sapi_name() != 'cli') { - if (!isset($_SERVER['REQUEST_URI'])) { - $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING']; - } + if (!isset($_SERVER['REQUEST_URI'])) { + $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING']; + } } // Add a E_USER_DEPRECATED for php versions <= 5.2 -if (!defined('E_USER_DEPRECATED')){ - define('E_USER_DEPRECATED', E_USER_NOTICE); +if (!defined('E_USER_DEPRECATED')) { + define('E_USER_DEPRECATED', E_USER_NOTICE); } /** @@ -264,10 +264,10 @@ * @hideinitializer */ $GLOBALS['PHPCAS_INIT_CALL'] = array ( - 'done' => FALSE, - 'file' => '?', - 'line' => -1, - 'method' => '?' + 'done' => FALSE, + 'file' => '?', + 'line' => -1, + 'method' => '?' ); /** @@ -277,11 +277,11 @@ * @hideinitializer */ $GLOBALS['PHPCAS_AUTH_CHECK_CALL'] = array ( - 'done' => FALSE, - 'file' => '?', - 'line' => -1, - 'method' => '?', - 'result' => FALSE + 'done' => FALSE, + 'file' => '?', + 'line' => -1, + 'method' => '?', + 'result' => FALSE ); /** @@ -290,9 +290,9 @@ * @hideinitializer */ $GLOBALS['PHPCAS_DEBUG'] = array ( - 'filename' => FALSE, - 'indent' => 0, - 'unique_id' => '' + 'filename' => FALSE, + 'indent' => 0, + 'unique_id' => '' ); /** @} */ @@ -320,1359 +320,1413 @@ * at the end of CAS/Client.php). */ -class phpCAS { - - // ######################################################################## - // INITIALIZATION - // ######################################################################## - - /** - * @addtogroup publicInit - * @{ - */ - - /** - * phpCAS client initializer. - * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be - * called, only once, and before all other methods (except phpCAS::getVersion() - * and phpCAS::setDebug()). - * - * @param $server_version the version of the CAS server - * @param $server_hostname the hostname of the CAS server - * @param $server_port the port the CAS server is running on - * @param $server_uri the URI the CAS server is responding on - * @param $start_session Have phpCAS start PHP sessions (default true) - * - * @return a newly created CAS_Client object - */ - public static function client($server_version, $server_hostname, $server_port, $server_uri, $start_session = true) { - global $PHPCAS_CLIENT, $PHPCAS_INIT_CALL; - - phpCAS :: traceBegin(); - if (is_object($PHPCAS_CLIENT)) { - phpCAS :: error($PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . $PHPCAS_INIT_CALL['file'] . ':' . $PHPCAS_INIT_CALL['line'] . ')'); - } - if (gettype($server_version) != 'string') { - phpCAS :: error('type mismatched for parameter $server_version (should be `string\')'); - } - if (gettype($server_hostname) != 'string') { - phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')'); - } - if (gettype($server_port) != 'integer') { - phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')'); - } - if (gettype($server_uri) != 'string') { - phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')'); - } - - // store where the initializer is called from - $dbg = debug_backtrace(); - $PHPCAS_INIT_CALL = array ( - 'done' => TRUE, - 'file' => $dbg[0]['file'], - 'line' => $dbg[0]['line'], - 'method' => __CLASS__ . '::' . __FUNCTION__ - ); - - // initialize the global object $PHPCAS_CLIENT - $PHPCAS_CLIENT = new CAS_Client($server_version, FALSE /*proxy*/ - , $server_hostname, $server_port, $server_uri, $start_session); - phpCAS :: traceEnd(); - } - - /** - * phpCAS proxy initializer. - * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be - * called, only once, and before all other methods (except phpCAS::getVersion() - * and phpCAS::setDebug()). - * - * @param $server_version the version of the CAS server - * @param $server_hostname the hostname of the CAS server - * @param $server_port the port the CAS server is running on - * @param $server_uri the URI the CAS server is responding on - * @param $start_session Have phpCAS start PHP sessions (default true) - * - * @return a newly created CAS_Client object - */ - public static function proxy($server_version, $server_hostname, $server_port, $server_uri, $start_session = true) { - global $PHPCAS_CLIENT, $PHPCAS_INIT_CALL; - - phpCAS :: traceBegin(); - if (is_object($PHPCAS_CLIENT)) { - phpCAS :: error($PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . $PHPCAS_INIT_CALL['file'] . ':' . $PHPCAS_INIT_CALL['line'] . ')'); - } - if (gettype($server_version) != 'string') { - phpCAS :: error('type mismatched for parameter $server_version (should be `string\')'); - } - if (gettype($server_hostname) != 'string') { - phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')'); - } - if (gettype($server_port) != 'integer') { - phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')'); - } - if (gettype($server_uri) != 'string') { - phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')'); - } - - // store where the initialzer is called from - $dbg = debug_backtrace(); - $PHPCAS_INIT_CALL = array ( - 'done' => TRUE, - 'file' => $dbg[0]['file'], - 'line' => $dbg[0]['line'], - 'method' => __CLASS__ . '::' . __FUNCTION__ - ); - - // initialize the global object $PHPCAS_CLIENT - $PHPCAS_CLIENT = new CAS_Client($server_version, TRUE /*proxy*/ - , $server_hostname, $server_port, $server_uri, $start_session); - phpCAS :: traceEnd(); - } - - /** @} */ - // ######################################################################## - // DEBUGGING - // ######################################################################## - - /** - * @addtogroup publicDebug - * @{ - */ - - /** - * Set/unset debug mode - * - * @param $filename the name of the file used for logging, or FALSE to stop debugging. - */ - public static function setDebug($filename = '') { - global $PHPCAS_DEBUG; - - if ($filename != FALSE && gettype($filename) != 'string') { - phpCAS :: error('type mismatched for parameter $dbg (should be FALSE or the name of the log file)'); - } - if ($filename === FALSE){ - $PHPCAS_DEBUG['filename'] = FALSE; - }else{ - if (empty ($filename)) { - if (preg_match('/^Win.*/', getenv('OS'))) { - if (isset ($_ENV['TMP'])) { - $debugDir = $_ENV['TMP'] . '/'; - } else - if (isset ($_ENV['TEMP'])) { - $debugDir = $_ENV['TEMP'] . '/'; - } else { - $debugDir = ''; - } - } else { - $debugDir = DEFAULT_DEBUG_DIR; - } - $filename = $debugDir . 'phpCAS.log'; - } - - if (empty ($PHPCAS_DEBUG['unique_id'])) { - $PHPCAS_DEBUG['unique_id'] = substr(strtoupper(md5(uniqid(''))), 0, 4); - } - - $PHPCAS_DEBUG['filename'] = $filename; - - phpCAS :: trace('START phpCAS-' . PHPCAS_VERSION . ' ******************'); - } - } - - - /** - * Logs a string in debug mode. - * - * @param $str the string to write - * - * @private - */ - public static function log($str) { - $indent_str = "."; - global $PHPCAS_DEBUG; - - if (!empty($PHPCAS_DEBUG['filename'])) { - for ($i = 0; $i < $PHPCAS_DEBUG['indent']; $i++) { - $indent_str .= '| '; - } - // allow for multiline output with proper identing. Usefull for dumping cas answers etc. - $str2 = str_replace("\n", "\n" . $PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str, $str); - error_log($PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str . $str2 . "\n", 3, $PHPCAS_DEBUG['filename']); - } - - } - - /** - * This method is used by interface methods to print an error and where the function - * was originally called from. - * - * @param $msg the message to print - * - * @private - */ - public static function error($msg) { - $dbg = debug_backtrace(); - $function = '?'; - $file = '?'; - $line = '?'; - if (is_array($dbg)) { - for ($i = 1; $i < sizeof($dbg); $i++) { - if (is_array($dbg[$i]) && isset($dbg[$i]['class']) ) { - if ($dbg[$i]['class'] == __CLASS__) { - $function = $dbg[$i]['function']; - $file = $dbg[$i]['file']; - $line = $dbg[$i]['line']; - } - } - } - } - echo "
    \nphpCAS error: " . __CLASS__ . "::" . $function . '(): ' . htmlentities($msg) . " in " . $file . " on line " . $line . "
    \n"; - phpCAS :: trace($msg); - phpCAS :: traceExit(); - exit (); - } - - /** - * This method is used to log something in debug mode. - */ - public static function trace($str) { - $dbg = debug_backtrace(); - phpCAS :: log($str . ' [' . basename($dbg[0]['file']) . ':' . $dbg[0]['line'] . ']'); - } - - /** - * This method is used to indicate the start of the execution of a function in debug mode. - */ - public static function traceBegin() { - global $PHPCAS_DEBUG; - - $dbg = debug_backtrace(); - $str = '=> '; - if (!empty ($dbg[1]['class'])) { - $str .= $dbg[1]['class'] . '::'; - } - $str .= $dbg[1]['function'] . '('; - if (is_array($dbg[1]['args'])) { - foreach ($dbg[1]['args'] as $index => $arg) { - if ($index != 0) { - $str .= ', '; - } - if(is_object($arg)){ - $str .= get_class($arg); - }else{ - $str .= str_replace(array("\r\n", "\n", "\r"), "", var_export($arg, TRUE)); - } - } - } - if (isset($dbg[1]['file'])) - $file = basename($dbg[1]['file']); - else - $file = 'unknown_file'; - if (isset($dbg[1]['line'])) - $line = $dbg[1]['line']; - else - $line = 'unknown_line'; - $str .= ') [' . $file . ':' . $line . ']'; - phpCAS :: log($str); - $PHPCAS_DEBUG['indent']++; - } - - /** - * This method is used to indicate the end of the execution of a function in debug mode. - * - * @param $res the result of the function - */ - public static function traceEnd($res = '') { - global $PHPCAS_DEBUG; - - $PHPCAS_DEBUG['indent']--; - $dbg = debug_backtrace(); - $str = ''; - if(is_object($res)){ - $str .= '<= ' . get_class($arg); - }else{ - $str .= '<= ' . str_replace(array("\r\n", "\n", "\r"), "", var_export($res, TRUE)); - } - - phpCAS :: log($str); - } - - /** - * This method is used to indicate the end of the execution of the program - */ - public static function traceExit() { - global $PHPCAS_DEBUG; - - phpCAS :: log('exit()'); - while ($PHPCAS_DEBUG['indent'] > 0) { - phpCAS :: log('-'); - $PHPCAS_DEBUG['indent']--; - } - } - - /** @} */ - // ######################################################################## - // INTERNATIONALIZATION - // ######################################################################## - /** - * @addtogroup publicLang - * @{ - */ - - /** - * This method is used to set the language used by phpCAS. - * @note Can be called only once. - * - * @param $lang a string representing the language. - * - * @sa PHPCAS_LANG_FRENCH, PHPCAS_LANG_ENGLISH - */ - public static function setLang($lang) { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - if (gettype($lang) != 'string') { - phpCAS :: error('type mismatched for parameter $lang (should be `string\')'); - } - $PHPCAS_CLIENT->setLang($lang); - } - - /** @} */ - // ######################################################################## - // VERSION - // ######################################################################## - /** - * @addtogroup public - * @{ - */ - - /** - * This method returns the phpCAS version. - * - * @return the phpCAS version. - */ - public static function getVersion() { - return PHPCAS_VERSION; - } - - /** @} */ - // ######################################################################## - // HTML OUTPUT - // ######################################################################## - /** - * @addtogroup publicOutput - * @{ - */ - - /** - * This method sets the HTML header used for all outputs. - * - * @param $header the HTML header. - */ - public static function setHTMLHeader($header) { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - if (gettype($header) != 'string') { - phpCAS :: error('type mismatched for parameter $header (should be `string\')'); - } - $PHPCAS_CLIENT->setHTMLHeader($header); - } - - /** - * This method sets the HTML footer used for all outputs. - * - * @param $footer the HTML footer. - */ - public static function setHTMLFooter($footer) { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - if (gettype($footer) != 'string') { - phpCAS :: error('type mismatched for parameter $footer (should be `string\')'); - } - $PHPCAS_CLIENT->setHTMLFooter($footer); - } - - /** @} */ - // ######################################################################## - // PGT STORAGE - // ######################################################################## - /** - * @addtogroup publicPGTStorage - * @{ - */ - - /** - * This method can be used to set a custom PGT storage object. - * - * @param $storage a PGT storage object that inherits from the CAS_PGTStorage class - */ - public static function setPGTStorage($storage) { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_CLIENT->isProxy()) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if ($PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called before ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() (called at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ')'); - } - if ( !($storage instanceof CAS_PGTStorage) ) { - phpCAS :: error('type mismatched for parameter $storage (should be a CAS_PGTStorage `object\')'); - } - $PHPCAS_CLIENT->setPGTStorage($storage); - phpCAS :: traceEnd(); - } - - /** - * This method is used to tell phpCAS to store the response of the - * CAS server to PGT requests in a database. - * - * @param $dsn_or_pdo a dsn string to use for creating a PDO object or a PDO object - * @param $username the username to use when connecting to the database - * @param $password the password to use when connecting to the database - * @param $table the table to use for storing and retrieving PGT's - * @param $driver_options any driver options to use when connecting to the database - */ - public static function setPGTStorageDb($dsn_or_pdo, $username='', $password='', $table='', $driver_options=null) { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_CLIENT->isProxy()) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if ($PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called before ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() (called at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ')'); - } - if (gettype($username) != 'string') { - phpCAS :: error('type mismatched for parameter $username (should be `string\')'); - } - if (gettype($password) != 'string') { - phpCAS :: error('type mismatched for parameter $password (should be `string\')'); - } - if (gettype($table) != 'string') { - phpCAS :: error('type mismatched for parameter $table (should be `string\')'); - } - $PHPCAS_CLIENT->setPGTStorageDb($dsn_or_pdo, $username, $password, $table, $driver_options); - phpCAS :: traceEnd(); - } - - /** - * This method is used to tell phpCAS to store the response of the - * CAS server to PGT requests onto the filesystem. - * @param $format the format used to store the PGT's. This parameter has no effect and is only for backwards compatibility - * @param $path the path where the PGT's should be stored - */ - public static function setPGTStorageFile($format = '', $path = '') { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_CLIENT->isProxy()) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if ($PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called before ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() (called at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ')'); - } - if (gettype($format) != 'string') { - phpCAS :: error('type mismatched for parameter $format (should be `string\')'); - } - if (gettype($path) != 'string') { - phpCAS :: error('type mismatched for parameter $format (should be `string\')'); - } - $PHPCAS_CLIENT->setPGTStorageFile($path); - phpCAS :: traceEnd(); - } - - /** @} */ - // ######################################################################## - // ACCESS TO EXTERNAL SERVICES - // ######################################################################## - /** - * @addtogroup publicServices - * @{ - */ - - /** - * Answer a proxy-authenticated service handler. - * - * @param string $type The service type. One of: - * PHPCAS_PROXIED_SERVICE_HTTP_GET - * PHPCAS_PROXIED_SERVICE_HTTP_POST - * PHPCAS_PROXIED_SERVICE_IMAP - * - * - * @return CAS_ProxiedService - * @throws InvalidArgumentException If the service type is unknown. - */ - public static function getProxiedService ($type) { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_CLIENT->isProxy()) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['result']) { - phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); - } - if (gettype($type) != 'string') { - phpCAS :: error('type mismatched for parameter $type (should be `string\')'); - } - - $res = $PHPCAS_CLIENT->getProxiedService($type); - - phpCAS :: traceEnd(); - return $res; - } - - /** - * Initialize a proxied-service handler with the proxy-ticket it should use. - * - * @param CAS_ProxiedService $proxiedService - * @return void - * @throws CAS_ProxyTicketException If there is a proxy-ticket failure. - * The code of the Exception will be one of: - * PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE - * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE - * PHPCAS_SERVICE_PT_FAILURE - */ - public static function initializeProxiedService (CAS_ProxiedService $proxiedService) { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_CLIENT->isProxy()) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['result']) { - phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); - } - - $PHPCAS_CLIENT->initializeProxiedService($proxiedService); - } - - /** - * This method is used to access an HTTP[S] service. - * - * @param $url the service to access. - * @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on - * success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, - * PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_NOT_AVAILABLE. - * @param $output the output of the service (also used to give an error - * message on failure). - * - * @return TRUE on success, FALSE otherwise (in this later case, $err_code - * gives the reason why it failed and $output contains an error message). - */ - public static function serviceWeb($url, & $err_code, & $output) { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_CLIENT->isProxy()) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['result']) { - phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); - } - if (gettype($url) != 'string') { - phpCAS :: error('type mismatched for parameter $url (should be `string\')'); - } - - $res = $PHPCAS_CLIENT->serviceWeb($url, $err_code, $output); - - phpCAS :: traceEnd($res); - return $res; - } - - /** - * This method is used to access an IMAP/POP3/NNTP service. - * - * @param $url a string giving the URL of the service, including the mailing box - * for IMAP URLs, as accepted by imap_open(). - * @param $service a string giving for CAS retrieve Proxy ticket - * @param $flags options given to imap_open(). - * @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on - * success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, - * PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_NOT_AVAILABLE. - * @param $err_msg an error message on failure - * @param $pt the Proxy Ticket (PT) retrieved from the CAS server to access the URL - * on success, FALSE on error). - * - * @return an IMAP stream on success, FALSE otherwise (in this later case, $err_code - * gives the reason why it failed and $err_msg contains an error message). - */ - public static function serviceMail($url, $service, $flags, & $err_code, & $err_msg, & $pt) { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_CLIENT->isProxy()) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['result']) { - phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); - } - if (gettype($url) != 'string') { - phpCAS :: error('type mismatched for parameter $url (should be `string\')'); - } - - if (gettype($flags) != 'integer') { - phpCAS :: error('type mismatched for parameter $flags (should be `integer\')'); - } - - $res = $PHPCAS_CLIENT->serviceMail($url, $service, $flags, $err_code, $err_msg, $pt); - - phpCAS :: traceEnd($res); - return $res; - } - - /** @} */ - // ######################################################################## - // AUTHENTICATION - // ######################################################################## - /** - * @addtogroup publicAuth - * @{ - */ - - /** - * Set the times authentication will be cached before really accessing the CAS server in gateway mode: - * - -1: check only once, and then never again (until you pree login) - * - 0: always check - * - n: check every "n" time - * - * @param $n an integer. - */ - public static function setCacheTimesForAuthRecheck($n) { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - if (gettype($n) != 'integer') { - phpCAS :: error('type mismatched for parameter $header (should be `string\')'); - } - $PHPCAS_CLIENT->setCacheTimesForAuthRecheck($n); - } - - /** - * Set a callback function to be run when a user authenticates. - * - * The callback function will be passed a $logoutTicket as its first parameter, - * followed by any $additionalArgs you pass. The $logoutTicket parameter is an - * opaque string that can be used to map the session-id to logout request in order - * to support single-signout in applications that manage their own sessions - * (rather than letting phpCAS start the session). - * - * phpCAS::forceAuthentication() will always exit and forward client unless - * they are already authenticated. To perform an action at the moment the user - * logs in (such as registering an account, performing logging, etc), register - * a callback function here. - * - * @param callback $function - * @param optional array $additionalArgs - * @return void - */ - public static function setPostAuthenticateCallback ($function, array $additionalArgs = array()) { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - - $PHPCAS_CLIENT->setPostAuthenticateCallback($function, $additionalArgs); - } - - /** - * Set a callback function to be run when a single-signout request is received. - * - * The callback function will be passed a $logoutTicket as its first parameter, - * followed by any $additionalArgs you pass. The $logoutTicket parameter is an - * opaque string that can be used to map a session-id to the logout request in order - * to support single-signout in applications that manage their own sessions - * (rather than letting phpCAS start and destroy the session). - * - * @param callback $function - * @param optional array $additionalArgs - * @return void - */ - public static function setSingleSignoutCallback ($function, array $additionalArgs = array()) { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - - $PHPCAS_CLIENT->setSingleSignoutCallback($function, $additionalArgs); - } - - /** - * This method is called to check if the user is already authenticated locally or has a global cas session. A already - * existing cas session is determined by a cas gateway call.(cas login call without any interactive prompt) - * @return TRUE when the user is authenticated, FALSE when a previous gateway login failed or - * the function will not return if the user is redirected to the cas server for a gateway login attempt - */ - public static function checkAuthentication() { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - - $auth = $PHPCAS_CLIENT->checkAuthentication(); - - // store where the authentication has been checked and the result - $dbg = debug_backtrace(); - $PHPCAS_AUTH_CHECK_CALL = array ( - 'done' => TRUE, - 'file' => $dbg[0]['file'], - 'line' => $dbg[0]['line'], - 'method' => __CLASS__ . '::' . __FUNCTION__, - 'result' => $auth - ); - phpCAS :: traceEnd($auth); - return $auth; - } - - /** - * This method is called to force authentication if the user was not already - * authenticated. If the user is not authenticated, halt by redirecting to - * the CAS server. - */ - public static function forceAuthentication() { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - - $auth = $PHPCAS_CLIENT->forceAuthentication(); - - // store where the authentication has been checked and the result - $dbg = debug_backtrace(); - $PHPCAS_AUTH_CHECK_CALL = array ( - 'done' => TRUE, - 'file' => $dbg[0]['file'], - 'line' => $dbg[0]['line'], - 'method' => __CLASS__ . '::' . __FUNCTION__, - 'result' => $auth - ); - - if (!$auth) { - phpCAS :: trace('user is not authenticated, redirecting to the CAS server'); - $PHPCAS_CLIENT->forceAuthentication(); - } else { - phpCAS :: trace('no need to authenticate (user `' . phpCAS :: getUser() . '\' is already authenticated)'); - } - - phpCAS :: traceEnd(); - return $auth; - } - - /** - * This method is called to renew the authentication. - **/ - public static function renewAuthentication() { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - $auth = $PHPCAS_CLIENT->renewAuthentication(); - // store where the authentication has been checked and the result - $dbg = debug_backtrace(); - $PHPCAS_AUTH_CHECK_CALL = array ( - 'done' => TRUE, - 'file' => $dbg[0]['file'], - 'line' => $dbg[0]['line'], - 'method' => __CLASS__ . '::' . __FUNCTION__, - 'result' => $auth - ); - - //$PHPCAS_CLIENT->renewAuthentication(); - phpCAS :: traceEnd(); - } - - /** - * This method is called to check if the user is authenticated (previously or by - * tickets given in the URL). - * - * @return TRUE when the user is authenticated. - */ - public static function isAuthenticated() { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - - // call the isAuthenticated method of the global $PHPCAS_CLIENT object - $auth = $PHPCAS_CLIENT->isAuthenticated(); - - // store where the authentication has been checked and the result - $dbg = debug_backtrace(); - $PHPCAS_AUTH_CHECK_CALL = array ( - 'done' => TRUE, - 'file' => $dbg[0]['file'], - 'line' => $dbg[0]['line'], - 'method' => __CLASS__ . '::' . __FUNCTION__, - 'result' => $auth - ); - phpCAS :: traceEnd($auth); - return $auth; - } - - /** - * Checks whether authenticated based on $_SESSION. Useful to avoid - * server calls. - * @return true if authenticated, false otherwise. - * @since 0.4.22 by Brendan Arnold - */ - public static function isSessionAuthenticated() { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - return ($PHPCAS_CLIENT->isSessionAuthenticated()); - } - - /** - * This method returns the CAS user's login name. - * @warning should not be called only after phpCAS::forceAuthentication() - * or phpCAS::checkAuthentication(). - * - * @return the login name of the authenticated user - */ - public static function getUser() { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['result']) { - phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); - } - return $PHPCAS_CLIENT->getUser(); - } - - /** - * Answer attributes about the authenticated user. - * - * @warning should not be called only after phpCAS::forceAuthentication() - * or phpCAS::checkAuthentication(). - * - * @return array - */ - public static function getAttributes() { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['result']) { - phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); - } - return $PHPCAS_CLIENT->getAttributes(); - } - - /** - * Answer true if there are attributes for the authenticated user. - * - * @warning should not be called only after phpCAS::forceAuthentication() - * or phpCAS::checkAuthentication(). - * - * @return boolean - */ - public static function hasAttributes() { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['result']) { - phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); - } - return $PHPCAS_CLIENT->hasAttributes(); - } - - /** - * Answer true if an attribute exists for the authenticated user. - * - * @warning should not be called only after phpCAS::forceAuthentication() - * or phpCAS::checkAuthentication(). - * - * @param string $key - * @return boolean - */ - public static function hasAttribute($key) { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['result']) { - phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); - } - return $PHPCAS_CLIENT->hasAttribute($key); - } - - /** - * Answer an attribute for the authenticated user. - * - * @warning should not be called only after phpCAS::forceAuthentication() - * or phpCAS::checkAuthentication(). - * - * @param string $key - * @return mixed string for a single value or an array if multiple values exist. - */ - public static function getAttribute($key) { - global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['done']) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()'); - } - if (!$PHPCAS_AUTH_CHECK_CALL['result']) { - phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); - } - return $PHPCAS_CLIENT->getAttribute($key); - } - - /** - * Handle logout requests. - */ - public static function handleLogoutRequests($check_client = true, $allowed_clients = false) { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - return ($PHPCAS_CLIENT->handleLogoutRequests($check_client, $allowed_clients)); - } - - /** - * This method returns the URL to be used to login. - * or phpCAS::isAuthenticated(). - * - * @return the login name of the authenticated user - */ - public static function getServerLoginURL() { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - return $PHPCAS_CLIENT->getServerLoginURL(); - } - - /** - * Set the login URL of the CAS server. - * @param $url the login URL - * @since 0.4.21 by Wyman Chan - */ - public static function setServerLoginURL($url = '') { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after - ' . __CLASS__ . '::client()'); - } - if (gettype($url) != 'string') { - phpCAS :: error('type mismatched for parameter $url (should be - `string\')'); - } - $PHPCAS_CLIENT->setServerLoginURL($url); - phpCAS :: traceEnd(); - } - - /** - * Set the serviceValidate URL of the CAS server. - * Used only in CAS 1.0 validations - * @param $url the serviceValidate URL - * @since 1.1.0 by Joachim Fritschi - */ - public static function setServerServiceValidateURL($url = '') { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after - ' . __CLASS__ . '::client()'); - } - if (gettype($url) != 'string') { - phpCAS :: error('type mismatched for parameter $url (should be - `string\')'); - } - $PHPCAS_CLIENT->setServerServiceValidateURL($url); - phpCAS :: traceEnd(); - } - - /** - * Set the proxyValidate URL of the CAS server. - * Used for all CAS 2.0 validations - * @param $url the proxyValidate URL - * @since 1.1.0 by Joachim Fritschi - */ - public static function setServerProxyValidateURL($url = '') { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after - ' . __CLASS__ . '::client()'); - } - if (gettype($url) != 'string') { - phpCAS :: error('type mismatched for parameter $url (should be - `string\')'); - } - $PHPCAS_CLIENT->setServerProxyValidateURL($url); - phpCAS :: traceEnd(); - } - - /** - * Set the samlValidate URL of the CAS server. - * @param $url the samlValidate URL - * @since 1.1.0 by Joachim Fritschi - */ - public static function setServerSamlValidateURL($url = '') { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after - ' . __CLASS__ . '::client()'); - } - if (gettype($url) != 'string') { - phpCAS :: error('type mismatched for parameter $url (should be - `string\')'); - } - $PHPCAS_CLIENT->setServerSamlValidateURL($url); - phpCAS :: traceEnd(); - } - - /** - * This method returns the URL to be used to login. - * or phpCAS::isAuthenticated(). - * - * @return the login name of the authenticated user - */ - public static function getServerLogoutURL() { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); - } - return $PHPCAS_CLIENT->getServerLogoutURL(); - } - - /** - * Set the logout URL of the CAS server. - * @param $url the logout URL - * @since 0.4.21 by Wyman Chan - */ - public static function setServerLogoutURL($url = '') { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after - ' . __CLASS__ . '::client()'); - } - if (gettype($url) != 'string') { - phpCAS :: error('type mismatched for parameter $url (should be - `string\')'); - } - $PHPCAS_CLIENT->setServerLogoutURL($url); - phpCAS :: traceEnd(); - } - - /** - * This method is used to logout from CAS. - * @params $params an array that contains the optional url and service parameters that will be passed to the CAS server - * @public - */ - public static function logout($params = "") { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); - } - $parsedParams = array (); - if ($params != "") { - if (is_string($params)) { - phpCAS :: error('method `phpCAS::logout($url)\' is now deprecated, use `phpCAS::logoutWithUrl($url)\' instead'); - } - if (!is_array($params)) { - phpCAS :: error('type mismatched for parameter $params (should be `array\')'); - } - foreach ($params as $key => $value) { - if ($key != "service" && $key != "url") { - phpCAS :: error('only `url\' and `service\' parameters are allowed for method `phpCAS::logout($params)\''); - } - $parsedParams[$key] = $value; - } - } - $PHPCAS_CLIENT->logout($parsedParams); - // never reached - phpCAS :: traceEnd(); - } - - /** - * This method is used to logout from CAS. Halts by redirecting to the CAS server. - * @param $service a URL that will be transmitted to the CAS server - */ - public static function logoutWithRedirectService($service) { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); - } - if (!is_string($service)) { - phpCAS :: error('type mismatched for parameter $service (should be `string\')'); - } - $PHPCAS_CLIENT->logout(array ( - "service" => $service - )); - // never reached - phpCAS :: traceEnd(); - } - - /** - * This method is used to logout from CAS. Halts by redirecting to the CAS server. - * @param $url a URL that will be transmitted to the CAS server - * @deprecated The url parameter has been removed from the CAS server as of version 3.3.5.1 - */ - public static function logoutWithUrl($url) { - trigger_error('Function deprecated for cas servers >= 3.3.5.1', E_USER_DEPRECATED); - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); - } - if (!is_string($url)) { - phpCAS :: error('type mismatched for parameter $url (should be `string\')'); - } - $PHPCAS_CLIENT->logout(array ( - "url" => $url - )); - // never reached - phpCAS :: traceEnd(); - } - - /** - * This method is used to logout from CAS. Halts by redirecting to the CAS server. - * @param $service a URL that will be transmitted to the CAS server - * @param $url a URL that will be transmitted to the CAS server - * @deprecated The url parameter has been removed from the CAS server as of version 3.3.5.1 - */ - public static function logoutWithRedirectServiceAndUrl($service, $url) { - trigger_error('Function deprecated for cas servers >= 3.3.5.1', E_USER_DEPRECATED); - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); - } - if (!is_string($service)) { - phpCAS :: error('type mismatched for parameter $service (should be `string\')'); - } - if (!is_string($url)) { - phpCAS :: error('type mismatched for parameter $url (should be `string\')'); - } - $PHPCAS_CLIENT->logout(array ( - "service" => $service, - "url" => $url - )); - // never reached - phpCAS :: traceEnd(); - } - - /** - * Set the fixed URL that will be used by the CAS server to transmit the PGT. - * When this method is not called, a phpCAS script uses its own URL for the callback. - * - * @param $url the URL - */ - public static function setFixedCallbackURL($url = '') { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (!$PHPCAS_CLIENT->isProxy()) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (gettype($url) != 'string') { - phpCAS :: error('type mismatched for parameter $url (should be `string\')'); - } - $PHPCAS_CLIENT->setCallbackURL($url); - phpCAS :: traceEnd(); - } - - /** - * Set the fixed URL that will be set as the CAS service parameter. When this - * method is not called, a phpCAS script uses its own URL. - * - * @param $url the URL - */ - public static function setFixedServiceURL($url) { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (gettype($url) != 'string') { - phpCAS :: error('type mismatched for parameter $url (should be `string\')'); - } - $PHPCAS_CLIENT->setURL($url); - phpCAS :: traceEnd(); - } - - /** - * Get the URL that is set as the CAS service parameter. - */ - public static function getServiceURL() { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - return ($PHPCAS_CLIENT->getURL()); - } - - /** - * Retrieve a Proxy Ticket from the CAS server. - */ - public static function retrievePT($target_service, & $err_code, & $err_msg) { - global $PHPCAS_CLIENT; - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); - } - if (gettype($target_service) != 'string') { - phpCAS :: error('type mismatched for parameter $target_service(should be `string\')'); - } - return ($PHPCAS_CLIENT->retrievePT($target_service, $err_code, $err_msg)); - } - - /** - * Set the certificate of the CAS server CA. - * - * @param $cert the CA certificate - */ - public static function setCasServerCACert($cert) { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); - } - if (gettype($cert) != 'string') { - phpCAS :: error('type mismatched for parameter $cert (should be `string\')'); - } - $PHPCAS_CLIENT->setCasServerCACert($cert); - phpCAS :: traceEnd(); - } - - /** - * Set no SSL validation for the CAS server. - */ - public static function setNoCasServerValidation() { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); - } - $PHPCAS_CLIENT->setNoCasServerValidation(); - phpCAS :: traceEnd(); - } - - - /** - * Disable the removal of a CAS-Ticket from the URL when authenticating - * DISABLING POSES A SECURITY RISK: - * We normally remove the ticket by an additional redirect as a security precaution +class phpCAS +{ + // ######################################################################## + // INITIALIZATION + // ######################################################################## + + /** + * @addtogroup publicInit + * @{ + */ + + /** + * phpCAS client initializer. + * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be + * called, only once, and before all other methods (except phpCAS::getVersion() + * and phpCAS::setDebug()). + * + * @param $server_version the version of the CAS server + * @param $server_hostname the hostname of the CAS server + * @param $server_port the port the CAS server is running on + * @param $server_uri the URI the CAS server is responding on + * @param $start_session Have phpCAS start PHP sessions (default true) + * + * @return a newly created CAS_Client object + */ + public static function client($server_version, $server_hostname, $server_port, $server_uri, $start_session = true) + { + global $PHPCAS_CLIENT, $PHPCAS_INIT_CALL; + + phpCAS :: traceBegin(); + if (is_object($PHPCAS_CLIENT)) { + phpCAS :: error($PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . $PHPCAS_INIT_CALL['file'] . ':' . $PHPCAS_INIT_CALL['line'] . ')'); + } + if (gettype($server_version) != 'string') { + phpCAS :: error('type mismatched for parameter $server_version (should be `string\')'); + } + if (gettype($server_hostname) != 'string') { + phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')'); + } + if (gettype($server_port) != 'integer') { + phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')'); + } + if (gettype($server_uri) != 'string') { + phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')'); + } + + // store where the initializer is called from + $dbg = debug_backtrace(); + $PHPCAS_INIT_CALL = array ( + 'done' => TRUE, + 'file' => $dbg[0]['file'], + 'line' => $dbg[0]['line'], + 'method' => __CLASS__ . '::' . __FUNCTION__ + ); + + // initialize the global object $PHPCAS_CLIENT + $PHPCAS_CLIENT = new CAS_Client($server_version, FALSE /*proxy*/ + , $server_hostname, $server_port, $server_uri, $start_session); + phpCAS :: traceEnd(); + } + + /** + * phpCAS proxy initializer. + * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be + * called, only once, and before all other methods (except phpCAS::getVersion() + * and phpCAS::setDebug()). + * + * @param $server_version the version of the CAS server + * @param $server_hostname the hostname of the CAS server + * @param $server_port the port the CAS server is running on + * @param $server_uri the URI the CAS server is responding on + * @param $start_session Have phpCAS start PHP sessions (default true) + * + * @return a newly created CAS_Client object + */ + public static function proxy($server_version, $server_hostname, $server_port, $server_uri, $start_session = true) + { + global $PHPCAS_CLIENT, $PHPCAS_INIT_CALL; + + phpCAS :: traceBegin(); + if (is_object($PHPCAS_CLIENT)) { + phpCAS :: error($PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . $PHPCAS_INIT_CALL['file'] . ':' . $PHPCAS_INIT_CALL['line'] . ')'); + } + if (gettype($server_version) != 'string') { + phpCAS :: error('type mismatched for parameter $server_version (should be `string\')'); + } + if (gettype($server_hostname) != 'string') { + phpCAS :: error('type mismatched for parameter $server_hostname (should be `string\')'); + } + if (gettype($server_port) != 'integer') { + phpCAS :: error('type mismatched for parameter $server_port (should be `integer\')'); + } + if (gettype($server_uri) != 'string') { + phpCAS :: error('type mismatched for parameter $server_uri (should be `string\')'); + } + + // store where the initialzer is called from + $dbg = debug_backtrace(); + $PHPCAS_INIT_CALL = array ( + 'done' => TRUE, + 'file' => $dbg[0]['file'], + 'line' => $dbg[0]['line'], + 'method' => __CLASS__ . '::' . __FUNCTION__ + ); + + // initialize the global object $PHPCAS_CLIENT + $PHPCAS_CLIENT = new CAS_Client($server_version, TRUE /*proxy*/ + , $server_hostname, $server_port, $server_uri, $start_session); + phpCAS :: traceEnd(); + } + + /** @} */ + // ######################################################################## + // DEBUGGING + // ######################################################################## + + /** + * @addtogroup publicDebug + * @{ + */ + + /** + * Set/unset debug mode + * + * @param $filename the name of the file used for logging, or FALSE to stop debugging. + */ + public static function setDebug($filename = '') + { + global $PHPCAS_DEBUG; + + if ($filename != FALSE && gettype($filename) != 'string') { + phpCAS :: error('type mismatched for parameter $dbg (should be FALSE or the name of the log file)'); + } + if ($filename === FALSE) { + $PHPCAS_DEBUG['filename'] = FALSE; + } else { + if (empty ($filename)) { + if (preg_match('/^Win.*/', getenv('OS'))) { + if (isset ($_ENV['TMP'])) { + $debugDir = $_ENV['TMP'] . '/'; + } else + if (isset ($_ENV['TEMP'])) { + $debugDir = $_ENV['TEMP'] . '/'; + } else { + $debugDir = ''; + } + } else { + $debugDir = DEFAULT_DEBUG_DIR; + } + $filename = $debugDir . 'phpCAS.log'; + } + + if (empty ($PHPCAS_DEBUG['unique_id'])) { + $PHPCAS_DEBUG['unique_id'] = substr(strtoupper(md5(uniqid(''))), 0, 4); + } + + $PHPCAS_DEBUG['filename'] = $filename; + + phpCAS :: trace('START phpCAS-' . PHPCAS_VERSION . ' ******************'); + } + } + + + /** + * Logs a string in debug mode. + * + * @param $str the string to write + * + * @private + */ + public static function log($str) + { + $indent_str = "."; + global $PHPCAS_DEBUG; + + if (!empty($PHPCAS_DEBUG['filename'])) { + for ($i = 0; $i < $PHPCAS_DEBUG['indent']; $i++) { + $indent_str .= '| '; + } + // allow for multiline output with proper identing. Usefull for dumping cas answers etc. + $str2 = str_replace("\n", "\n" . $PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str, $str); + error_log($PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str . $str2 . "\n", 3, $PHPCAS_DEBUG['filename']); + } + + } + + /** + * This method is used by interface methods to print an error and where the function + * was originally called from. + * + * @param $msg the message to print + * + * @private + */ + public static function error($msg) + { + $dbg = debug_backtrace(); + $function = '?'; + $file = '?'; + $line = '?'; + if (is_array($dbg)) { + for ($i = 1; $i < sizeof($dbg); $i++) { + if (is_array($dbg[$i]) && isset($dbg[$i]['class']) ) { + if ($dbg[$i]['class'] == __CLASS__) { + $function = $dbg[$i]['function']; + $file = $dbg[$i]['file']; + $line = $dbg[$i]['line']; + } + } + } + } + echo "
    \nphpCAS error: " . __CLASS__ . "::" . $function . '(): ' . htmlentities($msg) . " in " . $file . " on line " . $line . "
    \n"; + phpCAS :: trace($msg); + phpCAS :: traceExit(); + exit (); + } + + /** + * This method is used to log something in debug mode. + */ + public static function trace($str) + { + $dbg = debug_backtrace(); + phpCAS :: log($str . ' [' . basename($dbg[0]['file']) . ':' . $dbg[0]['line'] . ']'); + } + + /** + * This method is used to indicate the start of the execution of a function in debug mode. + */ + public static function traceBegin() + { + global $PHPCAS_DEBUG; + + $dbg = debug_backtrace(); + $str = '=> '; + if (!empty ($dbg[1]['class'])) { + $str .= $dbg[1]['class'] . '::'; + } + $str .= $dbg[1]['function'] . '('; + if (is_array($dbg[1]['args'])) { + foreach ($dbg[1]['args'] as $index => $arg) { + if ($index != 0) { + $str .= ', '; + } + if (is_object($arg)) { + $str .= get_class($arg); + } else { + $str .= str_replace(array("\r\n", "\n", "\r"), "", var_export($arg, TRUE)); + } + } + } + if (isset($dbg[1]['file'])) + $file = basename($dbg[1]['file']); + else + $file = 'unknown_file'; + if (isset($dbg[1]['line'])) + $line = $dbg[1]['line']; + else + $line = 'unknown_line'; + $str .= ') [' . $file . ':' . $line . ']'; + phpCAS :: log($str); + $PHPCAS_DEBUG['indent']++; + } + + /** + * This method is used to indicate the end of the execution of a function in debug mode. + * + * @param $res the result of the function + */ + public static function traceEnd($res = '') + { + global $PHPCAS_DEBUG; + + $PHPCAS_DEBUG['indent']--; + $dbg = debug_backtrace(); + $str = ''; + if (is_object($res)) { + $str .= '<= ' . get_class($arg); + } else { + $str .= '<= ' . str_replace(array("\r\n", "\n", "\r"), "", var_export($res, TRUE)); + } + + phpCAS :: log($str); + } + + /** + * This method is used to indicate the end of the execution of the program + */ + public static function traceExit() + { + global $PHPCAS_DEBUG; + + phpCAS :: log('exit()'); + while ($PHPCAS_DEBUG['indent'] > 0) { + phpCAS :: log('-'); + $PHPCAS_DEBUG['indent']--; + } + } + + /** @} */ + // ######################################################################## + // INTERNATIONALIZATION + // ######################################################################## + /** + * @addtogroup publicLang + * @{ + */ + + /** + * This method is used to set the language used by phpCAS. + * @note Can be called only once. + * + * @param $lang a string representing the language. + * + * @sa PHPCAS_LANG_FRENCH, PHPCAS_LANG_ENGLISH + */ + public static function setLang($lang) + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + if (gettype($lang) != 'string') { + phpCAS :: error('type mismatched for parameter $lang (should be `string\')'); + } + $PHPCAS_CLIENT->setLang($lang); + } + + /** @} */ + // ######################################################################## + // VERSION + // ######################################################################## + /** + * @addtogroup public + * @{ + */ + + /** + * This method returns the phpCAS version. + * + * @return the phpCAS version. + */ + public static function getVersion() + { + return PHPCAS_VERSION; + } + + /** @} */ + // ######################################################################## + // HTML OUTPUT + // ######################################################################## + /** + * @addtogroup publicOutput + * @{ + */ + + /** + * This method sets the HTML header used for all outputs. + * + * @param $header the HTML header. + */ + public static function setHTMLHeader($header) + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + if (gettype($header) != 'string') { + phpCAS :: error('type mismatched for parameter $header (should be `string\')'); + } + $PHPCAS_CLIENT->setHTMLHeader($header); + } + + /** + * This method sets the HTML footer used for all outputs. + * + * @param $footer the HTML footer. + */ + public static function setHTMLFooter($footer) + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + if (gettype($footer) != 'string') { + phpCAS :: error('type mismatched for parameter $footer (should be `string\')'); + } + $PHPCAS_CLIENT->setHTMLFooter($footer); + } + + /** @} */ + // ######################################################################## + // PGT STORAGE + // ######################################################################## + /** + * @addtogroup publicPGTStorage + * @{ + */ + + /** + * This method can be used to set a custom PGT storage object. + * + * @param $storage a PGT storage object that inherits from the CAS_PGTStorage class + */ + public static function setPGTStorage($storage) + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_CLIENT->isProxy()) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if ($PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called before ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() (called at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ')'); + } + if ( !($storage instanceof CAS_PGTStorage) ) { + phpCAS :: error('type mismatched for parameter $storage (should be a CAS_PGTStorage `object\')'); + } + $PHPCAS_CLIENT->setPGTStorage($storage); + phpCAS :: traceEnd(); + } + + /** + * This method is used to tell phpCAS to store the response of the + * CAS server to PGT requests in a database. + * + * @param $dsn_or_pdo a dsn string to use for creating a PDO object or a PDO object + * @param $username the username to use when connecting to the database + * @param $password the password to use when connecting to the database + * @param $table the table to use for storing and retrieving PGT's + * @param $driver_options any driver options to use when connecting to the database + */ + public static function setPGTStorageDb($dsn_or_pdo, $username='', $password='', $table='', $driver_options=null) + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_CLIENT->isProxy()) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if ($PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called before ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() (called at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ')'); + } + if (gettype($username) != 'string') { + phpCAS :: error('type mismatched for parameter $username (should be `string\')'); + } + if (gettype($password) != 'string') { + phpCAS :: error('type mismatched for parameter $password (should be `string\')'); + } + if (gettype($table) != 'string') { + phpCAS :: error('type mismatched for parameter $table (should be `string\')'); + } + $PHPCAS_CLIENT->setPGTStorageDb($dsn_or_pdo, $username, $password, $table, $driver_options); + phpCAS :: traceEnd(); + } + + /** + * This method is used to tell phpCAS to store the response of the + * CAS server to PGT requests onto the filesystem. + * @param $format the format used to store the PGT's. This parameter has no effect and is only for backwards compatibility + * @param $path the path where the PGT's should be stored + */ + public static function setPGTStorageFile($format = '', $path = '') + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_CLIENT->isProxy()) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if ($PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called before ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() (called at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ')'); + } + if (gettype($format) != 'string') { + phpCAS :: error('type mismatched for parameter $format (should be `string\')'); + } + if (gettype($path) != 'string') { + phpCAS :: error('type mismatched for parameter $format (should be `string\')'); + } + $PHPCAS_CLIENT->setPGTStorageFile($path); + phpCAS :: traceEnd(); + } + + /** @} */ + // ######################################################################## + // ACCESS TO EXTERNAL SERVICES + // ######################################################################## + /** + * @addtogroup publicServices + * @{ + */ + + /** + * Answer a proxy-authenticated service handler. + * + * @param string $type The service type. One of: + * PHPCAS_PROXIED_SERVICE_HTTP_GET + * PHPCAS_PROXIED_SERVICE_HTTP_POST + * PHPCAS_PROXIED_SERVICE_IMAP + * + * + * @return CAS_ProxiedService + * @throws InvalidArgumentException If the service type is unknown. + */ + public static function getProxiedService ($type) + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_CLIENT->isProxy()) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['result']) { + phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); + } + if (gettype($type) != 'string') { + phpCAS :: error('type mismatched for parameter $type (should be `string\')'); + } + + $res = $PHPCAS_CLIENT->getProxiedService($type); + + phpCAS :: traceEnd(); + return $res; + } + + /** + * Initialize a proxied-service handler with the proxy-ticket it should use. + * + * @param CAS_ProxiedService $proxiedService + * @return void + * @throws CAS_ProxyTicketException If there is a proxy-ticket failure. + * The code of the Exception will be one of: + * PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE + * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE + * PHPCAS_SERVICE_PT_FAILURE + */ + public static function initializeProxiedService (CAS_ProxiedService $proxiedService) + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_CLIENT->isProxy()) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['result']) { + phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); + } + + $PHPCAS_CLIENT->initializeProxiedService($proxiedService); + } + + /** + * This method is used to access an HTTP[S] service. + * + * @param $url the service to access. + * @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on + * success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, + * PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_NOT_AVAILABLE. + * @param $output the output of the service (also used to give an error + * message on failure). + * + * @return TRUE on success, FALSE otherwise (in this later case, $err_code + * gives the reason why it failed and $output contains an error message). + */ + public static function serviceWeb($url, & $err_code, & $output) + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_CLIENT->isProxy()) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['result']) { + phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); + } + if (gettype($url) != 'string') { + phpCAS :: error('type mismatched for parameter $url (should be `string\')'); + } + + $res = $PHPCAS_CLIENT->serviceWeb($url, $err_code, $output); + + phpCAS :: traceEnd($res); + return $res; + } + + /** + * This method is used to access an IMAP/POP3/NNTP service. + * + * @param $url a string giving the URL of the service, including the mailing box + * for IMAP URLs, as accepted by imap_open(). + * @param $service a string giving for CAS retrieve Proxy ticket + * @param $flags options given to imap_open(). + * @param $err_code an error code Possible values are PHPCAS_SERVICE_OK (on + * success), PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE, PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE, + * PHPCAS_SERVICE_PT_FAILURE, PHPCAS_SERVICE_NOT_AVAILABLE. + * @param $err_msg an error message on failure + * @param $pt the Proxy Ticket (PT) retrieved from the CAS server to access the URL + * on success, FALSE on error). + * + * @return an IMAP stream on success, FALSE otherwise (in this later case, $err_code + * gives the reason why it failed and $err_msg contains an error message). + */ + public static function serviceMail($url, $service, $flags, & $err_code, & $err_msg, & $pt) + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_CLIENT->isProxy()) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called after the programmer is sure the user has been authenticated (by calling ' . __CLASS__ . '::checkAuthentication() or ' . __CLASS__ . '::forceAuthentication()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['result']) { + phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); + } + if (gettype($url) != 'string') { + phpCAS :: error('type mismatched for parameter $url (should be `string\')'); + } + + if (gettype($flags) != 'integer') { + phpCAS :: error('type mismatched for parameter $flags (should be `integer\')'); + } + + $res = $PHPCAS_CLIENT->serviceMail($url, $service, $flags, $err_code, $err_msg, $pt); + + phpCAS :: traceEnd($res); + return $res; + } + + /** @} */ + // ######################################################################## + // AUTHENTICATION + // ######################################################################## + /** + * @addtogroup publicAuth + * @{ + */ + + /** + * Set the times authentication will be cached before really accessing the CAS server in gateway mode: + * - -1: check only once, and then never again (until you pree login) + * - 0: always check + * - n: check every "n" time + * + * @param $n an integer. + */ + public static function setCacheTimesForAuthRecheck($n) + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + if (gettype($n) != 'integer') { + phpCAS :: error('type mismatched for parameter $header (should be `string\')'); + } + $PHPCAS_CLIENT->setCacheTimesForAuthRecheck($n); + } + + /** + * Set a callback function to be run when a user authenticates. + * + * The callback function will be passed a $logoutTicket as its first parameter, + * followed by any $additionalArgs you pass. The $logoutTicket parameter is an + * opaque string that can be used to map the session-id to logout request in order + * to support single-signout in applications that manage their own sessions + * (rather than letting phpCAS start the session). + * + * phpCAS::forceAuthentication() will always exit and forward client unless + * they are already authenticated. To perform an action at the moment the user + * logs in (such as registering an account, performing logging, etc), register + * a callback function here. + * + * @param callback $function + * @param optional array $additionalArgs + * @return void + */ + public static function setPostAuthenticateCallback ($function, array $additionalArgs = array()) + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + + $PHPCAS_CLIENT->setPostAuthenticateCallback($function, $additionalArgs); + } + + /** + * Set a callback function to be run when a single-signout request is received. + * + * The callback function will be passed a $logoutTicket as its first parameter, + * followed by any $additionalArgs you pass. The $logoutTicket parameter is an + * opaque string that can be used to map a session-id to the logout request in order + * to support single-signout in applications that manage their own sessions + * (rather than letting phpCAS start and destroy the session). + * + * @param callback $function + * @param optional array $additionalArgs + * @return void + */ + public static function setSingleSignoutCallback ($function, array $additionalArgs = array()) + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + + $PHPCAS_CLIENT->setSingleSignoutCallback($function, $additionalArgs); + } + + /** + * This method is called to check if the user is already authenticated locally or has a global cas session. A already + * existing cas session is determined by a cas gateway call.(cas login call without any interactive prompt) + * @return TRUE when the user is authenticated, FALSE when a previous gateway login failed or + * the function will not return if the user is redirected to the cas server for a gateway login attempt + */ + public static function checkAuthentication() + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + + $auth = $PHPCAS_CLIENT->checkAuthentication(); + + // store where the authentication has been checked and the result + $dbg = debug_backtrace(); + $PHPCAS_AUTH_CHECK_CALL = array ( + 'done' => TRUE, + 'file' => $dbg[0]['file'], + 'line' => $dbg[0]['line'], + 'method' => __CLASS__ . '::' . __FUNCTION__, + 'result' => $auth + ); + phpCAS :: traceEnd($auth); + return $auth; + } + + /** + * This method is called to force authentication if the user was not already + * authenticated. If the user is not authenticated, halt by redirecting to + * the CAS server. + */ + public static function forceAuthentication() + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + + $auth = $PHPCAS_CLIENT->forceAuthentication(); + + // store where the authentication has been checked and the result + $dbg = debug_backtrace(); + $PHPCAS_AUTH_CHECK_CALL = array ( + 'done' => TRUE, + 'file' => $dbg[0]['file'], + 'line' => $dbg[0]['line'], + 'method' => __CLASS__ . '::' . __FUNCTION__, + 'result' => $auth + ); + + if (!$auth) { + phpCAS :: trace('user is not authenticated, redirecting to the CAS server'); + $PHPCAS_CLIENT->forceAuthentication(); + } else { + phpCAS :: trace('no need to authenticate (user `' . phpCAS :: getUser() . '\' is already authenticated)'); + } + + phpCAS :: traceEnd(); + return $auth; + } + + /** + * This method is called to renew the authentication. + **/ + public static function renewAuthentication() + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + $auth = $PHPCAS_CLIENT->renewAuthentication(); + // store where the authentication has been checked and the result + $dbg = debug_backtrace(); + $PHPCAS_AUTH_CHECK_CALL = array ( + 'done' => TRUE, + 'file' => $dbg[0]['file'], + 'line' => $dbg[0]['line'], + 'method' => __CLASS__ . '::' . __FUNCTION__, + 'result' => $auth + ); + + //$PHPCAS_CLIENT->renewAuthentication(); + phpCAS :: traceEnd(); + } + + /** + * This method is called to check if the user is authenticated (previously or by + * tickets given in the URL). + * + * @return TRUE when the user is authenticated. + */ + public static function isAuthenticated() + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + + // call the isAuthenticated method of the global $PHPCAS_CLIENT object + $auth = $PHPCAS_CLIENT->isAuthenticated(); + + // store where the authentication has been checked and the result + $dbg = debug_backtrace(); + $PHPCAS_AUTH_CHECK_CALL = array ( + 'done' => TRUE, + 'file' => $dbg[0]['file'], + 'line' => $dbg[0]['line'], + 'method' => __CLASS__ . '::' . __FUNCTION__, + 'result' => $auth + ); + phpCAS :: traceEnd($auth); + return $auth; + } + + /** + * Checks whether authenticated based on $_SESSION. Useful to avoid + * server calls. + * @return true if authenticated, false otherwise. + * @since 0.4.22 by Brendan Arnold + */ + public static function isSessionAuthenticated() + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + return ($PHPCAS_CLIENT->isSessionAuthenticated()); + } + + /** + * This method returns the CAS user's login name. + * @warning should not be called only after phpCAS::forceAuthentication() + * or phpCAS::checkAuthentication(). + * + * @return the login name of the authenticated user + */ + public static function getUser() + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['result']) { + phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); + } + return $PHPCAS_CLIENT->getUser(); + } + + /** + * Answer attributes about the authenticated user. + * + * @warning should not be called only after phpCAS::forceAuthentication() + * or phpCAS::checkAuthentication(). + * + * @return array + */ + public static function getAttributes() + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['result']) { + phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); + } + return $PHPCAS_CLIENT->getAttributes(); + } + + /** + * Answer true if there are attributes for the authenticated user. + * + * @warning should not be called only after phpCAS::forceAuthentication() + * or phpCAS::checkAuthentication(). + * + * @return boolean + */ + public static function hasAttributes() + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['result']) { + phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); + } + return $PHPCAS_CLIENT->hasAttributes(); + } + + /** + * Answer true if an attribute exists for the authenticated user. + * + * @warning should not be called only after phpCAS::forceAuthentication() + * or phpCAS::checkAuthentication(). + * + * @param string $key + * @return boolean + */ + public static function hasAttribute($key) + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['result']) { + phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); + } + return $PHPCAS_CLIENT->hasAttribute($key); + } + + /** + * Answer an attribute for the authenticated user. + * + * @warning should not be called only after phpCAS::forceAuthentication() + * or phpCAS::checkAuthentication(). + * + * @param string $key + * @return mixed string for a single value or an array if multiple values exist. + */ + public static function getAttribute($key) + { + global $PHPCAS_CLIENT, $PHPCAS_AUTH_CHECK_CALL; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['done']) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::forceAuthentication() or ' . __CLASS__ . '::isAuthenticated()'); + } + if (!$PHPCAS_AUTH_CHECK_CALL['result']) { + phpCAS :: error('authentication was checked (by ' . $PHPCAS_AUTH_CHECK_CALL['method'] . '() at ' . $PHPCAS_AUTH_CHECK_CALL['file'] . ':' . $PHPCAS_AUTH_CHECK_CALL['line'] . ') but the method returned FALSE'); + } + return $PHPCAS_CLIENT->getAttribute($key); + } + + /** + * Handle logout requests. + */ + public static function handleLogoutRequests($check_client = true, $allowed_clients = false) + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + return ($PHPCAS_CLIENT->handleLogoutRequests($check_client, $allowed_clients)); + } + + /** + * This method returns the URL to be used to login. + * or phpCAS::isAuthenticated(). + * + * @return the login name of the authenticated user + */ + public static function getServerLoginURL() + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + return $PHPCAS_CLIENT->getServerLoginURL(); + } + + /** + * Set the login URL of the CAS server. + * @param $url the login URL + * @since 0.4.21 by Wyman Chan + */ + public static function setServerLoginURL($url = '') + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after + ' . __CLASS__ . '::client()'); + } + if (gettype($url) != 'string') { + phpCAS :: error('type mismatched for parameter $url (should be + `string\')'); + } + $PHPCAS_CLIENT->setServerLoginURL($url); + phpCAS :: traceEnd(); + } + + /** + * Set the serviceValidate URL of the CAS server. + * Used only in CAS 1.0 validations + * @param $url the serviceValidate URL + * @since 1.1.0 by Joachim Fritschi + */ + public static function setServerServiceValidateURL($url = '') + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after + ' . __CLASS__ . '::client()'); + } + if (gettype($url) != 'string') { + phpCAS :: error('type mismatched for parameter $url (should be + `string\')'); + } + $PHPCAS_CLIENT->setServerServiceValidateURL($url); + phpCAS :: traceEnd(); + } + + /** + * Set the proxyValidate URL of the CAS server. + * Used for all CAS 2.0 validations + * @param $url the proxyValidate URL + * @since 1.1.0 by Joachim Fritschi + */ + public static function setServerProxyValidateURL($url = '') + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after + ' . __CLASS__ . '::client()'); + } + if (gettype($url) != 'string') { + phpCAS :: error('type mismatched for parameter $url (should be + `string\')'); + } + $PHPCAS_CLIENT->setServerProxyValidateURL($url); + phpCAS :: traceEnd(); + } + + /** + * Set the samlValidate URL of the CAS server. + * @param $url the samlValidate URL + * @since 1.1.0 by Joachim Fritschi + */ + public static function setServerSamlValidateURL($url = '') + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after + ' . __CLASS__ . '::client()'); + } + if (gettype($url) != 'string') { + phpCAS :: error('type mismatched for parameter $url (should be + `string\')'); + } + $PHPCAS_CLIENT->setServerSamlValidateURL($url); + phpCAS :: traceEnd(); + } + + /** + * This method returns the URL to be used to login. + * or phpCAS::isAuthenticated(). + * + * @return the login name of the authenticated user + */ + public static function getServerLogoutURL() + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should not be called before ' . __CLASS__ . '::client() or ' . __CLASS__ . '::proxy()'); + } + return $PHPCAS_CLIENT->getServerLogoutURL(); + } + + /** + * Set the logout URL of the CAS server. + * @param $url the logout URL + * @since 0.4.21 by Wyman Chan + */ + public static function setServerLogoutURL($url = '') + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after + ' . __CLASS__ . '::client()'); + } + if (gettype($url) != 'string') { + phpCAS :: error('type mismatched for parameter $url (should be + `string\')'); + } + $PHPCAS_CLIENT->setServerLogoutURL($url); + phpCAS :: traceEnd(); + } + + /** + * This method is used to logout from CAS. + * @params $params an array that contains the optional url and service parameters that will be passed to the CAS server + * @public + */ + public static function logout($params = "") + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); + } + $parsedParams = array (); + if ($params != "") { + if (is_string($params)) { + phpCAS :: error('method `phpCAS::logout($url)\' is now deprecated, use `phpCAS::logoutWithUrl($url)\' instead'); + } + if (!is_array($params)) { + phpCAS :: error('type mismatched for parameter $params (should be `array\')'); + } + foreach ($params as $key => $value) { + if ($key != "service" && $key != "url") { + phpCAS :: error('only `url\' and `service\' parameters are allowed for method `phpCAS::logout($params)\''); + } + $parsedParams[$key] = $value; + } + } + $PHPCAS_CLIENT->logout($parsedParams); + // never reached + phpCAS :: traceEnd(); + } + + /** + * This method is used to logout from CAS. Halts by redirecting to the CAS server. + * @param $service a URL that will be transmitted to the CAS server + */ + public static function logoutWithRedirectService($service) + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); + } + if (!is_string($service)) { + phpCAS :: error('type mismatched for parameter $service (should be `string\')'); + } + $PHPCAS_CLIENT->logout(array ( + "service" => $service + )); + // never reached + phpCAS :: traceEnd(); + } + + /** + * This method is used to logout from CAS. Halts by redirecting to the CAS server. + * @param $url a URL that will be transmitted to the CAS server + * @deprecated The url parameter has been removed from the CAS server as of version 3.3.5.1 + */ + public static function logoutWithUrl($url) + { + trigger_error('Function deprecated for cas servers >= 3.3.5.1', E_USER_DEPRECATED); + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); + } + if (!is_string($url)) { + phpCAS :: error('type mismatched for parameter $url (should be `string\')'); + } + $PHPCAS_CLIENT->logout(array ( + "url" => $url + )); + // never reached + phpCAS :: traceEnd(); + } + + /** + * This method is used to logout from CAS. Halts by redirecting to the CAS server. + * @param $service a URL that will be transmitted to the CAS server + * @param $url a URL that will be transmitted to the CAS server + * @deprecated The url parameter has been removed from the CAS server as of version 3.3.5.1 + */ + public static function logoutWithRedirectServiceAndUrl($service, $url) + { + trigger_error('Function deprecated for cas servers >= 3.3.5.1', E_USER_DEPRECATED); + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); + } + if (!is_string($service)) { + phpCAS :: error('type mismatched for parameter $service (should be `string\')'); + } + if (!is_string($url)) { + phpCAS :: error('type mismatched for parameter $url (should be `string\')'); + } + $PHPCAS_CLIENT->logout(array ( + "service" => $service, + "url" => $url + )); + // never reached + phpCAS :: traceEnd(); + } + + /** + * Set the fixed URL that will be used by the CAS server to transmit the PGT. + * When this method is not called, a phpCAS script uses its own URL for the callback. + * + * @param $url the URL + */ + public static function setFixedCallbackURL($url = '') + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (!$PHPCAS_CLIENT->isProxy()) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (gettype($url) != 'string') { + phpCAS :: error('type mismatched for parameter $url (should be `string\')'); + } + $PHPCAS_CLIENT->setCallbackURL($url); + phpCAS :: traceEnd(); + } + + /** + * Set the fixed URL that will be set as the CAS service parameter. When this + * method is not called, a phpCAS script uses its own URL. + * + * @param $url the URL + */ + public static function setFixedServiceURL($url) + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (gettype($url) != 'string') { + phpCAS :: error('type mismatched for parameter $url (should be `string\')'); + } + $PHPCAS_CLIENT->setURL($url); + phpCAS :: traceEnd(); + } + + /** + * Get the URL that is set as the CAS service parameter. + */ + public static function getServiceURL() + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + return ($PHPCAS_CLIENT->getURL()); + } + + /** + * Retrieve a Proxy Ticket from the CAS server. + */ + public static function retrievePT($target_service, & $err_code, & $err_msg) + { + global $PHPCAS_CLIENT; + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::proxy()'); + } + if (gettype($target_service) != 'string') { + phpCAS :: error('type mismatched for parameter $target_service(should be `string\')'); + } + return ($PHPCAS_CLIENT->retrievePT($target_service, $err_code, $err_msg)); + } + + /** + * Set the certificate of the CAS server CA. + * + * @param $cert the CA certificate + */ + public static function setCasServerCACert($cert) + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); + } + if (gettype($cert) != 'string') { + phpCAS :: error('type mismatched for parameter $cert (should be `string\')'); + } + $PHPCAS_CLIENT->setCasServerCACert($cert); + phpCAS :: traceEnd(); + } + + /** + * Set no SSL validation for the CAS server. + */ + public static function setNoCasServerValidation() + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); + } + $PHPCAS_CLIENT->setNoCasServerValidation(); + phpCAS :: traceEnd(); + } + + + /** + * Disable the removal of a CAS-Ticket from the URL when authenticating + * DISABLING POSES A SECURITY RISK: + * We normally remove the ticket by an additional redirect as a security precaution * to prevent a ticket in the HTTP_REFERRER or be carried over in the URL parameter - */ - public static function setNoClearTicketsFromUrl() { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); - } - $PHPCAS_CLIENT->setNoClearTicketsFromUrl(); - phpCAS :: traceEnd(); - } - - /** @} */ - - /** - * Change CURL options. - * CURL is used to connect through HTTPS to CAS server - * @param $key the option key - * @param $value the value to set - */ - public static function setExtraCurlOption($key, $value) { - global $PHPCAS_CLIENT; - phpCAS :: traceBegin(); - if (!is_object($PHPCAS_CLIENT)) { - phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); - } - $PHPCAS_CLIENT->setExtraCurlOption($key, $value); - phpCAS :: traceEnd(); - } - - - /** - * Answer an array of proxies that are sitting in front of this application. - * - * This method will only return a non-empty array if we have received and validated - * a Proxy Ticket. - * - * @return array - * @access public - * @since 6/25/09 - */ - public static function getProxies () { - global $PHPCAS_CLIENT; - if ( !is_object($PHPCAS_CLIENT) ) { - phpCAS::error('this method should only be called after '.__CLASS__.'::client()'); - } - - return($PHPCAS_CLIENT->getProxies()); - } + */ + public static function setNoClearTicketsFromUrl() + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); + } + $PHPCAS_CLIENT->setNoClearTicketsFromUrl(); + phpCAS :: traceEnd(); + } + + /** @} */ + + /** + * Change CURL options. + * CURL is used to connect through HTTPS to CAS server + * @param $key the option key + * @param $value the value to set + */ + public static function setExtraCurlOption($key, $value) + { + global $PHPCAS_CLIENT; + phpCAS :: traceBegin(); + if (!is_object($PHPCAS_CLIENT)) { + phpCAS :: error('this method should only be called after ' . __CLASS__ . '::client() or' . __CLASS__ . '::proxy()'); + } + $PHPCAS_CLIENT->setExtraCurlOption($key, $value); + phpCAS :: traceEnd(); + } + + + /** + * Answer an array of proxies that are sitting in front of this application. + * + * This method will only return a non-empty array if we have received and validated + * a Proxy Ticket. + * + * @return array + * @access public + * @since 6/25/09 + */ + public static function getProxies () + { + global $PHPCAS_CLIENT; + if ( !is_object($PHPCAS_CLIENT) ) { + phpCAS::error('this method should only be called after '.__CLASS__.'::client()'); + } + + return($PHPCAS_CLIENT->getProxies()); + } } @@ -1823,4 +1877,3 @@ public static function getProxies () { /** * @example example_advanced_saml11.php */ -?> diff --git a/core/src/plugins/auth.cas/class.casAuthDriver.php b/core/src/plugins/auth.cas/class.casAuthDriver.php index 4f956c5c18..4d2c6c84c5 100644 --- a/core/src/plugins/auth.cas/class.casAuthDriver.php +++ b/core/src/plugins/auth.cas/class.casAuthDriver.php @@ -33,7 +33,7 @@ class casAuthDriver extends serialAuthDriver private $cas_port; private $cas_uri; - function init($options) + public function init($options) { parent::init($options); $this->cas_server = $this->getOption("CAS_SERVER"); @@ -43,20 +43,19 @@ function init($options) phpCAS::setNoCasServerValidation(); } - function usersEditable() + public function usersEditable() { return false; } - function passwordsEditable() + public function passwordsEditable() { return false; } - function preLogUser($sessionId) + public function preLogUser($sessionId) { - if ($_GET['get_action'] == "logout") - { + if ($_GET['get_action'] == "logout") { phpCAS::logout(); return; } @@ -70,7 +69,7 @@ function preLogUser($sessionId) AuthService::logUser($cas_user, "", true); } - function getLogoutRedirect() + public function getLogoutRedirect() { $_SESSION = array(); session_destroy(); diff --git a/core/src/plugins/auth.cas/i18n/conf/es.php b/core/src/plugins/auth.cas/i18n/conf/es.php index d970aae16b..13806d15ed 100644 --- a/core/src/plugins/auth.cas/i18n/conf/es.php +++ b/core/src/plugins/auth.cas/i18n/conf/es.php @@ -29,4 +29,3 @@ "SQL Driver" => "Driver SQL", "SQL configuration using the same syntax as auth.sql plugin" => "Configuración de SQL usando la misma sintaxis que el plugin auth.sql" ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.cas/manifest.xml b/core/src/plugins/auth.cas/manifest.xml index 95257195c8..9226084033 100644 --- a/core/src/plugins/auth.cas/manifest.xml +++ b/core/src/plugins/auth.cas/manifest.xml @@ -51,5 +51,5 @@ - + diff --git a/core/src/plugins/auth.cmsms/action.xml b/core/src/plugins/auth.cmsms/action.xml index 324e820123..80b9707152 100644 --- a/core/src/plugins/auth.cmsms/action.xml +++ b/core/src/plugins/auth.cmsms/action.xml @@ -1,10 +1,10 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/core/src/plugins/auth.cmsms/class.cmsmsAuthDriver.php b/core/src/plugins/auth.cmsms/class.cmsmsAuthDriver.php index 20b90fef1d..5f3e0d3297 100644 --- a/core/src/plugins/auth.cmsms/class.cmsmsAuthDriver.php +++ b/core/src/plugins/auth.cmsms/class.cmsmsAuthDriver.php @@ -30,180 +30,197 @@ * You must modify conf.php like this: * "AUTH_DRIVER" => array( - "NAME" => "cmsms", - "OPTIONS" => array( + "NAME" => "cmsms", + "OPTIONS" => array( "SQL_DRIVER" => Array( - 'driver' => 'mysql', - 'host' => 'localhost', - 'username' => 'root', - 'password' => '', - 'database' => 'your_cmsms_db' - ), - "PREFIX_TABLE" => 'your_prefix', - "LOGIN_URL" => 'http://url of FEU login form', - "LOGOUT_URL" => 'http://url you want with the logout button ', - "SECRET" => '1234' //the common secret code between the two application (store in cmsms database on the other side) - ) - - ), + 'driver' => 'mysql', + 'host' => 'localhost', + 'username' => 'root', + 'password' => '', + 'database' => 'your_cmsms_db' + ), + "PREFIX_TABLE" => 'your_prefix', + "LOGIN_URL" => 'http://url of FEU login form', + "LOGOUT_URL" => 'http://url you want with the logout button ', + "SECRET" => '1234' //the common secret code between the two application (store in cmsms database on the other side) + ) + + ), * @package AjaXplorer_Plugins * @subpackage Auth */ -class cmsmsAuthDriver extends AbstractAuthDriver { - - var $sqlDriver; - var $driverName = "cmsms"; - var $slaveMode; - var $secret; - var $secret_cmsms; - var $urls; - var $prefix; - var $groupid; - - - function init($options){ +class cmsmsAuthDriver extends AbstractAuthDriver +{ + public $sqlDriver; + public $driverName = "cmsms"; + public $slaveMode; + public $secret; + public $secret_cmsms; + public $urls; + public $prefix; + public $groupid; + + + public function init($options) + { require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); - parent::init($options); - $this->sqlDriver = $this->options["SQL_DRIVER"]; - try { - dibi::connect($this->sqlDriver); - } catch (DibiException $e) { - echo get_class($e), ': ', $e->getMessage(), "\n"; - exit(1); - } - $this->secret = $this->options["SECRET"]; - $this->prefix = $this->options["PREFIX_TABLE"]; + parent::init($options); + $this->sqlDriver = $this->options["SQL_DRIVER"]; + try { + dibi::connect($this->sqlDriver); + } catch (DibiException $e) { + echo get_class($e), ': ', $e->getMessage(), "\n"; + exit(1); + } + $this->secret = $this->options["SECRET"]; + $this->prefix = $this->options["PREFIX_TABLE"]; $this->urls = array($this->options["LOGIN_URL"], $this->options["LOGOUT_URL"]); - $this->slaveMode = true; + $this->slaveMode = true; $res = dibi::query("SELECT sitepref_value FROM [".$this->prefix."siteprefs] WHERE sitepref_name = 'FEUajaxplorer_mapi_pref_ajxp_auth_group'"); $grp = $res->fetchSingle(); - $this->groupid = $grp; + $this->groupid = $grp; $res2 = dibi::query("SELECT sitepref_value FROM [".$this->prefix."siteprefs] WHERE sitepref_name = 'FEUajaxplorer_mapi_pref_ajxp_secret'"); $sec = $res2->fetchSingle(); - $this->secret_cmsms = trim($sec); - - } - - function listUsers(){ - $res = dibi::query("SELECT * FROM [".$this->prefix."module_feusers_users], [".$this->prefix."module_feusers_belongs] WHERE id = userid AND groupid=".$this->groupid); - $pairs = $res->fetchPairs('username', 'password'); - return $pairs; - } - - function userExists($login){ - $res = dibi::query("SELECT * FROM [".$this->prefix."module_feusers_users], [".$this->prefix."module_feusers_belongs] WHERE [username]=%s AND id = userid AND groupid=%s", $login, $this->groupid); - return($res->getRowCount()); - } - - function userIsConnected($username, $sessionid){ - $userid = $this->getUserId($username); - $res = dibi::query("SELECT * FROM [".$this->prefix."module_feusers_loggedin] WHERE [userid]=%s AND sessionid=%s", $userid, $sessionid); - return($res->getRowCount()); - } - - // Never call if used with the initial cmsms ajxp module. - // We don't check the password because we use sessionid and userid from FEU loggedin table. - function checkPassword($login, $pass, $seed){ - $userStoredPass = $this->getUserPass($login); - if(!$userStoredPass) return false; - if(md5($pass) == $userStoredPass) { - $loggedinData['sessionid']=session_id(); - $loggedinData['lastused']=time; - $loggedinData['userid']=$this->getUserId($login); - dibi::query('INSERT INTO ['.$this->prefix.'module_feusers_loggedin]', $loggedinData); - } - - return ($userStoredPass == md5($pass)); - } - - function usersEditable(){ - return true; - } - function passwordsEditable(){ - return true; - } - - function createUser($login, $passwd){ - $users = $this->listUsers(); - if(!is_array($users)) $users = array(); - if(array_key_exists($login, $users)) return "exists"; - $userData = array("username" => $login); - $userData["password"] = md5($passwd); - $userData["id"]=$this->getUserSeq()+1; - $userData["createdate"]=date("Y-m-d H:i:s"); - dibi::query('INSERT INTO ['.$this->prefix.'module_feusers_users]', $userData); - $this->setUserSeq($userData["id"]); - $belongsData["userid"]=$userData["id"]; - $belongsData["groupid"]=$this->groupid; - dibi::query('INSERT INTO ['.$this->prefix.'module_feusers_belongs]', $belongsData); - } - function changePassword($login, $newPass){ - $users = $this->listUsers(); - if(!is_array($users) || !array_key_exists($login, $users)) return ; - $userData = array("username" => $login); - $userData["password"] = md5($newPass); - dibi::query("UPDATE [".$this->prefix."module_feusers_users] SET ", $userData, "WHERE `username`=%s", $login); - } - function deleteUser($login){ - $uid=$this->getUserId($login); - //suppress all references in CMSMS FEU tables - dibi::query("DELETE FROM [".$this->prefix."module_feusers_users] WHERE `username`=%s", $login); - dibi::query("DELETE FROM [".$this->prefix."module_feusers_belongs] WHERE `userid`=%s", $uid); - dibi::query("DELETE FROM [".$this->prefix."module_feusers_properties] WHERE `userid`=%s", $uid); - } - - function getUserPass($login){ - $res = dibi::query("SELECT [password] FROM [".$this->prefix."module_feusers_users], [".$this->prefix."module_feusers_belongs] WHERE [username]=%s AND id = userid AND groupid= %s", $login, $this->groupid); - $pass = $res->fetchSingle(); - return $pass; - } - - function getUserSeq(){ - $res = dibi::query("SELECT [id] FROM [".$this->prefix."module_feusers_users_seq]"); - $seq = $res->fetchSingle(); - return $seq; + $this->secret_cmsms = trim($sec); + + } + + public function listUsers() + { + $res = dibi::query("SELECT * FROM [".$this->prefix."module_feusers_users], [".$this->prefix."module_feusers_belongs] WHERE id = userid AND groupid=".$this->groupid); + $pairs = $res->fetchPairs('username', 'password'); + return $pairs; + } + + public function userExists($login) + { + $res = dibi::query("SELECT * FROM [".$this->prefix."module_feusers_users], [".$this->prefix."module_feusers_belongs] WHERE [username]=%s AND id = userid AND groupid=%s", $login, $this->groupid); + return($res->getRowCount()); + } + + public function userIsConnected($username, $sessionid) + { + $userid = $this->getUserId($username); + $res = dibi::query("SELECT * FROM [".$this->prefix."module_feusers_loggedin] WHERE [userid]=%s AND sessionid=%s", $userid, $sessionid); + return($res->getRowCount()); + } + + // Never call if used with the initial cmsms ajxp module. + // We don't check the password because we use sessionid and userid from FEU loggedin table. + public function checkPassword($login, $pass, $seed) + { + $userStoredPass = $this->getUserPass($login); + if(!$userStoredPass) return false; + if (md5($pass) == $userStoredPass) { + $loggedinData['sessionid']=session_id(); + $loggedinData['lastused']=time; + $loggedinData['userid']=$this->getUserId($login); + dibi::query('INSERT INTO ['.$this->prefix.'module_feusers_loggedin]', $loggedinData); + } + + return ($userStoredPass == md5($pass)); + } + + public function usersEditable() + { + return true; + } + public function passwordsEditable() + { + return true; + } + + public function createUser($login, $passwd) + { + $users = $this->listUsers(); + if(!is_array($users)) $users = array(); + if(array_key_exists($login, $users)) return "exists"; + $userData = array("username" => $login); + $userData["password"] = md5($passwd); + $userData["id"]=$this->getUserSeq()+1; + $userData["createdate"]=date("Y-m-d H:i:s"); + dibi::query('INSERT INTO ['.$this->prefix.'module_feusers_users]', $userData); + $this->setUserSeq($userData["id"]); + $belongsData["userid"]=$userData["id"]; + $belongsData["groupid"]=$this->groupid; + dibi::query('INSERT INTO ['.$this->prefix.'module_feusers_belongs]', $belongsData); + } + public function changePassword($login, $newPass) + { + $users = $this->listUsers(); + if(!is_array($users) || !array_key_exists($login, $users)) return ; + $userData = array("username" => $login); + $userData["password"] = md5($newPass); + dibi::query("UPDATE [".$this->prefix."module_feusers_users] SET ", $userData, "WHERE `username`=%s", $login); + } + public function deleteUser($login) + { + $uid=$this->getUserId($login); + //suppress all references in CMSMS FEU tables + dibi::query("DELETE FROM [".$this->prefix."module_feusers_users] WHERE `username`=%s", $login); + dibi::query("DELETE FROM [".$this->prefix."module_feusers_belongs] WHERE `userid`=%s", $uid); + dibi::query("DELETE FROM [".$this->prefix."module_feusers_properties] WHERE `userid`=%s", $uid); + } + + public function getUserPass($login) + { + $res = dibi::query("SELECT [password] FROM [".$this->prefix."module_feusers_users], [".$this->prefix."module_feusers_belongs] WHERE [username]=%s AND id = userid AND groupid= %s", $login, $this->groupid); + $pass = $res->fetchSingle(); + return $pass; + } + + public function getUserSeq() + { + $res = dibi::query("SELECT [id] FROM [".$this->prefix."module_feusers_users_seq]"); + $seq = $res->fetchSingle(); + return $seq; } - function setUserSeq($num){ - $res = dibi::query("UPDATE [".$this->prefix."module_feusers_users_seq] SET `id`=".$num); - } - - function getUserId($login){ - $res = dibi::query("SELECT id FROM [".$this->prefix."module_feusers_users], [".$this->prefix."module_feusers_belongs] WHERE [username]=%s AND id = userid AND groupid= %s", $login, $this->groupid); - $uid = $res->fetchSingle(); - return $uid; - } - function listUsersSerial(){ - return AJXP_Utils::loadSerialFile($this->usersSerFile); - } - function getLoginRedirect(){ - if ($this->slaveMode) { - if (isset($_SESSION["AJXP_USER"])) return false; - return $this->urls[0]; - } - return false; + public function setUserSeq($num) + { + $res = dibi::query("UPDATE [".$this->prefix."module_feusers_users_seq] SET `id`=".$num); + } + + public function getUserId($login) + { + $res = dibi::query("SELECT id FROM [".$this->prefix."module_feusers_users], [".$this->prefix."module_feusers_belongs] WHERE [username]=%s AND id = userid AND groupid= %s", $login, $this->groupid); + $uid = $res->fetchSingle(); + return $uid; + } + public function listUsersSerial() + { + return AJXP_Utils::loadSerialFile($this->usersSerFile); + } + public function getLoginRedirect() + { + if ($this->slaveMode) { + if (isset($_SESSION["AJXP_USER"])) return false; + return $this->urls[0]; + } + return false; } - function getLogoutRedirect(){ - if ($this->slaveMode) { - return $this->urls[1]; - } - return false; - } + public function getLogoutRedirect() + { + if ($this->slaveMode) { + return $this->urls[1]; + } + return false; + } // call by CMS Made Simple with the followings arguments: // username : username of the FEU user -// sessionid : num. of session in the loggedin table for matching the logging the user here. - function login_cmsms(){ - $username=strip_tags($_GET['username']); - $sessionid=strip_tags($_GET['sessionid']); - //verifying the CIA secret code... - if($this->secret != $this->secret_cmsms) exit( "secret");//return header("Location: ".$this->getLoginRedirect()); - //verifying that the user exists (in the right group) - if(!$this->userExists($username)) exit( "exists");//return header("Location: ".$this->getLoginRedirect()); - //verifying that the user is connected - if(!$this->userIsConnected($username, $sessionid)) exit( "connect");//return header("Location: ".$this->getLoginRedirect()); - //all tests passed...we connect the user - if($log=AuthService::logUser($username,"",true)==1) return header("Location: index.php"); - } +// sessionid : num. of session in the loggedin table for matching the logging the user here. + public function login_cmsms() + { + $username=strip_tags($_GET['username']); + $sessionid=strip_tags($_GET['sessionid']); + //verifying the CIA secret code... + if($this->secret != $this->secret_cmsms) exit( "secret");//return header("Location: ".$this->getLoginRedirect()); + //verifying that the user exists (in the right group) + if(!$this->userExists($username)) exit( "exists");//return header("Location: ".$this->getLoginRedirect()); + //verifying that the user is connected + if(!$this->userIsConnected($username, $sessionid)) exit( "connect");//return header("Location: ".$this->getLoginRedirect()); + //all tests passed...we connect the user + if($log=AuthService::logUser($username,"",true)==1) return header("Location: index.php"); + } } -?> \ No newline at end of file diff --git a/core/src/plugins/auth.cmsms/i18n/conf/en.php b/core/src/plugins/auth.cmsms/i18n/conf/en.php index 1ce6a79771..c4c03867f2 100644 --- a/core/src/plugins/auth.cmsms/i18n/conf/en.php +++ b/core/src/plugins/auth.cmsms/i18n/conf/en.php @@ -31,4 +31,3 @@ "Prefix tables" => "Prefix tables", "Prefix of CMSMS tables " => "Prefix of CMSMS tables ", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.cmsms/i18n/conf/fr.php b/core/src/plugins/auth.cmsms/i18n/conf/fr.php index 40e14059c9..d2c00db592 100644 --- a/core/src/plugins/auth.cmsms/i18n/conf/fr.php +++ b/core/src/plugins/auth.cmsms/i18n/conf/fr.php @@ -31,4 +31,3 @@ "Prefix tables" => "Préfixes", "Prefix of CMSMS tables " => "Préfixes des tables CMSMS", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.cmsms/manifest.xml b/core/src/plugins/auth.cmsms/manifest.xml index 546691cc97..424afabaab 100644 --- a/core/src/plugins/auth.cmsms/manifest.xml +++ b/core/src/plugins/auth.cmsms/manifest.xml @@ -21,6 +21,6 @@ - + - \ No newline at end of file + diff --git a/core/src/plugins/auth.ftp/class.ftpAuthDriver.php b/core/src/plugins/auth.ftp/class.ftpAuthDriver.php index 0928b67d81..a7e47c8156 100644 --- a/core/src/plugins/auth.ftp/class.ftpAuthDriver.php +++ b/core/src/plugins/auth.ftp/class.ftpAuthDriver.php @@ -22,10 +22,12 @@ require_once(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/access.ftp/class.ftpAccessWrapper.php"); -class ftpSonWrapper extends ftpAccessWrapper { - public function initUrl($url){ - $this->parseUrl($url, true); - } +class ftpSonWrapper extends ftpAccessWrapper +{ + public function initUrl($url) + { + $this->parseUrl($url, true); + } } /** @@ -33,131 +35,143 @@ public function initUrl($url){ * @package AjaXplorer_Plugins * @subpackage Auth */ -class ftpAuthDriver extends AbstractAuthDriver { - - var $driverName = "ftp"; - - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); - if($contribNode->nodeName != "actions") return ; - $actionXpath=new DOMXPath($contribNode->ownerDocument); - if(!isset($this->options["FTP_LOGIN_SCREEN"]) || $this->options["FTP_LOGIN_SCREEN"] != "TRUE" || $this->options["FTP_LOGIN_SCREEN"] === false){ - // Remove "ftp_login" && "ftp_set_data" actions - $nodeList = $actionXpath->query('action[@name="dynamic_login"]', $contribNode); - if(!$nodeList->length) return ; - unset($this->actions["dynamic_login"]); - $contribNode->removeChild($nodeList->item(0)); - - $nodeList = $actionXpath->query('action[@name="ftp_set_data"]', $contribNode); - if(!$nodeList->length) return ; - unset($this->actions["ftp_set_data"]); - $contribNode->removeChild($node = $nodeList->item(0)); - }else{ - // Replace "login" by "dynamic_login" - $loginList = $actionXpath->query('action[@name="login"]', $contribNode); - if($loginList->length && $loginList->item(0)->getAttribute("auth_ftp_impl") == null){ - $contribNode->removeChild($loginList->item(0)); - } - $dynaLoginList = $actionXpath->query('action[@name="dynamic_login"]', $contribNode); - if($dynaLoginList->length){ - $dynaLoginList->item(0)->setAttribute("name", "login"); - $dynaLoginList->item(0)->setAttribute("auth_ftp_impl", "true"); - } - } - } - - - function listUsers(){ - $adminUser = $this->options["AJXP_ADMIN_LOGIN"]; - if(isSet($this->options["ADMIN_USER"])) { +class ftpAuthDriver extends AbstractAuthDriver +{ + public $driverName = "ftp"; + + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); + if($contribNode->nodeName != "actions") return ; + $actionXpath=new DOMXPath($contribNode->ownerDocument); + if (!isset($this->options["FTP_LOGIN_SCREEN"]) || $this->options["FTP_LOGIN_SCREEN"] != "TRUE" || $this->options["FTP_LOGIN_SCREEN"] === false) { + // Remove "ftp_login" && "ftp_set_data" actions + $nodeList = $actionXpath->query('action[@name="dynamic_login"]', $contribNode); + if(!$nodeList->length) return ; + unset($this->actions["dynamic_login"]); + $contribNode->removeChild($nodeList->item(0)); + + $nodeList = $actionXpath->query('action[@name="ftp_set_data"]', $contribNode); + if(!$nodeList->length) return ; + unset($this->actions["ftp_set_data"]); + $contribNode->removeChild($node = $nodeList->item(0)); + } else { + // Replace "login" by "dynamic_login" + $loginList = $actionXpath->query('action[@name="login"]', $contribNode); + if ($loginList->length && $loginList->item(0)->getAttribute("auth_ftp_impl") == null) { + $contribNode->removeChild($loginList->item(0)); + } + $dynaLoginList = $actionXpath->query('action[@name="dynamic_login"]', $contribNode); + if ($dynaLoginList->length) { + $dynaLoginList->item(0)->setAttribute("name", "login"); + $dynaLoginList->item(0)->setAttribute("auth_ftp_impl", "true"); + } + } + } + + + public function listUsers() + { + $adminUser = $this->options["AJXP_ADMIN_LOGIN"]; + if (isSet($this->options["ADMIN_USER"])) { $adminUser = $this->options["AJXP_ADMIN_LOGIN"]; } - return array($adminUser => $adminUser); - } - - function userExists($login){ - return true ; - } - - function logoutCallback($actionName, $httpVars, $fileVars){ - $safeCredentials = AJXP_Safe::loadCredentials(); - $crtUser = $safeCredentials["user"]; - if(isSet($_SESSION["AJXP_DYNAMIC_FTP_DATA"])){ - unset($_SESSION["AJXP_DYNAMIC_FTP_DATA"]); - } - AJXP_Safe::clearCredentials(); - $adminUser = $this->options["AJXP_ADMIN_LOGIN"]; - if(isSet($this->options["ADMIN_USER"])) { + return array($adminUser => $adminUser); + } + + public function userExists($login) + { + return true ; + } + + public function logoutCallback($actionName, $httpVars, $fileVars) + { + $safeCredentials = AJXP_Safe::loadCredentials(); + $crtUser = $safeCredentials["user"]; + if (isSet($_SESSION["AJXP_DYNAMIC_FTP_DATA"])) { + unset($_SESSION["AJXP_DYNAMIC_FTP_DATA"]); + } + AJXP_Safe::clearCredentials(); + $adminUser = $this->options["AJXP_ADMIN_LOGIN"]; + if (isSet($this->options["ADMIN_USER"])) { $adminUser = $this->options["AJXP_ADMIN_LOGIN"]; } - $subUsers = array(); - if($crtUser != $adminUser && $crtUser!=""){ + $subUsers = array(); + if ($crtUser != $adminUser && $crtUser!="") { ConfService::getConfStorageImpl()->deleteUser($crtUser, $subUsers); - } - AuthService::disconnect(); + } + AuthService::disconnect(); session_destroy(); - session_write_close(); - AJXP_XMLWriter::header(); - AJXP_XMLWriter::loggingResult(2); - AJXP_XMLWriter::close(); - } - - function setFtpDataCallback($actionName, $httpVars, $fileVars){ - $options = array("CHARSET", "FTP_DIRECT", "FTP_HOST", "FTP_PORT", "FTP_SECURE", "PATH"); - $ftpOptions = array(); - foreach ($options as $option){ - if(isSet($httpVars[$option])){ - $ftpOptions[$option] = $httpVars[$option]; - } - } - $_SESSION["AJXP_DYNAMIC_FTP_DATA"] = $ftpOptions; - } - - function testParameters($params){ + session_write_close(); + AJXP_XMLWriter::header(); + AJXP_XMLWriter::loggingResult(2); + AJXP_XMLWriter::close(); + } + + public function setFtpDataCallback($actionName, $httpVars, $fileVars) + { + $options = array("CHARSET", "FTP_DIRECT", "FTP_HOST", "FTP_PORT", "FTP_SECURE", "PATH"); + $ftpOptions = array(); + foreach ($options as $option) { + if (isSet($httpVars[$option])) { + $ftpOptions[$option] = $httpVars[$option]; + } + } + $_SESSION["AJXP_DYNAMIC_FTP_DATA"] = $ftpOptions; + } + + public function testParameters($params) + { AJXP_Logger::debug("TESTING", $params); $repositoryId = $params["REPOSITORY_ID"]; $wrapper = new ftpSonWrapper(); - try{ + try { $wrapper->initUrl("ajxp.ftp://fake:fake@$repositoryId/"); - }catch (Exception $e){ - if($e->getMessage() == "Cannot login to FTP server with user fake"){ + } catch (Exception $e) { + if ($e->getMessage() == "Cannot login to FTP server with user fake") { return "SUCCESS: FTP server successfully contacted."; - }else{ + } else { return "ERROR: ".$e->getMessage(); } } return "SUCCESS: Could succesfully connect to the FTP server!"; } - function checkPassword($login, $pass, $seed){ - $wrapper = new ftpSonWrapper(); - $repoId = $this->options["REPOSITORY_ID"]; - try{ + public function checkPassword($login, $pass, $seed) + { + $wrapper = new ftpSonWrapper(); + $repoId = $this->options["REPOSITORY_ID"]; + try { $wrapper->initUrl("ajxp.ftp://".rawurlencode($login).":".rawurlencode($pass)."@$repoId/"); - AJXP_Safe::storeCredentials($login, $pass); - }catch(Exception $e){ - return false; - } - return true; - } - - function usersEditable(){ - return false; - } - function passwordsEditable(){ - return false; - } - - function createUser($login, $passwd){ - } - function changePassword($login, $newPass){ - } - function deleteUser($login){ - } - - function getUserPass($login){ - return ""; - } + AJXP_Safe::storeCredentials($login, $pass); + } catch (Exception $e) { + return false; + } + return true; + } + + public function usersEditable() + { + return false; + } + public function passwordsEditable() + { + return false; + } + + public function createUser($login, $passwd) + { + } + public function changePassword($login, $newPass) + { + } + public function deleteUser($login) + { + } + + public function getUserPass($login) + { + return ""; + } } -?> \ No newline at end of file diff --git a/core/src/plugins/auth.ftp/i18n/conf/en.php b/core/src/plugins/auth.ftp/i18n/conf/en.php index 9f8d5d0d9c..4f33f214fd 100644 --- a/core/src/plugins/auth.ftp/i18n/conf/en.php +++ b/core/src/plugins/auth.ftp/i18n/conf/en.php @@ -28,4 +28,3 @@ "Admin user" => "Admin user", "The ID of an existing admin for Ajaxplorer (using conf.serial)" => "The ID of an existing admin for Ajaxplorer (using conf.serial)", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.ftp/i18n/conf/fr.php b/core/src/plugins/auth.ftp/i18n/conf/fr.php index 48898496db..5b56e05fa9 100644 --- a/core/src/plugins/auth.ftp/i18n/conf/fr.php +++ b/core/src/plugins/auth.ftp/i18n/conf/fr.php @@ -28,4 +28,3 @@ "Admin user" => "Utilisateur admin", "The ID of an existing admin for Ajaxplorer (using conf.serial)" => "ID d'un utilisateur admin récuperé dans conf.serial.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.ftp/i18n/conf/pt.php b/core/src/plugins/auth.ftp/i18n/conf/pt.php index 60d4e82d97..23b856be30 100644 --- a/core/src/plugins/auth.ftp/i18n/conf/pt.php +++ b/core/src/plugins/auth.ftp/i18n/conf/pt.php @@ -28,4 +28,3 @@ "Admin user" => "Administrador", "The ID of an existing admin for Ajaxplorer (using conf.serial)" => "Introduzir o ID de um administrador existente do AjaXplorer (utilizando conf.serial)", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.ftp/i18n/en.php b/core/src/plugins/auth.ftp/i18n/en.php index bfa95d59b8..186902aa00 100644 --- a/core/src/plugins/auth.ftp/i18n/en.php +++ b/core/src/plugins/auth.ftp/i18n/en.php @@ -1,31 +1,30 @@ - -* This file is part of AjaXplorer. -* -* AjaXplorer is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* AjaXplorer is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with AjaXplorer. If not, see . -* -* The latest code can be found at . -*/ -$mess=array( -"1" => "Enter connexion data", -"2" => "Host", -"3" => "Optionnal Data", -"4" => "Start", -"5" => "Protocol", -"6" => "Charset", -"7" => "Active", -"8" => "Port", -); -?> \ No newline at end of file + +* This file is part of AjaXplorer. +* +* AjaXplorer is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* AjaXplorer is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with AjaXplorer. If not, see . +* +* The latest code can be found at . +*/ +$mess=array( +"1" => "Enter connexion data", +"2" => "Host", +"3" => "Optionnal Data", +"4" => "Start", +"5" => "Protocol", +"6" => "Charset", +"7" => "Active", +"8" => "Port", +); diff --git a/core/src/plugins/auth.ftp/i18n/et.php b/core/src/plugins/auth.ftp/i18n/et.php index 52632db312..d5aa930581 100644 --- a/core/src/plugins/auth.ftp/i18n/et.php +++ b/core/src/plugins/auth.ftp/i18n/et.php @@ -32,4 +32,3 @@ "7" => "Aktiivne", "8" => "Port", ); -?> diff --git a/core/src/plugins/auth.ftp/i18n/fr.php b/core/src/plugins/auth.ftp/i18n/fr.php index 90fe0a3c87..64ae1db0f7 100644 --- a/core/src/plugins/auth.ftp/i18n/fr.php +++ b/core/src/plugins/auth.ftp/i18n/fr.php @@ -1,31 +1,30 @@ - -* This file is part of AjaXplorer. -* -* AjaXplorer is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* AjaXplorer is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with AjaXplorer. If not, see . -* -* The latest code can be found at . -*/ -$mess=array( -"1" => "Données de connexion", -"2" => "Hôte", -"3" => "Optionel", -"4" => "Chemin", -"5" => "Protocole", -"6" => "Encodage", -"7" => "Actif", -"8" => "Port", -); -?> \ No newline at end of file + +* This file is part of AjaXplorer. +* +* AjaXplorer is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* AjaXplorer is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with AjaXplorer. If not, see . +* +* The latest code can be found at . +*/ +$mess=array( +"1" => "Données de connexion", +"2" => "Hôte", +"3" => "Optionel", +"4" => "Chemin", +"5" => "Protocole", +"6" => "Encodage", +"7" => "Actif", +"8" => "Port", +); diff --git a/core/src/plugins/auth.ftp/i18n/pt.php b/core/src/plugins/auth.ftp/i18n/pt.php index 68465e04bc..781ecfb8de 100644 --- a/core/src/plugins/auth.ftp/i18n/pt.php +++ b/core/src/plugins/auth.ftp/i18n/pt.php @@ -28,4 +28,3 @@ "7" => "Activo", "8" => "Porta", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.ftp/manifest.xml b/core/src/plugins/auth.ftp/manifest.xml index 340e1ec763..63dba3b692 100644 --- a/core/src/plugins/auth.ftp/manifest.xml +++ b/core/src/plugins/auth.ftp/manifest.xml @@ -33,20 +33,20 @@ actionBarGroup="user"> - + - @@ -94,19 +94,19 @@ AJXP_MESSAGE[ftp_auth.4] AJXP_MESSAGE[ftp_auth.5] - + AJXP_MESSAGE[ftp_auth.6] AJXP_MESSAGE[ftp_auth.7]
    - + ]]> - + - + - \ No newline at end of file + diff --git a/core/src/plugins/auth.ldap/class.ldapAuthDriver.php b/core/src/plugins/auth.ldap/class.ldapAuthDriver.php index ae296bb7a8..4c288aa93e 100644 --- a/core/src/plugins/auth.ldap/class.ldapAuthDriver.php +++ b/core/src/plugins/auth.ldap/class.ldapAuthDriver.php @@ -25,40 +25,41 @@ * @package AjaXplorer_Plugins * @subpackage Auth */ -class ldapAuthDriver extends AbstractAuthDriver { - - var $ldapUrl; - var $ldapPort = 389; - var $ldapAdminUsername; - var $ldapAdminPassword; - var $ldapDN; - var $ldapGDN; - var $ldapFilter; - var $ldapGFilter; - var $dynamicFilter; - var $dynamicExpected; - var $ldapUserAttr; - var $ldapGroupAttr; - - var $ldapconn = null; - var $separateGroup = ""; - - var $hasGroupsMapping = false; +class ldapAuthDriver extends AbstractAuthDriver +{ + public $ldapUrl; + public $ldapPort = 389; + public $ldapAdminUsername; + public $ldapAdminPassword; + public $ldapDN; + public $ldapGDN; + public $ldapFilter; + public $ldapGFilter; + public $dynamicFilter; + public $dynamicExpected; + public $ldapUserAttr; + public $ldapGroupAttr; + + public $ldapconn = null; + public $separateGroup = ""; + + public $hasGroupsMapping = false; /** * Legacy way, defined through PHP array * @var array */ - var $customParamsMapping = array(); + public $customParamsMapping = array(); /** * New way, defined through GUI Options (PARAM_MAPPING replication group). * @var array */ - var $paramsMapping = array(); + public $paramsMapping = array(); - function init($options){ + public function init($options) + { parent::init($options); $options = $this->options; $this->ldapUrl = $options["LDAP_URL"]; @@ -69,25 +70,25 @@ function init($options){ if ($options["LDAP_GDN"]) $this->ldapGDN = $this->parseReplicatedParams($options, array("LDAP_GDN")); if (is_array($options["CUSTOM_DATA_MAPPING"])) $this->customParamsMapping = $options["CUSTOM_DATA_MAPPING"]; $this->paramsMapping = $this->parseReplicatedParams($options, array("MAPPING_LDAP_PARAM", "MAPPING_LOCAL_TYPE", "MAPPING_LOCAL_PARAM")); - if(count($this->paramsMapping)){ - foreach($this->paramsMapping as $param){ - if(strtolower($param["MAPPING_LOCAL_TYPE"]) == "group_path"){ + if (count($this->paramsMapping)) { + foreach ($this->paramsMapping as $param) { + if (strtolower($param["MAPPING_LOCAL_TYPE"]) == "group_path") { $this->hasGroupsMapping = $param["MAPPING_LDAP_PARAM"]; break; } } } - if (!empty($options["LDAP_FILTER"])){ + if (!empty($options["LDAP_FILTER"])) { $this->ldapFilter = $options["LDAP_FILTER"]; if ($this->ldapFilter != "" && !preg_match("/^\(.*\)$/", $this->ldapFilter)) { $this->ldapFilter = "(" . $this->ldapFilter . ")"; } } else { - if($this->hasGroupsMapping && !empty($this->ldapGFilter)){ + if ($this->hasGroupsMapping && !empty($this->ldapGFilter)) { $this->ldapFilter = "!(".$this->ldapGFilter.")"; } } - if (!empty($options["LDAP_GROUP_FILTER"])){ + if (!empty($options["LDAP_GROUP_FILTER"])) { $this->ldapGFilter = $options["LDAP_GROUP_FILTER"]; if ($this->ldapGFilter != "" && !preg_match("/^\(.*\)$/", $this->ldapGFilter)) { $this->ldapGFilter = "(" . $this->ldapGFilter . ")"; @@ -95,33 +96,34 @@ function init($options){ } else { $this->ldapGFilter = "(objectClass=group)"; } - if (!empty($options["LDAP_USERATTR"])){ - $this->ldapUserAttr = strtolower($options["LDAP_USERATTR"]); - }else{ - $this->ldapUserAttr = 'uid' ; - } - if (!empty($options["LDAP_GROUPATTR"])){ - $this->ldapGroupAttr = strtolower($options["LDAP_GROUPATTR"]); - }else{ - $this->ldapGroupAttr = 'cn' ; - } + if (!empty($options["LDAP_USERATTR"])) { + $this->ldapUserAttr = strtolower($options["LDAP_USERATTR"]); + } else { + $this->ldapUserAttr = 'uid' ; + } + if (!empty($options["LDAP_GROUPATTR"])) { + $this->ldapGroupAttr = strtolower($options["LDAP_GROUPATTR"]); + } else { + $this->ldapGroupAttr = 'cn' ; + } } - function parseReplicatedParams($options, $optionsNames){ + public function parseReplicatedParams($options, $optionsNames) + { $i = 0; $data = array(); - while(true){ + while (true) { $ok = true; $occurence = array(); $suffix = ($i==0 ? "" : "_" . $i); - foreach($optionsNames as $name){ - if(!isSet($options[$name.$suffix])) { + foreach ($optionsNames as $name) { + if (!isSet($options[$name.$suffix])) { $ok = false; break; } - if(count($optionsNames) == 1){ + if (count($optionsNames) == 1) { $occurence = $options[$name.$suffix]; - }else{ + } else { $occurence[$name] = $options[$name.$suffix]; } } @@ -132,56 +134,59 @@ function parseReplicatedParams($options, $optionsNames){ return $data; } - public function testLDAPConnexion($options){ - + public function testLDAPConnexion($options) + { $this->ldapUrl = $options["LDAP_URL"]; if ($options["LDAP_PORT"]) $this->ldapPort = $options["LDAP_PORT"]; if ($options["LDAP_USER"]) $this->ldapAdminUsername = $options["LDAP_USER"]; if ($options["LDAP_PASSWORD"]) $this->ldapAdminPassword = $options["LDAP_PASSWORD"]; if ($options["LDAP_DN"]) $this->ldapDN = $this->parseReplicatedParams($options, array("LDAP_DN")); $this->startConnexion(); - if($this->ldapconn == null){ + if ($this->ldapconn == null) { return "ERROR: Cannot connect to the server"; - }else{ - if(!empty($options["TEST_USER"])){ + } else { + if (!empty($options["TEST_USER"])) { $entries = $this->getUserEntries($options["TEST_USER"]); if(!is_array($entries)) return false; - if(AuthService::ignoreUserCase()) { + if (AuthService::ignoreUserCase()) { $res = (strcasecmp($options["TEST_USER"], $entries[0][$this->ldapUserAttr][0]) == 0); - }else { + } else { $res = (strcmp($options["TEST_USER"], $entries[0][$this->ldapUserAttr][0]) == 0 ); } AJXP_Logger::debug('Auth.ldap :: checking if user '.$options["TEST_USER"].' exists : '.$res); - if(!$res){ + if (!$res) { return "ERROR: Could correctly connect to the server, but could not find the specified user in the directory."; - }else{ + } else { return "SUCCESS: Could connect to the server, and could find the specified user inside the directory."; } - }else{ + } else { return "SUCCESS: Correctly connected to the server"; } } } - function startConnexion(){ + public function startConnexion() + { AJXP_Logger::debug('Auth.ldap :: start connexion'); - if($this->ldapconn == null){ + if ($this->ldapconn == null) { $this->ldapconn = $this->LDAP_Connect(); - if($this->ldapconn == null) { + if ($this->ldapconn == null) { AJXP_Logger::logAction('LDAP Server connexion could NOT be established'); } } //return $this->ldapconn; } - function __deconstruct(){ - if($this->ldapconn != null){ + public function __deconstruct() + { + if ($this->ldapconn != null) { ldap_close($this->ldapconn); } } - function LDAP_Connect(){ + public function LDAP_Connect() + { $ldapconn = ldap_connect($this->ldapUrl, $this->ldapPort) or die("Cannot connect to LDAP server"); //@todo : return error_code @@ -191,7 +196,7 @@ function LDAP_Connect(){ //AJXP_Logger::logAction("auth.ldap:We are connected"); ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); - if ($this->ldapAdminUsername === null){ + if ($this->ldapAdminUsername === null) { //connecting anonymously AJXP_Logger::debug('Auth.ldap :: Anonymous LDAP connexion'); $ldapbind = @ldap_bind($ldapconn); @@ -200,14 +205,14 @@ function LDAP_Connect(){ $ldapbind = @ldap_bind($ldapconn, $this->ldapAdminUsername, $this->ldapAdminPassword); } - if ($ldapbind){ + if ($ldapbind) { AJXP_Logger::debug('Auth.ldap :: LDAP connexion OK'); return $ldapconn; } else { AJXP_Logger::debug('Auth.ldap :: LDAP connexion FAILED'); return null; } - + } else { AJXP_Logger::logAction("Error while connection to LDAP server"); } @@ -215,42 +220,43 @@ function LDAP_Connect(){ } - function getUserEntries($login = null, $countOnly = false, $offset = -1, $limit = -1){ - if ($login == null){ + public function getUserEntries($login = null, $countOnly = false, $offset = -1, $limit = -1) + { + if ($login == null) { $filter = $this->ldapFilter; } else { if($this->ldapFilter == "") $filter = "(" . $this->ldapUserAttr . "=" . $login . ")"; else $filter = "(&" . $this->ldapFilter . "(" . $this->ldapUserAttr . "=" . $login . "))"; } - if(empty($filter)){ + if (empty($filter)) { if(!empty($this->dynamicFilter)) $filter = $this->dynamicFilter; else $filter = $this->ldapUserAttr . "=*"; - }else{ + } else { if(!empty($this->dynamicFilter)) $filter = "(&(".$this->dynamicFilter.")".$filter.")"; } - if($this->ldapconn == null){ - $this->startConnexion(); + if ($this->ldapconn == null) { + $this->startConnexion(); } $conn = array(); - if(is_array($this->ldapDN)){ - foreach($this->ldapDN as $dn){ + if (is_array($this->ldapDN)) { + foreach ($this->ldapDN as $dn) { $conn[] = $this->ldapconn; } - }else{ + } else { $conn = array($this->ldapconn); } $expected = array($this->ldapUserAttr); - if($login != null && (!empty($this->customParamsMapping) || !empty($this->paramsMapping))){ - if(!empty($this->customParamsMapping)){ + if ($login != null && (!empty($this->customParamsMapping) || !empty($this->paramsMapping))) { + if (!empty($this->customParamsMapping)) { $expected = array_merge($expected, array_keys($this->customParamsMapping)); } - if(!empty($this->paramsMapping)){ + if (!empty($this->paramsMapping)) { $keys = array(); foreach($this->paramsMapping as $param) $keys[] = $param["MAPPING_LDAP_PARAM"]; $expected = array_merge($expected, $keys); } } - if(is_array($this->dynamicExpected)){ + if (is_array($this->dynamicExpected)) { $expected = array_merge($expected, $this->dynamicExpected); } foreach ($conn as $dn => $ldapc) { @@ -263,19 +269,19 @@ function getUserEntries($login = null, $countOnly = false, $offset = -1, $limit } $ret = ldap_search($conn,$this->ldapDN,$filter, $expected); $allEntries = array("count" => 0); - foreach($ret as $i => $resourceResult){ + foreach ($ret as $i => $resourceResult) { if($resourceResult === false) continue; - if($countOnly){ + if ($countOnly) { $allEntries["count"] += ldap_count_entries($conn[$i], $resourceResult); continue; } $entries = ldap_get_entries($conn[$i], $resourceResult); $index = 0; - if(!empty($entries["count"])){ + if (!empty($entries["count"])) { $allEntries["count"] += $entries["count"]; unset($entries["count"]); - foreach($entries as $entry){ - if($offset != -1 && $index < $offset){ + foreach ($entries as $entry) { + if ($offset != -1 && $index < $offset) { $index ++; continue; } $allEntries[] = $entry; @@ -287,19 +293,20 @@ function getUserEntries($login = null, $countOnly = false, $offset = -1, $limit return $allEntries; } - function supportsUsersPagination(){ + public function supportsUsersPagination() + { return true; } - function listUsersPaginated($baseGroup="/", $regexp, $offset, $limit){ - - if($this->hasGroupsMapping !== false){ - if($baseGroup == "/"){ + public function listUsersPaginated($baseGroup="/", $regexp, $offset, $limit) + { + if ($this->hasGroupsMapping !== false) { + if ($baseGroup == "/") { $this->dynamicFilter = "!(".$this->hasGroupsMapping."=*)"; - }else{ + } else { $this->dynamicFilter = $this->hasGroupsMapping."=".ltrim($baseGroup, "/"); } - }else if(!empty($this->separateGroup) && $baseGroup != "/".$this->separateGroup) { + } else if (!empty($this->separateGroup) && $baseGroup != "/".$this->separateGroup) { return array(); } @@ -310,16 +317,17 @@ function listUsersPaginated($baseGroup="/", $regexp, $offset, $limit){ $this->dynamicFilter = null; $persons = array(); unset($entries['count']); // remove 'count' entry - foreach($entries as $id => $person){ + foreach ($entries as $id => $person) { $login = $person[$this->ldapUserAttr][0]; if(AuthService::ignoreUserCase()) $login = strtolower($login); $persons[$login] = "XXX"; } return $persons; } - function getUsersCount($baseGroup = "/", $regexp = ""){ + public function getUsersCount($baseGroup = "/", $regexp = "") + { $re = null; - if(!empty($regexp)){ + if (!empty($regexp)) { if($regexp[0]=="^") $re = ltrim($regexp, "^")."*"; else if($regexp[strlen($regexp)-1] == "$") $re = "*".rtrim($regexp, "$"); } @@ -334,13 +342,14 @@ function getUsersCount($baseGroup = "/", $regexp = ""){ * @param string $baseGroup * @return string[] */ - function listChildrenGroups($baseGroup = "/"){ + public function listChildrenGroups($baseGroup = "/") + { $arr = array(); - if($baseGroup == "/" && !empty($this->separateGroup)) { + if ($baseGroup == "/" && !empty($this->separateGroup)) { $arr[$this->separateGroup] = "LDAP Annuary"; return $arr; } - if($this->hasGroupsMapping){ + if ($this->hasGroupsMapping) { $origUsersDN = $this->ldapDN; $origUsersFilter = $this->ldapFilter; $origUsersAttr = $this->ldapUserAttr; @@ -348,9 +357,9 @@ function listChildrenGroups($baseGroup = "/"){ $this->ldapFilter = $this->ldapGFilter; $this->ldapUserAttr = $this->ldapGroupAttr; - if($baseGroup != "/"){ + if ($baseGroup != "/") { $this->dynamicFilter = $this->hasGroupsMapping."=".ltrim($baseGroup, "/"); - }else{ + } else { //STRANGE, SHOULD WORK BUT CAN EXCLUDES ALL GROUPS $this->dynamicFilter = "!(".$this->hasGroupsMapping."=*)"; } @@ -359,7 +368,7 @@ function listChildrenGroups($baseGroup = "/"){ $this->dynamicFilter = null; $persons = array(); unset($entries['count']); // remove 'count' entry - foreach($entries as $id => $person){ + foreach ($entries as $id => $person) { $login = $person[$this->ldapUserAttr][0]; //if(AuthService::ignoreUserCase()) $login = strtolower($login); $persons[$person["dn"]] = $login; @@ -367,7 +376,7 @@ function listChildrenGroups($baseGroup = "/"){ $branch = array(); $this->buildGroupBranch($login, $branch); $parent = "/"; - if(count($branch)){ + if (count($branch)) { $parent = "/".implode("/", array_reverse($branch)); } AuthService::createGroup($parent, $person["dn"], $login); @@ -383,14 +392,15 @@ function listChildrenGroups($baseGroup = "/"){ } - function listUsers($baseGroup = "/"){ - if($this->hasGroupsMapping !== false){ - if($baseGroup == "/"){ + public function listUsers($baseGroup = "/") + { + if ($this->hasGroupsMapping !== false) { + if ($baseGroup == "/") { $this->dynamicFilter = $this->hasGroupsMapping."="; - }else{ + } else { $this->dynamicFilter = $this->hasGroupsMapping."=".array_pop(explode("/", $baseGroup)); } - }else if(!empty($this->separateGroup) && $baseGroup != "/".$this->separateGroup) { + } else if (!empty($this->separateGroup) && $baseGroup != "/".$this->separateGroup) { return array(); } @@ -398,7 +408,7 @@ function listUsers($baseGroup = "/"){ $this->dynamicFilter = null; $persons = array(); unset($entries['count']); // remove 'count' entry - foreach($entries as $id => $person){ + foreach ($entries as $id => $person) { $login = $person[$this->ldapUserAttr][0]; if(AuthService::ignoreUserCase()) $login = strtolower($login); $persons[$login] = "XXX"; @@ -406,28 +416,29 @@ function listUsers($baseGroup = "/"){ return $persons; } - function userExists($login){ - // Check if local storage exists for the user. If it does, assume the user - // exists. This prevents a barrage of ldap_connect/ldap_bind/ldap_search - // calls. - $confDriver = ConfService::getConfStorageImpl(); - $userObject = $confDriver->instantiateAbstractUserImpl($login); - if ($userObject->storageExists()) { - //return true; - } + public function userExists($login) + { + // Check if local storage exists for the user. If it does, assume the user + // exists. This prevents a barrage of ldap_connect/ldap_bind/ldap_search + // calls. + $confDriver = ConfService::getConfStorageImpl(); + $userObject = $confDriver->instantiateAbstractUserImpl($login); + if ($userObject->storageExists()) { + //return true; + } $entries = $this->getUserEntries($login); if(!is_array($entries)) return false; - if(AuthService::ignoreUserCase()) { + if (AuthService::ignoreUserCase()) { $res = (strcasecmp($login, $entries[0][$this->ldapUserAttr][0]) == 0); - }else { + } else { $res = (strcmp($login, $entries[0][$this->ldapUserAttr][0]) == 0 ); } AJXP_Logger::debug('Auth.ldap :: checking if user '.$login.' exists : '.$res); return $res; } - function checkPassword($login, $pass, $seed){ - + public function checkPassword($login, $pass, $seed) + { if(empty($pass)) return false; $entries = $this->getUserEntries($login); if ($entries['count']>0) { @@ -444,14 +455,17 @@ function checkPassword($login, $pass, $seed){ } } - function usersEditable(){ + public function usersEditable() + { return false; } - function passwordsEditable(){ + public function passwordsEditable() + { return false; } - function buildGroupBranch($groupAttrValue, &$branch = array()){ + public function buildGroupBranch($groupAttrValue, &$branch = array()) + { // Load group data. Detect memberOf. Load parent group. $origUsersDN = $this->ldapDN; $origUsersFilter = $this->ldapFilter; @@ -476,13 +490,13 @@ function buildGroupBranch($groupAttrValue, &$branch = array()){ $this->ldapFilter = $origUsersFilter; $this->ldapUserAttr = $origUsersAttr; - if(!empty($memberOf)){ + if (!empty($memberOf)) { $parts = explode(",", ltrim($memberOf, '/')); - foreach($parts as $part){ + foreach ($parts as $part) { list($att,$attVal) = explode("=", $part); if(strtolower($att) == "cn") $parentCN = $attVal; } - if(!empty($parentCN)){ + if (!empty($parentCN)) { $branch[] = $memberOf; $this->buildGroupBranch($parentCN, $branch); } @@ -492,65 +506,66 @@ function buildGroupBranch($groupAttrValue, &$branch = array()){ } - function updateUserObject(&$userObject){ + public function updateUserObject(&$userObject) + { if(!empty($this->separateGroup)) $userObject->setGroupPath("/".$this->separateGroup); // SHOULD BE DEPRECATED - if(!empty($this->customParamsMapping)){ + if (!empty($this->customParamsMapping)) { $checkValues = array_values($this->customParamsMapping); $prefs = $userObject->getPref("CUSTOM_PARAMS"); - if(!is_array($prefs)) { + if (!is_array($prefs)) { $prefs = array(); } // If one value exist, we consider the mapping has already been done. - foreach($checkValues as $val){ + foreach ($checkValues as $val) { if(array_key_exists($val, $prefs)) return; } $changes = false; $entries = $this->getUserEntries($userObject->getId()); - if($entries["count"]){ + if ($entries["count"]) { $entry = $entries[0]; - foreach($this->customParamsMapping as $key => $value){ - if(isSet($entry[$key])){ + foreach ($this->customParamsMapping as $key => $value) { + if (isSet($entry[$key])) { $prefs[$value] = $entry[$key][0]; $changes = true; } } } - if($changes){ + if ($changes) { $userObject->setPref("CUSTOM_PARAMS", $prefs); $userObject->save(); } } - if(!empty($this->paramsMapping)){ + if (!empty($this->paramsMapping)) { $changes = false; $entries = $this->getUserEntries($userObject->getId()); - if($entries["count"]){ + if ($entries["count"]) { $entry = $entries[0]; - foreach($this->paramsMapping as $params){ + foreach ($this->paramsMapping as $params) { $key = strtolower($params['MAPPING_LDAP_PARAM']); - if(isSet($entry[$key])){ + if (isSet($entry[$key])) { $value = $entry[$key][0]; - if($key == "memberof"){ + if ($key == "memberof") { $memberValues = array(); // get CN from value - foreach($entry[$key] as $possibleValue){ + foreach ($entry[$key] as $possibleValue) { $hnParts = array(); $parts = explode(",", ltrim($possibleValue, '/')); - foreach($parts as $part){ + foreach ($parts as $part) { list($att,$attVal) = explode("=", $part); if(strtolower($att) == "cn") $hnParts[] = $attVal; } - if(count($hnParts)) { + if (count($hnParts)) { $memberValues[implode(",", $hnParts)] = $possibleValue; } } } - switch($params['MAPPING_LOCAL_TYPE']){ + switch ($params['MAPPING_LOCAL_TYPE']) { case "role_id": - if($key == "memberof"){ - foreach($memberValues as $uniqValue => $fullDN){ - if(!in_array($uniqValue, array_keys($userObject->getRoles()))){ + if ($key == "memberof") { + foreach ($memberValues as $uniqValue => $fullDN) { + if (!in_array($uniqValue, array_keys($userObject->getRoles()))) { $userObject->addRole(AuthService::getRole($uniqValue, true)); $userObject->recomputeMergedRole(); $changes = true; @@ -559,24 +574,24 @@ function updateUserObject(&$userObject){ } break; case "group_path": - if($key == "memberof"){ + if ($key == "memberof") { $filter = $params["MAPPING_LOCAL_PARAM"]; - if(strpos($filter, "preg:") !== false){ + if (strpos($filter, "preg:") !== false) { $matchFilter = "/".str_replace("preg:", "", $filter)."/i"; - }else{ + } else { $valueFilters = array_map("trim", explode(",", $filter)); } - foreach($memberValues as $uniqValue => $fullDN){ + foreach ($memberValues as $uniqValue => $fullDN) { if(isSet($matchFilter) && !preg_match($matchFilter, $uniqValue)) continue; if(isSet($valueFilters) && !in_array($uniqValue, $matchFilter)) continue; - if($userObject->personalRole->filterParameterValue("auth.ldap", "MEMBER_OF", AJXP_REPO_SCOPE_ALL, "") == $fullDN){ - break; + if ($userObject->personalRole->filterParameterValue("auth.ldap", "MEMBER_OF", AJXP_REPO_SCOPE_ALL, "") == $fullDN) { + //break; } $humanName = $uniqValue; $branch = array(); $this->buildGroupBranch($uniqValue, $branch); $parent = "/"; - if(count($branch)){ + if (count($branch)) { $parent = "/".implode("/", array_reverse($branch)); } AuthService::createGroup($parent, $fullDN, $humanName); @@ -584,7 +599,7 @@ function updateUserObject(&$userObject){ // Update Roles from groupPath $b = array_reverse($branch); $b[] = $fullDN; - for($i=1;$i<=count($b);$i++){ + for ($i=1;$i<=count($b);$i++) { $userObject->addRole(AuthService::getRole("AJXP_GRP_/".implode("/", array_slice($b, 0, $i)), true)); } $userObject->personalRole->setParameterValue("auth.ldap", "MEMBER_OF", $fullDN); @@ -594,7 +609,7 @@ function updateUserObject(&$userObject){ } break; case "profile": - if($userObject->getProfile() != $value){ + if ($userObject->getProfile() != $value) { $changes = true; $userObject->setProfile($value); AuthService::updateAutoApplyRole($userObject); @@ -602,13 +617,13 @@ function updateUserObject(&$userObject){ break; case "plugin_param": default: - if(strpos($params["MAPPING_LOCAL_PARAM"], "/") !== false){ + if (strpos($params["MAPPING_LOCAL_PARAM"], "/") !== false) { list($pId, $param) = explode("/", $params["MAPPING_LOCAL_PARAM"]); - }else{ + } else { $pId = $this->getId(); $param = $params["MAPPING_LOCAL_PARAM"]; } - if($userObject->personalRole->filterParameterValue($pId, $param, AJXP_REPO_SCOPE_ALL, "") != $value){ + if ($userObject->personalRole->filterParameterValue($pId, $param, AJXP_REPO_SCOPE_ALL, "") != $value) { $userObject->personalRole->setParameterValue($pId, $param, $value); $userObject->recomputeMergedRole(); $changes = true; @@ -618,7 +633,7 @@ function updateUserObject(&$userObject){ } } } - if($changes){ + if ($changes) { $userObject->save("superuser"); } diff --git a/core/src/plugins/auth.ldap/i18n/conf/en.php b/core/src/plugins/auth.ldap/i18n/conf/en.php index c7b7ae4ce8..bf664f41b4 100644 --- a/core/src/plugins/auth.ldap/i18n/conf/en.php +++ b/core/src/plugins/auth.ldap/i18n/conf/en.php @@ -36,4 +36,3 @@ "User attribute" => "User attribute", "Username attribute" => "Username attribute", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.ldap/i18n/conf/fr.php b/core/src/plugins/auth.ldap/i18n/conf/fr.php index 19bdbcf601..98e79f05ae 100644 --- a/core/src/plugins/auth.ldap/i18n/conf/fr.php +++ b/core/src/plugins/auth.ldap/i18n/conf/fr.php @@ -36,4 +36,3 @@ "User attribute" => "User attribute", "Username attribute" => "Username attribute", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.ldap/i18n/conf/pt.php b/core/src/plugins/auth.ldap/i18n/conf/pt.php index 16d00a3da3..21824f74b6 100644 --- a/core/src/plugins/auth.ldap/i18n/conf/pt.php +++ b/core/src/plugins/auth.ldap/i18n/conf/pt.php @@ -36,4 +36,3 @@ "User attribute" => "Atributo de Utilizador", "Username attribute" => "Atributo de Login", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.ldap/manifest.xml b/core/src/plugins/auth.ldap/manifest.xml index 761be20496..daccc48f65 100644 --- a/core/src/plugins/auth.ldap/manifest.xml +++ b/core/src/plugins/auth.ldap/manifest.xml @@ -29,4 +29,4 @@ - \ No newline at end of file + diff --git a/core/src/plugins/auth.multi/class.multiAuthDriver.php b/core/src/plugins/auth.multi/class.multiAuthDriver.php index 6c31545859..43f37ff550 100644 --- a/core/src/plugins/auth.multi/class.multiAuthDriver.php +++ b/core/src/plugins/auth.multi/class.multiAuthDriver.php @@ -25,193 +25,209 @@ * @package AjaXplorer_Plugins * @subpackage Auth */ -class multiAuthDriver extends AbstractAuthDriver { - - var $driverName = "multi"; - var $driversDef = array(); - var $currentDriver; - - var $masterSlaveMode = false; - var $masterName; - var $slaveName; - var $baseName; - - static $schemesCache = null; - - /** - * @var $drivers AbstractAuthDriver[] - */ - var $drivers = array(); - - public function init($options){ - //parent::init($options); - $this->options = $options; - $this->driversDef = $this->getOption("DRIVERS"); +class multiAuthDriver extends AbstractAuthDriver +{ + public $driverName = "multi"; + public $driversDef = array(); + public $currentDriver; + + public $masterSlaveMode = false; + public $masterName; + public $slaveName; + public $baseName; + + public static $schemesCache = null; + + /** + * @var $drivers AbstractAuthDriver[] + */ + public $drivers = array(); + + public function init($options) + { + //parent::init($options); + $this->options = $options; + $this->driversDef = $this->getOption("DRIVERS"); $this->masterSlaveMode = ($this->getOption("MODE") == "MASTER_SLAVE"); $this->masterName = $this->getOption("MASTER_DRIVER"); $this->baseName = $this->getOption("USER_BASE_DRIVER"); - foreach($this->driversDef as $def){ - $name = $def["NAME"]; - $options = $def["OPTIONS"]; - $options["TRANSMIT_CLEAR_PASS"] = $this->options["TRANSMIT_CLEAR_PASS"]; - $options["LOGIN_REDIRECT"] = $this->options["LOGIN_REDIRECT"]; - $instance = AJXP_PluginsService::findPlugin("auth", $name); - if(!is_object($instance)){ - throw new Exception("Cannot find plugin $name for type 'auth'"); - } - $instance->init($options); - if($name != $this->getOption("MASTER_DRIVER")){ + foreach ($this->driversDef as $def) { + $name = $def["NAME"]; + $options = $def["OPTIONS"]; + $options["TRANSMIT_CLEAR_PASS"] = $this->options["TRANSMIT_CLEAR_PASS"]; + $options["LOGIN_REDIRECT"] = $this->options["LOGIN_REDIRECT"]; + $instance = AJXP_PluginsService::findPlugin("auth", $name); + if (!is_object($instance)) { + throw new Exception("Cannot find plugin $name for type 'auth'"); + } + $instance->init($options); + if ($name != $this->getOption("MASTER_DRIVER")) { $this->slaveName = $name; } - $this->drivers[$name] = $instance; - } - // THE "LOAD REGISTRY CONTRIBUTIONS" METHOD - // WILL BE CALLED LATER, TO BE SURE THAT THE - // SESSION IS ALREADY STARTED. - } - - public function getRegistryContributions( $extendedVersion = true ){ - // AJXP_Logger::debug("get contributions NOW"); - $this->loadRegistryContributions(); - return parent::getRegistryContributions( $extendedVersion ); - } - - private function detectCurrentDriver(){ - //if(isSet($this->currentDriver)) return; - $authSource = $this->getOption("MASTER_DRIVER"); - if(isSet($_POST["auth_source"])){ - $_SESSION["AJXP_MULTIAUTH_SOURCE"] = $_POST["auth_source"]; - $authSource = $_POST["auth_source"]; - AJXP_Logger::debug("Auth source from POST"); - }else if(isSet($_SESSION["AJXP_MULTIAUTH_SOURCE"])){ - $authSource = $_SESSION["AJXP_MULTIAUTH_SOURCE"]; - AJXP_Logger::debug("Auth source from SESSION"); - }else { - AJXP_Logger::debug("Auth source from MASTER"); - } - $this->setCurrentDriverName($authSource); - } - - protected function parseSpecificContributions(&$contribNode){ - parent::parseSpecificContributions($contribNode); + $this->drivers[$name] = $instance; + } + // THE "LOAD REGISTRY CONTRIBUTIONS" METHOD + // WILL BE CALLED LATER, TO BE SURE THAT THE + // SESSION IS ALREADY STARTED. + } + + public function getRegistryContributions( $extendedVersion = true ) + { + // AJXP_Logger::debug("get contributions NOW"); + $this->loadRegistryContributions(); + return parent::getRegistryContributions( $extendedVersion ); + } + + private function detectCurrentDriver() + { + //if(isSet($this->currentDriver)) return; + $authSource = $this->getOption("MASTER_DRIVER"); + if (isSet($_POST["auth_source"])) { + $_SESSION["AJXP_MULTIAUTH_SOURCE"] = $_POST["auth_source"]; + $authSource = $_POST["auth_source"]; + AJXP_Logger::debug("Auth source from POST"); + } else if (isSet($_SESSION["AJXP_MULTIAUTH_SOURCE"])) { + $authSource = $_SESSION["AJXP_MULTIAUTH_SOURCE"]; + AJXP_Logger::debug("Auth source from SESSION"); + } else { + AJXP_Logger::debug("Auth source from MASTER"); + } + $this->setCurrentDriverName($authSource); + } + + protected function parseSpecificContributions(&$contribNode) + { + parent::parseSpecificContributions($contribNode); if($this->masterSlaveMode) return; - if($contribNode->nodeName != "actions") return ; - // Replace callback code - $actionXpath=new DOMXPath($contribNode->ownerDocument); - $loginCallbackNodeList = $actionXpath->query('action[@name="login"]/processing/clientCallback', $contribNode); - if(!$loginCallbackNodeList->length) return ; - $xmlContent = file_get_contents(AJXP_INSTALL_PATH."/plugins/auth.multi/login_patch.xml"); - $sources = array(); - foreach($this->getOption("DRIVERS") as $driverDef){ - $dName = $driverDef["NAME"]; - if(isSet($driverDef["LABEL"])){ - $dLabel = $driverDef["LABEL"]; - }else{ - $dLabel = $driverDef["NAME"]; - } - $sources[$dName] = $dLabel; - } - $xmlContent = str_replace("AJXP_MULTIAUTH_SOURCES", json_encode($sources), $xmlContent); - $xmlContent = str_replace("AJXP_MULTIAUTH_MASTER", $this->getOption("MASTER_DRIVER"), $xmlContent); - $xmlContent = str_replace("AJXP_USER_ID_SEPARATOR", $this->getOption("USER_ID_SEPARATOR"), $xmlContent); + if($contribNode->nodeName != "actions") return ; + // Replace callback code + $actionXpath=new DOMXPath($contribNode->ownerDocument); + $loginCallbackNodeList = $actionXpath->query('action[@name="login"]/processing/clientCallback', $contribNode); + if(!$loginCallbackNodeList->length) return ; + $xmlContent = file_get_contents(AJXP_INSTALL_PATH."/plugins/auth.multi/login_patch.xml"); + $sources = array(); + foreach ($this->getOption("DRIVERS") as $driverDef) { + $dName = $driverDef["NAME"]; + if (isSet($driverDef["LABEL"])) { + $dLabel = $driverDef["LABEL"]; + } else { + $dLabel = $driverDef["NAME"]; + } + $sources[$dName] = $dLabel; + } + $xmlContent = str_replace("AJXP_MULTIAUTH_SOURCES", json_encode($sources), $xmlContent); + $xmlContent = str_replace("AJXP_MULTIAUTH_MASTER", $this->getOption("MASTER_DRIVER"), $xmlContent); + $xmlContent = str_replace("AJXP_USER_ID_SEPARATOR", $this->getOption("USER_ID_SEPARATOR"), $xmlContent); $patchDoc = new DOMDocument(); $patchDoc->loadXML($xmlContent); - $patchNode = $patchDoc->documentElement; - $imported = $contribNode->ownerDocument->importNode($patchNode, true); - $loginCallback = $loginCallbackNodeList->item(0); - $loginCallback->parentNode->replaceChild($imported, $loginCallback); - //var_dump($contribNode->ownerDocument->saveXML($contribNode)); - } - - protected function setCurrentDriverName($name){ - $this->currentDriver = $name; - } - - protected function getCurrentDriver(){ - $this->detectCurrentDriver(); - if(isSet($this->currentDriver) && isSet($this->drivers[$this->currentDriver])){ - return $this->drivers[$this->currentDriver]; - }else{ - return false; - } - } - - protected function extractRealId($userId){ - $parts = explode($this->getOption("USER_ID_SEPARATOR"), $userId); - if(count($parts) == 2){ - return $parts[1]; - } - return $userId; - } - - public function performChecks(){ - foreach($this->drivers as $driver){ - $driver->performChecks(); - } - } - - function getAuthScheme($login){ - if(!isSet(multiAuthDriver::$schemesCache)){ - foreach($this->drivers as $scheme => $d){ + $patchNode = $patchDoc->documentElement; + $imported = $contribNode->ownerDocument->importNode($patchNode, true); + $loginCallback = $loginCallbackNodeList->item(0); + $loginCallback->parentNode->replaceChild($imported, $loginCallback); + //var_dump($contribNode->ownerDocument->saveXML($contribNode)); + } + + protected function setCurrentDriverName($name) + { + $this->currentDriver = $name; + } + + protected function getCurrentDriver() + { + $this->detectCurrentDriver(); + if (isSet($this->currentDriver) && isSet($this->drivers[$this->currentDriver])) { + return $this->drivers[$this->currentDriver]; + } else { + return false; + } + } + + protected function extractRealId($userId) + { + $parts = explode($this->getOption("USER_ID_SEPARATOR"), $userId); + if (count($parts) == 2) { + return $parts[1]; + } + return $userId; + } + + public function performChecks() + { + foreach ($this->drivers as $driver) { + $driver->performChecks(); + } + } + + public function getAuthScheme($login) + { + if (!isSet(multiAuthDriver::$schemesCache)) { + foreach ($this->drivers as $scheme => $d) { if($d->userExists($login)) return $scheme; } - } else if(isSet(multiAuthDriver::$schemesCache[$login])){ + } else if (isSet(multiAuthDriver::$schemesCache[$login])) { return multiAuthDriver::$schemesCache[$login]; } return null; } - function supportsAuthSchemes(){ + public function supportsAuthSchemes() + { return true; } - function addToCache($usersList, $scheme){ - if(!isset(multiAuthDriver::$schemesCache)){ + public function addToCache($usersList, $scheme) + { + if (!isset(multiAuthDriver::$schemesCache)) { multiAuthDriver::$schemesCache = array(); } - foreach($usersList as $userName){ + foreach ($usersList as $userName) { multiAuthDriver::$schemesCache[$userName] = $scheme; } } - function supportsUsersPagination(){ - if(!empty($this->baseName)){ + public function supportsUsersPagination() + { + if (!empty($this->baseName)) { return $this->drivers[$this->baseName]->supportsUsersPagination(); - }else{ + } else { return $this->drivers[$this->masterName]->supportsUsersPagination() && $this->drivers[$this->slaveName]->supportsUsersPagination(); } } - function listUsersPaginated($baseGroup="/", $regexp, $offset, $limit){ - if(!empty($this->baseName)){ + public function listUsersPaginated($baseGroup="/", $regexp, $offset, $limit) + { + if (!empty($this->baseName)) { return $this->drivers[$this->baseName]->listUsersPaginated($baseGroup, $regexp, $offset, $limit); - }else{ + } else { $keys = array_keys($this->drivers); return $this->drivers[$keys[0]]->listUsersPaginated($baseGroup, $regexp, $offset, $limit) + $this->drivers[$keys[1]]->listUsersPaginated($baseGroup, $regexp, $offset, $limit); } } - function getUsersCount($baseGroup = "/", $regexp = ""){ - if(empty($this->baseName)){ - if($this->masterSlaveMode){ + public function getUsersCount($baseGroup = "/", $regexp = "") + { + if (empty($this->baseName)) { + if ($this->masterSlaveMode) { return $this->drivers[$this->slaveName]->getUsersCount($baseGroup, $regexp) + $this->drivers[$this->masterName]->getUsersCount($baseGroup, $regexp); - }else{ + } else { $keys = array_keys($this->drivers); return $this->drivers[$keys[0]]->getUsersCount($baseGroup, $regexp) + $this->drivers[$keys[1]]->getUsersCount($baseGroup, $regexp); } - }else{ + } else { return $this->drivers[$this->baseName]->getUsersCount($baseGroup, $regexp); } } - function isAjxpAdmin($login){ + public function isAjxpAdmin($login) + { $keys = array_keys($this->drivers); return ($this->drivers[$keys[0]]->getOption("AJXP_ADMIN_LOGIN") === $login) || ($this->drivers[$keys[1]]->getOption("AJXP_ADMIN_LOGIN") === $login); } - function listUsers($baseGroup="/"){ - if($this->masterSlaveMode){ - if(!empty($this->baseName)) { + public function listUsers($baseGroup="/") + { + if ($this->masterSlaveMode) { + if (!empty($this->baseName)) { $users = $this->drivers[$this->baseName]->listUsers($baseGroup); $this->addToCache(array_keys($users), $this->baseName); return $users; @@ -222,28 +238,29 @@ function listUsers($baseGroup="/"){ $this->addToCache(array_keys($slaveUsers), $this->masterName); return array_merge($masterUsers, $slaveUsers); } - if($this->getCurrentDriver()){ + if ($this->getCurrentDriver()) { // return $this->getCurrentDriver()->listUsers($baseGroup); - } - $allUsers = array(); - foreach($this->drivers as $driver){ - $allUsers = array_merge($allUsers, $driver->listUsers($baseGroup)); - } - return $allUsers; - } - - function updateUserObject(&$userObject){ + } + $allUsers = array(); + foreach ($this->drivers as $driver) { + $allUsers = array_merge($allUsers, $driver->listUsers($baseGroup)); + } + return $allUsers; + } + + public function updateUserObject(&$userObject) + { $s = $this->getAuthScheme($userObject->getId()); - if(!$this->masterSlaveMode){ + if (!$this->masterSlaveMode) { $test = $this->extractRealId($userObject->getId()); - if($test != $userObject->getId()) { + if ($test != $userObject->getId()) { $restore = $userObject->getId(); $userObject->setId($test); } } - if(!empty($s) && isSet($this->drivers[$s])){ + if (!empty($s) && isSet($this->drivers[$s])) { $this->drivers[$s]->updateUserObject($userObject); - }else if(!empty($this->currentDriver) && isSet($this->drivers[$this->currentDriver])){ + } else if (!empty($this->currentDriver) && isSet($this->drivers[$this->currentDriver])) { $this->drivers[$this->currentDriver]->updateUserObject($userObject); } if(isSet($restore)) $userObject->setId($restore); @@ -255,174 +272,185 @@ function updateUserObject(&$userObject){ * @param string $baseGroup * @return string[] */ - function listChildrenGroups($baseGroup = "/"){ - if($this->masterSlaveMode){ + public function listChildrenGroups($baseGroup = "/") + { + if ($this->masterSlaveMode) { if(!empty($this->baseName)) return $this->drivers[$this->baseName]->listChildrenGroups($baseGroup); $aGroups = $this->drivers[$this->masterName]->listChildrenGroups($baseGroup); $bGroups = $this->drivers[$this->slaveName]->listChildrenGroups($baseGroup); return $aGroups + $bGroups; } - if($this->getCurrentDriver()){ + if ($this->getCurrentDriver()) { // return $this->drivers[$this->currentDriver]->listChildrenGroups($baseGroup); } $groups = array(); - foreach($this->drivers as $d){ + foreach ($this->drivers as $d) { $groups = array_merge($groups, $d->listChildrenGroups($baseGroup)); } return $groups; } - function preLogUser($remoteSessionId){ - if($this->masterSlaveMode){ + public function preLogUser($remoteSessionId) + { + if ($this->masterSlaveMode) { $this->drivers[$this->slaveName]->preLogUser($remoteSessionId); - if(AuthService::getLoggedUser() == null){ + if (AuthService::getLoggedUser() == null) { return $this->drivers[$this->masterName]->preLogUser($remoteSessionId); } return; } - if($this->getCurrentDriver()){ - return $this->getCurrentDriver()->preLogUser($remoteSessionId); - }else{ - throw new Exception("No driver instanciated in multi driver!"); - } - } + if ($this->getCurrentDriver()) { + return $this->getCurrentDriver()->preLogUser($remoteSessionId); + } else { + throw new Exception("No driver instanciated in multi driver!"); + } + } - function userExistsWrite($login){ - if($this->masterSlaveMode){ - if($this->drivers[$this->slaveName]->userExists($login)){ + public function userExistsWrite($login) + { + if ($this->masterSlaveMode) { + if ($this->drivers[$this->slaveName]->userExists($login)) { return true; } return false; - }else{ + } else { return $this->userExists($login); } } - function userExists($login){ - if($this->masterSlaveMode){ - if($this->drivers[$this->slaveName]->userExists($login)){ + public function userExists($login) + { + if ($this->masterSlaveMode) { + if ($this->drivers[$this->slaveName]->userExists($login)) { return true; } - if($this->drivers[$this->masterName]->userExists($login)){ + if ($this->drivers[$this->masterName]->userExists($login)) { return true; } return false; } - $login = $this->extractRealId($login); - AJXP_Logger::debug("user exists ".$login); - if($this->getCurrentDriver()){ - return $this->getCurrentDriver()->userExists($login); - }else{ - throw new Exception("No driver instanciated in multi driver!"); - } - } - - function checkPassword($login, $pass, $seed){ - if($this->masterSlaveMode){ - if($this->drivers[$this->masterName]->userExists($login)){ + $login = $this->extractRealId($login); + AJXP_Logger::debug("user exists ".$login); + if ($this->getCurrentDriver()) { + return $this->getCurrentDriver()->userExists($login); + } else { + throw new Exception("No driver instanciated in multi driver!"); + } + } + + public function checkPassword($login, $pass, $seed) + { + if ($this->masterSlaveMode) { + if ($this->drivers[$this->masterName]->userExists($login)) { // check master, and refresh slave if necessary - if($this->drivers[$this->masterName]->checkPassword($login, $pass, $seed)){ - if($this->drivers[$this->slaveName]->userExists($login)){ + if ($this->drivers[$this->masterName]->checkPassword($login, $pass, $seed)) { + if ($this->drivers[$this->slaveName]->userExists($login)) { $this->drivers[$this->slaveName]->changePassword($login, $pass); - }else{ + } else { $this->drivers[$this->slaveName]->createUser($login, $pass); } return true; - }else{ + } else { return false; } - }else{ + } else { $res = $this->drivers[$this->slaveName]->checkPassword($login, $pass, $seed); return $res; } } - $login = $this->extractRealId($login); - AJXP_Logger::debug("check pass ".$login); - if($this->getCurrentDriver()){ - return $this->getCurrentDriver()->checkPassword($login, $pass, $seed); - }else{ - throw new Exception("No driver instanciated in multi driver!"); - } - } - - function usersEditable(){ + $login = $this->extractRealId($login); + AJXP_Logger::debug("check pass ".$login); + if ($this->getCurrentDriver()) { + return $this->getCurrentDriver()->checkPassword($login, $pass, $seed); + } else { + throw new Exception("No driver instanciated in multi driver!"); + } + } + + public function usersEditable() + { if($this->masterSlaveMode) return true; - if($this->getCurrentDriver()){ - return $this->getCurrentDriver()->usersEditable(); - }else{ - throw new Exception("No driver instanciated in multi driver!"); - } - } - - function passwordsEditable(){ + if ($this->getCurrentDriver()) { + return $this->getCurrentDriver()->usersEditable(); + } else { + throw new Exception("No driver instanciated in multi driver!"); + } + } + + public function passwordsEditable() + { if($this->masterSlaveMode) return true; - if($this->getCurrentDriver()){ - return $this->getCurrentDriver()->passwordsEditable(); - }else{ - //throw new Exception("No driver instanciated in multi driver!"); - AJXP_Logger::debug("passEditable no current driver set??"); - return false; - } - } - - function createUser($login, $passwd){ - if($this->masterSlaveMode){ + if ($this->getCurrentDriver()) { + return $this->getCurrentDriver()->passwordsEditable(); + } else { + //throw new Exception("No driver instanciated in multi driver!"); + AJXP_Logger::debug("passEditable no current driver set??"); + return false; + } + } + + public function createUser($login, $passwd) + { + if ($this->masterSlaveMode) { return $this->drivers[$this->slaveName]->createUser($login, $passwd); } - $login = $this->extractRealId($login); - if($this->getCurrentDriver()){ - return $this->getCurrentDriver()->createUser($login, $passwd); - }else{ - throw new Exception("No driver instanciated in multi driver!"); - } - } - - function changePassword($login, $newPass){ - if($this->masterSlaveMode){ + $login = $this->extractRealId($login); + if ($this->getCurrentDriver()) { + return $this->getCurrentDriver()->createUser($login, $passwd); + } else { + throw new Exception("No driver instanciated in multi driver!"); + } + } + + public function changePassword($login, $newPass) + { + if ($this->masterSlaveMode) { return $this->drivers[$this->slaveName]->changePassword($login, $newPass); } - if($this->getCurrentDriver() && $this->getCurrentDriver()->usersEditable()){ - return $this->getCurrentDriver()->changePassword($login, $newPass); - }else{ - throw new Exception("No driver instanciated in multi driver!"); - } - } + if ($this->getCurrentDriver() && $this->getCurrentDriver()->usersEditable()) { + return $this->getCurrentDriver()->changePassword($login, $newPass); + } else { + throw new Exception("No driver instanciated in multi driver!"); + } + } - function deleteUser($login){ - if($this->masterSlaveMode){ + public function deleteUser($login) + { + if ($this->masterSlaveMode) { return $this->drivers[$this->slaveName]->deleteUser($login); } - if($this->getCurrentDriver()){ - return $this->getCurrentDriver()->deleteUser($login); - }else{ - throw new Exception("No driver instanciated in multi driver!"); - } - } + if ($this->getCurrentDriver()) { + return $this->getCurrentDriver()->deleteUser($login); + } else { + throw new Exception("No driver instanciated in multi driver!"); + } + } - function getUserPass($login){ - if($this->masterSlaveMode){ + public function getUserPass($login) + { + if ($this->masterSlaveMode) { return $this->drivers[$this->slaveName]->getUserPass($login); } - if($this->getCurrentDriver()){ - return $this->getCurrentDriver()->getUserPass($login); - }else{ - throw new Exception("No driver instanciated in multi driver!"); - } - } - - function filterCredentials($userId, $pwd){ + if ($this->getCurrentDriver()) { + return $this->getCurrentDriver()->getUserPass($login); + } else { + throw new Exception("No driver instanciated in multi driver!"); + } + } + + public function filterCredentials($userId, $pwd) + { if($this->masterSlaveMode) return array($userId, $pwd); - return array($this->extractRealId($userId), $pwd); - } + return array($this->extractRealId($userId), $pwd); + } } -?> \ No newline at end of file diff --git a/core/src/plugins/auth.multi/i18n/conf/en.php b/core/src/plugins/auth.multi/i18n/conf/en.php index 2c83ce6790..d2e395349e 100644 --- a/core/src/plugins/auth.multi/i18n/conf/en.php +++ b/core/src/plugins/auth.multi/i18n/conf/en.php @@ -28,4 +28,3 @@ "Separator" => "Separator", "This is necessary to discriminate users data loaded from various sources. Warning, use foldername compliant characters. For example :: does not work!" => "This is necessary to discriminate users data loaded from various sources. Warning, use foldername compliant characters. For example :: does not work!", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.multi/i18n/conf/fr.php b/core/src/plugins/auth.multi/i18n/conf/fr.php index 6fc4adedc8..7586426d8a 100644 --- a/core/src/plugins/auth.multi/i18n/conf/fr.php +++ b/core/src/plugins/auth.multi/i18n/conf/fr.php @@ -28,4 +28,3 @@ "Separator" => "Séparateur", "This is necessary to discriminate users data loaded from various sources. Warning, use foldername compliant characters. For example :: does not work!" => "Séparateur pour stocker les données des utilisateurs avec en les différenciant correctement selon les drivers.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.multi/i18n/conf/pt.php b/core/src/plugins/auth.multi/i18n/conf/pt.php index 2695bd0f97..1af8879e63 100644 --- a/core/src/plugins/auth.multi/i18n/conf/pt.php +++ b/core/src/plugins/auth.multi/i18n/conf/pt.php @@ -28,4 +28,3 @@ "Separator" => "Separador", "This is necessary to discriminate users data loaded from various sources. Warning, use foldername compliant characters. For example :: does not work!" => "Esta função é necessária para descriminar dados dos utilizadores de várias fontes. ATENÇÃO: Use apenas caracteres padrão para o nome das pastas. Por exemplo :: não irá funcionar!", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.multi/login_patch.xml b/core/src/plugins/auth.multi/login_patch.xml index 4e7e14b4dc..b347f60d90 100644 --- a/core/src/plugins/auth.multi/login_patch.xml +++ b/core/src/plugins/auth.multi/login_patch.xml @@ -7,7 +7,7 @@ if(loginRedirect){ document.location.href=loginRedirect; }else{ - modal.showDialogForm('Log In', ($('login_form')?'login_form':'login_form_dynamic'), + modal.showDialogForm('Log In', ($('login_form')?'login_form':'login_form_dynamic'), function(oForm){ $("generic_dialog_box").setStyle({ top:$("progressBox").getStyle('top'), @@ -98,7 +98,7 @@ connexion.sendAsync(); oForm.userid.value = ''; oForm.password.value = ''; - return false; + return false; }); } -]]> \ No newline at end of file +]]> diff --git a/core/src/plugins/auth.multi/manifest.xml b/core/src/plugins/auth.multi/manifest.xml index 97d048d146..1919e7d095 100755 --- a/core/src/plugins/auth.multi/manifest.xml +++ b/core/src/plugins/auth.multi/manifest.xml @@ -19,4 +19,4 @@ - \ No newline at end of file + diff --git a/core/src/plugins/auth.phpbb/class.phpbbAuthDriver.php b/core/src/plugins/auth.phpbb/class.phpbbAuthDriver.php index 4a8175cd71..ef03cb3f4c 100644 --- a/core/src/plugins/auth.phpbb/class.phpbbAuthDriver.php +++ b/core/src/plugins/auth.phpbb/class.phpbbAuthDriver.php @@ -25,81 +25,84 @@ * @package AjaXplorer_Plugins * @subpackage Auth */ -class phpbbAuthDriver extends serialAuthDriver { - - var $usersSerFile; - var $phpbb_root_path; - var $driverName = "phpbb"; - - function init($options){ - parent::init($options); +class phpbbAuthDriver extends serialAuthDriver +{ + public $usersSerFile; + public $phpbb_root_path; + public $driverName = "phpbb"; + + public function init($options) + { + parent::init($options); $options = $this->options; $this->usersSerFile = $options["USERS_FILEPATH"]; - $this->slaveMode = ($options["SLAVE_MODE"]) ? true : false; - $this->urls = array($options["LOGIN_URL"], $options["LOGOUT_URL"]); - - global $phpbb_root_path, $phpEx, $user, $db, $config, $cache, $template; - define('IN_PHPBB', true); - $phpbb_root_path = $options["PHPBB_PATH"]; - $phpEx = substr(strrchr(__FILE__, '.'), 1); - require($phpbb_root_path . 'common.' . $phpEx); - $user->session_begin(); - - if(!$user->data['is_registered']) - $this->disconnect(); - - } - - function disconnect() - { - if(!empty($_SESSION["AJXP_USER"])){ - unset($_SESSION["AJXP_USER"]); - session_destroy(); - } - } - - function usersEditable() { return false; } - - function passwordsEditable() { return false; } - - function preLogUser($sessionId) { - global $user; - - $username = $user->data['username_clean']; - $password = md5($user->data['user_password']); - - if(!$user->data['is_registered']) - return false; - - if(!$this->userExists($username)){ - if($this->autoCreateUser()){ - $this->createUser($username, $password); - }else{ - return false; - } - } - - AuthService::logUser($username, '', true); - return true; - } - - function getLoginRedirect(){ - if ($this->slaveMode) { - if (!empty($_SESSION["AJXP_USER"])) - return false; - - return $this->urls[0]; - } - return false; - } - - function getLogoutRedirect(){ - if ($this->slaveMode) { - return $this->urls[1]; - } - return false; - } + $this->slaveMode = ($options["SLAVE_MODE"]) ? true : false; + $this->urls = array($options["LOGIN_URL"], $options["LOGOUT_URL"]); + + global $phpbb_root_path, $phpEx, $user, $db, $config, $cache, $template; + define('IN_PHPBB', true); + $phpbb_root_path = $options["PHPBB_PATH"]; + $phpEx = substr(strrchr(__FILE__, '.'), 1); + require($phpbb_root_path . 'common.' . $phpEx); + $user->session_begin(); + + if(!$user->data['is_registered']) + $this->disconnect(); + + } + + public function disconnect() + { + if (!empty($_SESSION["AJXP_USER"])) { + unset($_SESSION["AJXP_USER"]); + session_destroy(); + } + } + + public function usersEditable() { return false; } + + public function passwordsEditable() { return false; } + + public function preLogUser($sessionId) + { + global $user; + + $username = $user->data['username_clean']; + $password = md5($user->data['user_password']); + + if(!$user->data['is_registered']) + return false; + + if (!$this->userExists($username)) { + if ($this->autoCreateUser()) { + $this->createUser($username, $password); + } else { + return false; + } + } + + AuthService::logUser($username, '', true); + return true; + } + + public function getLoginRedirect() + { + if ($this->slaveMode) { + if (!empty($_SESSION["AJXP_USER"])) + return false; + + return $this->urls[0]; + } + return false; + } + + public function getLogoutRedirect() + { + if ($this->slaveMode) { + return $this->urls[1]; + } + return false; + } } -?> \ No newline at end of file diff --git a/core/src/plugins/auth.phpbb/i18n/conf/en.php b/core/src/plugins/auth.phpbb/i18n/conf/en.php index 4ba661953e..5ee3548540 100644 --- a/core/src/plugins/auth.phpbb/i18n/conf/en.php +++ b/core/src/plugins/auth.phpbb/i18n/conf/en.php @@ -32,4 +32,3 @@ "Users" => "Users", "The users list" => "The users list", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.phpbb/i18n/conf/fr.php b/core/src/plugins/auth.phpbb/i18n/conf/fr.php index e4ea23bae6..6fa34c5bbe 100644 --- a/core/src/plugins/auth.phpbb/i18n/conf/fr.php +++ b/core/src/plugins/auth.phpbb/i18n/conf/fr.php @@ -32,4 +32,3 @@ "Users" => "Utilisateurs", "The users list" => "Liste des utilisateurs", ); -?> \ No newline at end of file diff --git a/core/src/plugins/auth.phpbb/manifest.xml b/core/src/plugins/auth.phpbb/manifest.xml index 3e5eda20d3..0131b68ce0 100644 --- a/core/src/plugins/auth.phpbb/manifest.xml +++ b/core/src/plugins/auth.phpbb/manifest.xml @@ -1,7 +1,7 @@ - -
    \ No newline at end of file + + diff --git a/core/src/plugins/downloader.http/resources/i18n/ca.php b/core/src/plugins/downloader.http/resources/i18n/ca.php index aaf3ed0a70..95270a869a 100644 --- a/core/src/plugins/downloader.http/resources/i18n/ca.php +++ b/core/src/plugins/downloader.http/resources/i18n/ca.php @@ -1,25 +1,25 @@ - "Desc. Remota", - "2" => "Descarregar el(s) fitxer(s) de un servidor remot", - "3" => "m", - "4" => "Entreu al menys una URL apuntant al fitxer que voleu descarregar directament des d'un servidor HTTP cap a la carpeta actual. Aquesta acció es farà en segon terme i mentrestant podreu seguir fent servir l'AjaXplorer.", - "5" => "URL", - "6" => "Descarregant", - "7" => "al servidor", - "8" => "Fitxer descarregat, recarregant el client!", - "9" => "Generar bookmarklet", - "10"=> "Descarregar a l'AjaXplorer", - "10a"=> "Descarregar a %s", - "10b"=> "Desc. a %s", - "10c"=> "Desc. a %s", - "10d"=> "AjXp Descàrrega (%s)", - "11"=> "Arrossegeu algun del enllaços cap a la vostra barra de preferits : ", - "12"=> "Començar descàrrega remota", - "13"=> "De l'ordinador", - "14"=> "D'un servidor remot", - "15"=> "O creeu un preferit manualment i feu servir el codi de sota com a url : ", - "16"=> "Arrosega'm a la barra de preferits!", - "17"=> "Descarregar fitxer", - "18"=> "Fitxer parcial" -); + "Desc. Remota", + "2" => "Descarregar el(s) fitxer(s) de un servidor remot", + "3" => "m", + "4" => "Entreu al menys una URL apuntant al fitxer que voleu descarregar directament des d'un servidor HTTP cap a la carpeta actual. Aquesta acció es farà en segon terme i mentrestant podreu seguir fent servir l'AjaXplorer.", + "5" => "URL", + "6" => "Descarregant", + "7" => "al servidor", + "8" => "Fitxer descarregat, recarregant el client!", + "9" => "Generar bookmarklet", + "10"=> "Descarregar a l'AjaXplorer", + "10a"=> "Descarregar a %s", + "10b"=> "Desc. a %s", + "10c"=> "Desc. a %s", + "10d"=> "AjXp Descàrrega (%s)", + "11"=> "Arrossegeu algun del enllaços cap a la vostra barra de preferits : ", + "12"=> "Començar descàrrega remota", + "13"=> "De l'ordinador", + "14"=> "D'un servidor remot", + "15"=> "O creeu un preferit manualment i feu servir el codi de sota com a url : ", + "16"=> "Arrosega'm a la barra de preferits!", + "17"=> "Descarregar fitxer", + "18"=> "Fitxer parcial" +); diff --git a/core/src/plugins/downloader.http/resources/i18n/cs.php b/core/src/plugins/downloader.http/resources/i18n/cs.php index 8c43509988..7d9468e08c 100644 --- a/core/src/plugins/downloader.http/resources/i18n/cs.php +++ b/core/src/plugins/downloader.http/resources/i18n/cs.php @@ -1,13 +1,13 @@ "Remote DL", - "2" => "Stáhnout soubor(y) ze vzdáleného serveru", - "3" => "m", - "4" => "Enter at least one URL pointing to a file that you want to download directly from an external HTTP server to the current folder. This action will be sent to the background and you will be able to continue using AjaXplorer during the download.", - "5" => "URL", - "6" => "Downloading", - "7" => "to server", - "8" => "File downloaded, reloading the client!", + "1" => "Remote DL", + "2" => "Stáhnout soubor(y) ze vzdáleného serveru", + "3" => "m", + "4" => "Enter at least one URL pointing to a file that you want to download directly from an external HTTP server to the current folder. This action will be sent to the background and you will be able to continue using AjaXplorer during the download.", + "5" => "URL", + "6" => "Downloading", + "7" => "to server", + "8" => "File downloaded, reloading the client!", "9" => "Vytvořit záložku", "10"=> "Download to AjaXplorer", "10a"=> "Download to %s", @@ -22,4 +22,4 @@ "16"=> "Drag me to your bookmark bar!", "17"=> "Download file", "18"=> "Partial file" -); \ No newline at end of file +); diff --git a/core/src/plugins/downloader.http/resources/i18n/de.php b/core/src/plugins/downloader.http/resources/i18n/de.php index b3561f3aea..b78d7126fe 100644 --- a/core/src/plugins/downloader.http/resources/i18n/de.php +++ b/core/src/plugins/downloader.http/resources/i18n/de.php @@ -22,4 +22,4 @@ "16" => "Drag me to your bookmark bar!", "17" => "Datei Downloaden", "18" => "Partial file", -); \ No newline at end of file +); diff --git a/core/src/plugins/downloader.http/resources/i18n/en.php b/core/src/plugins/downloader.http/resources/i18n/en.php index dffac55606..0eefe7c2bb 100644 --- a/core/src/plugins/downloader.http/resources/i18n/en.php +++ b/core/src/plugins/downloader.http/resources/i18n/en.php @@ -1,25 +1,25 @@ - "Remote DL", - "2" => "Download file(s) from remote server", - "3" => "m", - "4" => "Enter at least one URL pointing to a file that you want to download directly from an external HTTP server to the current folder. This action will be sent to the background and you will be able to continue using AjaXplorer during the download.", - "5" => "URL", - "6" => "Downloading", - "7" => "to server", - "8" => "File downloaded, reloading the client!", - "9" => "Generate Bookmarklet", - "10"=> "Download to AjaXplorer", - "10a"=> "Download to %s", - "10b"=> "DL to %s", - "10c"=> "DL to %s", - "10d"=> "AjXp Download (%s)", - "11"=> "Drag one of the following link to your bookmark bar : ", - "12"=> "Trigger remote file download", - "13"=> "From computer", - "14"=> "From remote server", - "15"=> "Or create a bookmark manually and use the code below as the link url : ", - "16"=> "Drag me to your bookmark bar!", - "17"=> "Download file", - "18"=> "Partial file" -); \ No newline at end of file + "Remote DL", + "2" => "Download file(s) from remote server", + "3" => "m", + "4" => "Enter at least one URL pointing to a file that you want to download directly from an external HTTP server to the current folder. This action will be sent to the background and you will be able to continue using AjaXplorer during the download.", + "5" => "URL", + "6" => "Downloading", + "7" => "to server", + "8" => "File downloaded, reloading the client!", + "9" => "Generate Bookmarklet", + "10"=> "Download to AjaXplorer", + "10a"=> "Download to %s", + "10b"=> "DL to %s", + "10c"=> "DL to %s", + "10d"=> "AjXp Download (%s)", + "11"=> "Drag one of the following link to your bookmark bar : ", + "12"=> "Trigger remote file download", + "13"=> "From computer", + "14"=> "From remote server", + "15"=> "Or create a bookmark manually and use the code below as the link url : ", + "16"=> "Drag me to your bookmark bar!", + "17"=> "Download file", + "18"=> "Partial file" +); diff --git a/core/src/plugins/downloader.http/resources/i18n/es.php b/core/src/plugins/downloader.http/resources/i18n/es.php index 6174f3b981..67e4d19f29 100644 --- a/core/src/plugins/downloader.http/resources/i18n/es.php +++ b/core/src/plugins/downloader.http/resources/i18n/es.php @@ -1,25 +1,25 @@ - "Descarrga remota", - "2" => "Descargar fichero(s) desde servidor remoto", - "3" => "m", - "4" => "Introduzca al menos una URL apuntando a un fichero que quiera descargar directamente a esta carpeta. Esta acción se ejecutará en segundo plano y podrá seguir usando la aplicación durante la descarga.", - "5" => "URL", - "6" => "Descargando", - "7" => "al servidor", - "8" => "Fichero descargado, actualizando el cliente!", - "9" => "Generando marcador", - "10"=> "Descargar a la aplicación", - "10a"=> "Descargar a %s", - "10b"=> "Descargar a %s", - "10c"=> "Descargar a %s", - "10d"=> "Descarga (%s)", - "11"=> "Arrastre y suelte uno de los siguientes enlaces a su barra de marcadores : ", - "12"=> "Trigger remote file download", - "13"=> "Desde el ordenador", - "14"=> "Desde un servidor remoto", - "15"=> "O cree un marcador manualmente y ese el código siguiente como la URL de enlace : ", - "16"=> "Arrástreme sobre su barra de marcadores!", - "17"=> "Descargarfichero", - "18"=> "Fichero parcial" -); + "Descarrga remota", + "2" => "Descargar fichero(s) desde servidor remoto", + "3" => "m", + "4" => "Introduzca al menos una URL apuntando a un fichero que quiera descargar directamente a esta carpeta. Esta acción se ejecutará en segundo plano y podrá seguir usando la aplicación durante la descarga.", + "5" => "URL", + "6" => "Descargando", + "7" => "al servidor", + "8" => "Fichero descargado, actualizando el cliente!", + "9" => "Generando marcador", + "10"=> "Descargar a la aplicación", + "10a"=> "Descargar a %s", + "10b"=> "Descargar a %s", + "10c"=> "Descargar a %s", + "10d"=> "Descarga (%s)", + "11"=> "Arrastre y suelte uno de los siguientes enlaces a su barra de marcadores : ", + "12"=> "Trigger remote file download", + "13"=> "Desde el ordenador", + "14"=> "Desde un servidor remoto", + "15"=> "O cree un marcador manualmente y ese el código siguiente como la URL de enlace : ", + "16"=> "Arrástreme sobre su barra de marcadores!", + "17"=> "Descargarfichero", + "18"=> "Fichero parcial" +); diff --git a/core/src/plugins/downloader.http/resources/i18n/et.php b/core/src/plugins/downloader.http/resources/i18n/et.php index 8bca215a0a..95da93311d 100644 --- a/core/src/plugins/downloader.http/resources/i18n/et.php +++ b/core/src/plugins/downloader.http/resources/i18n/et.php @@ -1,13 +1,13 @@ "Eemaltlaadimine", - "2" => "Laadi alla faile eemalasuvast serverist", - "3" => "m", - "4" => "Sisesta vähemalt üks URL, mis osutab failile, mille soovid alla laadida otse mõnest eemal asuvast HTTP serverist. Allalaadimine teostatakse taustal ja võid samaaegselt jätkata failihalduri kasutamist.", - "5" => "URL", - "6" => "Laadin alla", - "7" => "serverisse", - "8" => "Fail alla laaditud, värskendan akent!", + "2" => "Laadi alla faile eemalasuvast serverist", + "3" => "m", + "4" => "Sisesta vähemalt üks URL, mis osutab failile, mille soovid alla laadida otse mõnest eemal asuvast HTTP serverist. Allalaadimine teostatakse taustal ja võid samaaegselt jätkata failihalduri kasutamist.", + "5" => "URL", + "6" => "Laadin alla", + "7" => "serverisse", + "8" => "Fail alla laaditud, värskendan akent!", "9" => "Loo järjehoidja", "10"=> "Laadi alla failihaldurisse", "10a"=> "Laadi alla sihtkohta %s", diff --git a/core/src/plugins/downloader.http/resources/i18n/fr.php b/core/src/plugins/downloader.http/resources/i18n/fr.php index 0769adda4e..16d6eb0b3c 100644 --- a/core/src/plugins/downloader.http/resources/i18n/fr.php +++ b/core/src/plugins/downloader.http/resources/i18n/fr.php @@ -1,25 +1,25 @@ - "Download distant", - "2" => "Télécharger des fichiers depuis un autre serveur", - "3" => "m", - "4" => "Entrez une ou plusieurs adresses HTTP de fichiers que vous voulez télécharger. Cette action sera effectuée en arrière-plan et vous pourrez continuer à utiliser AjaXplorer pendant ce temps.", - "5" => "URL", - "6" => "Chargement", - "7" => "sur le serveur", - "8" => "Fichier téléchargé, rechargement du client!", - "9" => "Générer le bookmarklet", - "10"=> "Envoyer sur AjaXplorer", - "10a"=> "Envoyer dans %s", - "10b"=> "Env. dans %s", - "10c"=> "Env. dans %s", - "10d"=> "AjXp Chargement (%s)", - "11"=> "Glissez l'un des liens suivants dans votre barre de favoris : ", - "12"=> "Déclencher le chargement de fichier distant.", - "13"=> "Depuis votre ordinateur", - "14"=> "Depuis un autre serveur", - "15"=> "Ou créez un favori manuellement et inserez-y le code suivante : ", - "16"=> "Glissez moi sur votre barre de favori!", - "17"=> "Télécharger le fichier", - "18"=> "Fichier partiel" -); \ No newline at end of file + "Download distant", + "2" => "Télécharger des fichiers depuis un autre serveur", + "3" => "m", + "4" => "Entrez une ou plusieurs adresses HTTP de fichiers que vous voulez télécharger. Cette action sera effectuée en arrière-plan et vous pourrez continuer à utiliser AjaXplorer pendant ce temps.", + "5" => "URL", + "6" => "Chargement", + "7" => "sur le serveur", + "8" => "Fichier téléchargé, rechargement du client!", + "9" => "Générer le bookmarklet", + "10"=> "Envoyer sur AjaXplorer", + "10a"=> "Envoyer dans %s", + "10b"=> "Env. dans %s", + "10c"=> "Env. dans %s", + "10d"=> "AjXp Chargement (%s)", + "11"=> "Glissez l'un des liens suivants dans votre barre de favoris : ", + "12"=> "Déclencher le chargement de fichier distant.", + "13"=> "Depuis votre ordinateur", + "14"=> "Depuis un autre serveur", + "15"=> "Ou créez un favori manuellement et inserez-y le code suivante : ", + "16"=> "Glissez moi sur votre barre de favori!", + "17"=> "Télécharger le fichier", + "18"=> "Fichier partiel" +); diff --git a/core/src/plugins/downloader.http/resources/i18n/pt.php b/core/src/plugins/downloader.http/resources/i18n/pt.php index aad3d41075..76142df2a7 100644 --- a/core/src/plugins/downloader.http/resources/i18n/pt.php +++ b/core/src/plugins/downloader.http/resources/i18n/pt.php @@ -1,13 +1,13 @@ "Transferência Remota", - "2" => "Transferir ficheiro(s) de um servidor remoto", - "3" => "m", - "4" => "Introduza pelo menos um URL a apontar para o ficheiro que pretende transferir directamente de um servidor remoto HTTP para a pasta actual. Esta acção irá ser processada em segundo plano, pelo que poderá continuar a utilizar o AjaxPlorer enquanto a transferência é efectuada.", - "5" => "URL", - "6" => "A transferir", - "7" => "para o servidor", - "8" => "Ficheiro transferido com sucesso, a recarregar o cliente!", + "1" => "Transferência Remota", + "2" => "Transferir ficheiro(s) de um servidor remoto", + "3" => "m", + "4" => "Introduza pelo menos um URL a apontar para o ficheiro que pretende transferir directamente de um servidor remoto HTTP para a pasta actual. Esta acção irá ser processada em segundo plano, pelo que poderá continuar a utilizar o AjaxPlorer enquanto a transferência é efectuada.", + "5" => "URL", + "6" => "A transferir", + "7" => "para o servidor", + "8" => "Ficheiro transferido com sucesso, a recarregar o cliente!", "9" => "Gerar Marcador", "10"=> "Transferir para o AjaXplorer", "10a"=> "Transferir para %s", @@ -22,4 +22,4 @@ "16"=> "Arrasta-me para a sua lista de marcadores!", "17"=> "Transferir Ficheiro", "18"=> "Ficheiro Parcial" -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.ajxp_plugin/i18n/conf/fr.php b/core/src/plugins/editor.ajxp_plugin/i18n/conf/fr.php index c522155bee..40b704770d 100755 --- a/core/src/plugins/editor.ajxp_plugin/i18n/conf/fr.php +++ b/core/src/plugins/editor.ajxp_plugin/i18n/conf/fr.php @@ -21,4 +21,3 @@ $mess=array( "Repository Editor" => "Editeur de dépôts", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.ajxp_plugin/i18n/fr.php b/core/src/plugins/editor.ajxp_plugin/i18n/fr.php index ba34d64593..39008ea861 100755 --- a/core/src/plugins/editor.ajxp_plugin/i18n/fr.php +++ b/core/src/plugins/editor.ajxp_plugin/i18n/fr.php @@ -34,4 +34,4 @@ "13" => "Are you sure you want to delete this source?", "14" => "Please choose a driver!", "15" => "This repository is defined in the config file (see conf/bootstrap_repositories.php), you cannot edit its features via the GUI.", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.ajxp_plugin/manifest.xml b/core/src/plugins/editor.ajxp_plugin/manifest.xml index 078ac831e0..0986f82073 100755 --- a/core/src/plugins/editor.ajxp_plugin/manifest.xml +++ b/core/src/plugins/editor.ajxp_plugin/manifest.xml @@ -32,9 +32,9 @@
    - + ]]> - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.ajxp_repository/i18n/conf/fr.php b/core/src/plugins/editor.ajxp_repository/i18n/conf/fr.php index c522155bee..40b704770d 100755 --- a/core/src/plugins/editor.ajxp_repository/i18n/conf/fr.php +++ b/core/src/plugins/editor.ajxp_repository/i18n/conf/fr.php @@ -21,4 +21,3 @@ $mess=array( "Repository Editor" => "Editeur de dépôts", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.ajxp_repository/i18n/fr.php b/core/src/plugins/editor.ajxp_repository/i18n/fr.php index ba34d64593..39008ea861 100755 --- a/core/src/plugins/editor.ajxp_repository/i18n/fr.php +++ b/core/src/plugins/editor.ajxp_repository/i18n/fr.php @@ -34,4 +34,4 @@ "13" => "Are you sure you want to delete this source?", "14" => "Please choose a driver!", "15" => "This repository is defined in the config file (see conf/bootstrap_repositories.php), you cannot edit its features via the GUI.", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.ajxp_repository/manifest.xml b/core/src/plugins/editor.ajxp_repository/manifest.xml index 38e76dde55..6fffd090e3 100644 --- a/core/src/plugins/editor.ajxp_repository/manifest.xml +++ b/core/src/plugins/editor.ajxp_repository/manifest.xml @@ -32,9 +32,9 @@
    - + ]]> - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.ajxp_role/i18n/conf/fr.php b/core/src/plugins/editor.ajxp_role/i18n/conf/fr.php index 6a361cf3f6..7730119b57 100755 --- a/core/src/plugins/editor.ajxp_role/i18n/conf/fr.php +++ b/core/src/plugins/editor.ajxp_role/i18n/conf/fr.php @@ -22,4 +22,3 @@ "Text Editor" => "Editeur Text", "Very basic text editor" => "editeur text basique", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.ajxp_role/i18n/fr.php b/core/src/plugins/editor.ajxp_role/i18n/fr.php index 69188d46da..04c475b466 100755 --- a/core/src/plugins/editor.ajxp_role/i18n/fr.php +++ b/core/src/plugins/editor.ajxp_role/i18n/fr.php @@ -66,4 +66,4 @@ "40" => "Activer", "41" => "Supprimer", "42" => "Données du rôle", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.ajxp_role/manifest.xml b/core/src/plugins/editor.ajxp_role/manifest.xml index e340a641dd..e849b5ce3b 100755 --- a/core/src/plugins/editor.ajxp_role/manifest.xml +++ b/core/src/plugins/editor.ajxp_role/manifest.xml @@ -76,9 +76,9 @@
    - + ]]> - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.audio/class.AudioPreviewer.php b/core/src/plugins/editor.audio/class.AudioPreviewer.php index 02e9af3495..614d76c04a 100644 --- a/core/src/plugins/editor.audio/class.AudioPreviewer.php +++ b/core/src/plugins/editor.audio/class.AudioPreviewer.php @@ -26,72 +26,72 @@ * @package AjaXplorer_Plugins * @subpackage Editor */ -class AudioPreviewer extends AJXP_Plugin { +class AudioPreviewer extends AJXP_Plugin +{ + public function preProcessAction($action, &$httpVars, &$fileVars) + { + if ($action != "ls" || !isset($httpVars["playlist"])) { + return ; + } + $httpVars["dir"] = base64_decode($httpVars["dir"]); + } - public function preProcessAction($action, &$httpVars, &$fileVars){ - if($action != "ls" || !isset($httpVars["playlist"])){ - return ; - } - $httpVars["dir"] = base64_decode($httpVars["dir"]); - } - - public function switchAction($action, $httpVars, $postProcessData){ - - if(!isSet($this->actions[$action])) return false; - - $repository = ConfService::getRepository(); - if(!$repository->detectStreamWrapper(false)){ - return false; - } - $plugin = AJXP_PluginsService::findPlugin("access", $repository->getAccessType()); - $streamData = $plugin->detectStreamWrapper(true); - $destStreamURL = $streamData["protocol"]."://".$repository->getId()."/"; - - if($action == "audio_proxy"){ + public function switchAction($action, $httpVars, $postProcessData) + { + if(!isSet($this->actions[$action])) return false; + + $repository = ConfService::getRepository(); + if (!$repository->detectStreamWrapper(false)) { + return false; + } + $plugin = AJXP_PluginsService::findPlugin("access", $repository->getAccessType()); + $streamData = $plugin->detectStreamWrapper(true); + $destStreamURL = $streamData["protocol"]."://".$repository->getId()."/"; + + if ($action == "audio_proxy") { $file = AJXP_Utils::decodeSecureMagic(base64_decode($httpVars["file"])); $cType = "audio/".array_pop(explode(".", $file)); - $localName = basename($file); + $localName = basename($file); header("Content-Type: ".$cType."; name=\"".$localName."\""); - header("Content-Length: ".filesize($destStreamURL.$file)); - - $stream = fopen("php://output", "a"); - call_user_func(array($streamData["classname"], "copyFileInStream"), $destStreamURL.$file, $stream); - fflush($stream); - fclose($stream); + header("Content-Length: ".filesize($destStreamURL.$file)); + + $stream = fopen("php://output", "a"); + call_user_func(array($streamData["classname"], "copyFileInStream"), $destStreamURL.$file, $stream); + fflush($stream); + fclose($stream); $node = new AJXP_Node($destStreamURL.$file); AJXP_Controller::applyHook("node.read", array($node)); //exit(1); - - }else if($action == "ls"){ - if(!isSet($httpVars["playlist"])){ - // This should not happen anyway, because of the applyCondition. - AJXP_Controller::passProcessDataThrough($postProcessData); - return ; - } - // We transform the XML into XSPF - $xmlString = $postProcessData["ob_output"]; + + } else if ($action == "ls") { + if (!isSet($httpVars["playlist"])) { + // This should not happen anyway, because of the applyCondition. + AJXP_Controller::passProcessDataThrough($postProcessData); + return ; + } + // We transform the XML into XSPF + $xmlString = $postProcessData["ob_output"]; $xmlDoc = new DOMDocument(); $xmlDoc->loadXML($xmlString); - $xElement = $xmlDoc->documentElement; - header("Content-Type:application/xspf+xml;charset=UTF-8"); - print(''); - print(''); - print(""); - foreach ($xElement->childNodes as $child){ - $isFile = ($child->getAttribute("is_file") == "true"); - $label = $child->getAttribute("text"); + $xElement = $xmlDoc->documentElement; + header("Content-Type:application/xspf+xml;charset=UTF-8"); + print(''); + print(''); + print(""); + foreach ($xElement->childNodes as $child) { + $isFile = ($child->getAttribute("is_file") == "true"); + $label = $child->getAttribute("text"); $ar = explode(".", $label); - $ext = strtolower(end($ar)); - if(!$isFile || $ext != "mp3") continue; - print("".AJXP_SERVER_ACCESS."?secure_token=".AuthService::getSecureToken()."&get_action=audio_proxy&file=".base64_encode($child->getAttribute("filename"))."".$label.""); - } - print(""); - AJXP_XMLWriter::close("playlist"); - } - } + $ext = strtolower(end($ar)); + if(!$isFile || $ext != "mp3") continue; + print("".AJXP_SERVER_ACCESS."?secure_token=".AuthService::getSecureToken()."&get_action=audio_proxy&file=".base64_encode($child->getAttribute("filename"))."".$label.""); + } + print(""); + AJXP_XMLWriter::close("playlist"); + } + } } -?> \ No newline at end of file diff --git a/core/src/plugins/editor.audio/i18n/conf/en.php b/core/src/plugins/editor.audio/i18n/conf/en.php index 19899a07b9..e0bbc5a298 100644 --- a/core/src/plugins/editor.audio/i18n/conf/en.php +++ b/core/src/plugins/editor.audio/i18n/conf/en.php @@ -22,4 +22,3 @@ "Audio Player" => "Audio Player", "Inserts a flash player for reading mp3 files online, and playing a whole folder in a separate window." => "Inserts a flash player for reading mp3 files online, and playing a whole folder in a separate window.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.audio/i18n/conf/fr.php b/core/src/plugins/editor.audio/i18n/conf/fr.php index 00404688e5..f6b1960075 100644 --- a/core/src/plugins/editor.audio/i18n/conf/fr.php +++ b/core/src/plugins/editor.audio/i18n/conf/fr.php @@ -22,4 +22,3 @@ "Audio Player" => "Player Audio", "Inserts a flash player for reading mp3 files online, and playing a whole folder in a separate window." => "Insertion d'un lecteur flash pour lire les mp3, et possibilité de lire tout un répertoire.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.audio/i18n/conf/pt.php b/core/src/plugins/editor.audio/i18n/conf/pt.php index 17064b7f9d..76e8d606f1 100644 --- a/core/src/plugins/editor.audio/i18n/conf/pt.php +++ b/core/src/plugins/editor.audio/i18n/conf/pt.php @@ -22,4 +22,3 @@ "Audio Player" => "Reprodutor de Música", "Inserts a flash player for reading mp3 files online, and playing a whole folder in a separate window." => "Insere um reprodutor em Flash para ler ficheiros MP3 online, e reproduz os conteúdos de uma pasta numa janela em separado.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.audio/manifest.xml b/core/src/plugins/editor.audio/manifest.xml index 55d0f38eb6..38cdce5ed5 100644 --- a/core/src/plugins/editor.audio/manifest.xml +++ b/core/src/plugins/editor.audio/manifest.xml @@ -25,7 +25,7 @@ var editorClass = Class.getByName(editor.editorClass); if(editorClass){ editorClass.prototype.createFolderPlayer(ajaxplorer.getContextNode()); - } + } } ]]> @@ -33,10 +33,10 @@ - + - + @@ -45,5 +45,5 @@ - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.browser/class.FileMimeSender.php b/core/src/plugins/editor.browser/class.FileMimeSender.php index af204724ef..a8e45a993e 100755 --- a/core/src/plugins/editor.browser/class.FileMimeSender.php +++ b/core/src/plugins/editor.browser/class.FileMimeSender.php @@ -1,114 +1,112 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * Extract the mimetype of a file and send it to the browser - * @package AjaXplorer_Plugins - * @subpackage Editor - */ -class FileMimeSender extends AJXP_Plugin { - - public function switchAction($action, $httpVars, $filesVars) { - - if(!isSet($this->actions[$action])) - return false; - - $repository = ConfService::getRepositoryById($httpVars["repository_id"]); - - if(!$repository->detectStreamWrapper(true)) - return false; - - if(AuthService::usersEnabled()){ - $loggedUser = AuthService::getLoggedUser(); - if($loggedUser === null && ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth")){ - AuthService::logUser("guest", null); - $loggedUser = AuthService::getLoggedUser(); - } - if(!$loggedUser->canSwitchTo($repository->getId())){ - echo("You do not have permissions to access this resource"); - return false; - } - } - - $streamData = $repository->streamData; - $destStreamURL = $streamData["protocol"] . "://" . $repository->getId(); - - if($action == "open_file") { - $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); - if(!file_exists($destStreamURL . $file)){ - echo("File does not exist"); - return false; - } - - $filesize = filesize($destStreamURL . $file); - $fp = fopen($destStreamURL . $file, "rb"); - - //Get mimetype with fileinfo PECL extension - if(class_exists("finfo")) { - $finfo = new finfo(FILEINFO_MIME); - $fileMime = $finfo->buffer(fread($fp, 100)); - } - //Get mimetype with (deprecated) mime_content_type - elseif(function_exists("mime_content_type")) { - $fileMime = @mime_content_type($fp); - } - //Guess mimetype based on file extension - else { - $fileExt = substr(strrchr(basename($file), '.'), 1); - if(empty($fileExt)) - $fileMime = "application/octet-stream"; - else { - $regex = "/^([\w\+\-\.\/]+)\s+(\w+\s)*($fileExt\s)/i"; - $lines = file( $this->getBaseDir()."/resources/other/mime.types"); - foreach($lines as $line) { - if(substr($line, 0, 1) == '#') - continue; // skip comments - $line = rtrim($line) . " "; - if(!preg_match($regex, $line, $matches)) - continue; // no match to the extension - $fileMime = $matches[1]; - } - } - } - fclose($fp); - // If still no mimetype, give up and serve application/octet-stream - if(empty($fileMime)) - $fileMime = "application/octet-stream"; - - //Send headers - HTMLWriter::generateInlineHeaders(basename($file), $filesize, $fileMime); - - $class = $streamData["classname"]; - $stream = fopen("php://output", "a"); - call_user_func(array($streamData["classname"], "copyFileInStream"), $destStreamURL . $file, $stream); - fflush($stream); - fclose($stream); - - $node = new AJXP_Node($destStreamURL.$file); - AJXP_Controller::applyHook("node.read", array($node)); - - } - } -} - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * Extract the mimetype of a file and send it to the browser + * @package AjaXplorer_Plugins + * @subpackage Editor + */ +class FileMimeSender extends AJXP_Plugin +{ + public function switchAction($action, $httpVars, $filesVars) + { + if(!isSet($this->actions[$action])) + return false; + + $repository = ConfService::getRepositoryById($httpVars["repository_id"]); + + if(!$repository->detectStreamWrapper(true)) + return false; + + if (AuthService::usersEnabled()) { + $loggedUser = AuthService::getLoggedUser(); + if ($loggedUser === null && ConfService::getCoreConf("ALLOW_GUEST_BROWSING", "auth")) { + AuthService::logUser("guest", null); + $loggedUser = AuthService::getLoggedUser(); + } + if (!$loggedUser->canSwitchTo($repository->getId())) { + echo("You do not have permissions to access this resource"); + return false; + } + } + + $streamData = $repository->streamData; + $destStreamURL = $streamData["protocol"] . "://" . $repository->getId(); + + if ($action == "open_file") { + $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + if (!file_exists($destStreamURL . $file)) { + echo("File does not exist"); + return false; + } + + $filesize = filesize($destStreamURL . $file); + $fp = fopen($destStreamURL . $file, "rb"); + + //Get mimetype with fileinfo PECL extension + if (class_exists("finfo")) { + $finfo = new finfo(FILEINFO_MIME); + $fileMime = $finfo->buffer(fread($fp, 100)); + } + //Get mimetype with (deprecated) mime_content_type + elseif (function_exists("mime_content_type")) { + $fileMime = @mime_content_type($fp); + } + //Guess mimetype based on file extension + else { + $fileExt = substr(strrchr(basename($file), '.'), 1); + if(empty($fileExt)) + $fileMime = "application/octet-stream"; + else { + $regex = "/^([\w\+\-\.\/]+)\s+(\w+\s)*($fileExt\s)/i"; + $lines = file( $this->getBaseDir()."/resources/other/mime.types"); + foreach ($lines as $line) { + if(substr($line, 0, 1) == '#') + continue; // skip comments + $line = rtrim($line) . " "; + if(!preg_match($regex, $line, $matches)) + continue; // no match to the extension + $fileMime = $matches[1]; + } + } + } + fclose($fp); + // If still no mimetype, give up and serve application/octet-stream + if(empty($fileMime)) + $fileMime = "application/octet-stream"; + + //Send headers + HTMLWriter::generateInlineHeaders(basename($file), $filesize, $fileMime); + + $class = $streamData["classname"]; + $stream = fopen("php://output", "a"); + call_user_func(array($streamData["classname"], "copyFileInStream"), $destStreamURL . $file, $stream); + fflush($stream); + fclose($stream); + + $node = new AJXP_Node($destStreamURL.$file); + AJXP_Controller::applyHook("node.read", array($node)); + + } + } +} diff --git a/core/src/plugins/editor.browser/manifest.xml b/core/src/plugins/editor.browser/manifest.xml index 8222684ac9..e76f09f383 100644 --- a/core/src/plugins/editor.browser/manifest.xml +++ b/core/src/plugins/editor.browser/manifest.xml @@ -1,5 +1,5 @@ - @@ -13,12 +13,12 @@ AJXP_MESSAGE[openbrowser.3] - - ]]> + + ]]> - + @@ -29,5 +29,5 @@ - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.browser/resources/i18n/de.php b/core/src/plugins/editor.browser/resources/i18n/de.php index ba64bb2988..61f0251fc3 100755 --- a/core/src/plugins/editor.browser/resources/i18n/de.php +++ b/core/src/plugins/editor.browser/resources/i18n/de.php @@ -1,26 +1,25 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess=array( -"1" => "Externes Fenster", -"2" => "Externes Browser Fenster", -"3" => "Öffne Datei im externen Fenster, bitte warten, dieses Fenster schließt sich automatisch.", -); -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess=array( +"1" => "Externes Fenster", +"2" => "Externes Browser Fenster", +"3" => "Öffne Datei im externen Fenster, bitte warten, dieses Fenster schließt sich automatisch.", +); diff --git a/core/src/plugins/editor.browser/resources/i18n/en.php b/core/src/plugins/editor.browser/resources/i18n/en.php index b9ad7a6df2..bc99c082ff 100755 --- a/core/src/plugins/editor.browser/resources/i18n/en.php +++ b/core/src/plugins/editor.browser/resources/i18n/en.php @@ -1,26 +1,25 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess=array( -"1" => "External window", -"2" => "External browser window", -"3" => "Opening file in external window, please wait, this window should close automatically.", -); -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess=array( +"1" => "External window", +"2" => "External browser window", +"3" => "Opening file in external window, please wait, this window should close automatically.", +); diff --git a/core/src/plugins/editor.browser/resources/i18n/es.php b/core/src/plugins/editor.browser/resources/i18n/es.php index 7a5e9e61c3..a5a9339b69 100755 --- a/core/src/plugins/editor.browser/resources/i18n/es.php +++ b/core/src/plugins/editor.browser/resources/i18n/es.php @@ -1,26 +1,25 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -$mess=array( -"1" => "Nueva ventana", -"2" => "Navegador en nueva ventana", -"3" => "Abriendo el fichero en una ventana externa, espere por favor, esta ventana se cerrará automáticamente.", -); -?> + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +$mess=array( +"1" => "Nueva ventana", +"2" => "Navegador en nueva ventana", +"3" => "Abriendo el fichero en una ventana externa, espere por favor, esta ventana se cerrará automáticamente.", +); diff --git a/core/src/plugins/editor.browser/resources/i18n/et.php b/core/src/plugins/editor.browser/resources/i18n/et.php index ee4bf050a1..65dd5c090d 100644 --- a/core/src/plugins/editor.browser/resources/i18n/et.php +++ b/core/src/plugins/editor.browser/resources/i18n/et.php @@ -26,5 +26,4 @@ "1" => "Väline aken", "2" => "Väline veebilehitseja aken", "3" => "Avan faili välises aknas, palun oota, see teade sulgub automaatselt.", -); -?> +); diff --git a/core/src/plugins/editor.browser/resources/i18n/fr.php b/core/src/plugins/editor.browser/resources/i18n/fr.php index a16001c9aa..3af6a355b5 100644 --- a/core/src/plugins/editor.browser/resources/i18n/fr.php +++ b/core/src/plugins/editor.browser/resources/i18n/fr.php @@ -23,4 +23,3 @@ "2" => "Fenêtre externe", "3" => "Ouvrir le fichier dans une nouvelle fenêtre du navigateur.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.browser/resources/i18n/pt.php b/core/src/plugins/editor.browser/resources/i18n/pt.php index b93ab300ff..e3424d7fe9 100644 --- a/core/src/plugins/editor.browser/resources/i18n/pt.php +++ b/core/src/plugins/editor.browser/resources/i18n/pt.php @@ -22,5 +22,4 @@ "1" => "Janela Externa", "2" => "Janela Externa no Navegador", "3" => "A Abrir ficheiro numa janela Externa, por favor aguarde, esta janela deverá ser fechada automaticamente.", -); -?> +); diff --git a/core/src/plugins/editor.ckeditor/i18n/conf/en.php b/core/src/plugins/editor.ckeditor/i18n/conf/en.php index 26eed5f152..d0fb3fcb18 100644 --- a/core/src/plugins/editor.ckeditor/i18n/conf/en.php +++ b/core/src/plugins/editor.ckeditor/i18n/conf/en.php @@ -20,4 +20,3 @@ */ $mess=array( ); -?> diff --git a/core/src/plugins/editor.ckeditor/i18n/conf/pt.php b/core/src/plugins/editor.ckeditor/i18n/conf/pt.php index 26eed5f152..d0fb3fcb18 100644 --- a/core/src/plugins/editor.ckeditor/i18n/conf/pt.php +++ b/core/src/plugins/editor.ckeditor/i18n/conf/pt.php @@ -20,4 +20,3 @@ */ $mess=array( ); -?> diff --git a/core/src/plugins/editor.ckeditor/manifest.xml b/core/src/plugins/editor.ckeditor/manifest.xml index 0d7e4f9ca3..a0e2cfdf22 100644 --- a/core/src/plugins/editor.ckeditor/manifest.xml +++ b/core/src/plugins/editor.ckeditor/manifest.xml @@ -6,7 +6,7 @@ - + @@ -18,5 +18,5 @@ window.CKEDITOR_BASEPATH = 'plugins/editor.ckeditor/ckeditor/'; - ]]> - \ No newline at end of file + ]]> + diff --git a/core/src/plugins/editor.codemirror/i18n/conf/en.php b/core/src/plugins/editor.codemirror/i18n/conf/en.php index 5279dc6770..d19ff06b1c 100644 --- a/core/src/plugins/editor.codemirror/i18n/conf/en.php +++ b/core/src/plugins/editor.codemirror/i18n/conf/en.php @@ -22,4 +22,3 @@ "Source Viewer" => "Source Viewer", "Syntax Highlighter for all major code source files" => "Syntax Highlighter for all major code source files", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.codemirror/i18n/conf/fr.php b/core/src/plugins/editor.codemirror/i18n/conf/fr.php index fce3753d11..fc85086f65 100644 --- a/core/src/plugins/editor.codemirror/i18n/conf/fr.php +++ b/core/src/plugins/editor.codemirror/i18n/conf/fr.php @@ -22,4 +22,3 @@ "Source Viewer" => "Afficheur de Sources", "Syntax Highlighter for all major code source files" => "Syntax Highlight pour la plupart des code source", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.codemirror/i18n/conf/pt.php b/core/src/plugins/editor.codemirror/i18n/conf/pt.php index 11c7f7efa9..e1746de29c 100644 --- a/core/src/plugins/editor.codemirror/i18n/conf/pt.php +++ b/core/src/plugins/editor.codemirror/i18n/conf/pt.php @@ -22,4 +22,3 @@ "Source Viewer" => "Visualizador de Código-Fonte", "Syntax Highlighter for all major code source files" => "Visualizador Syntax Highlighter para todos os tipos principais de código-fonte", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.codemirror/i18n/de.php b/core/src/plugins/editor.codemirror/i18n/de.php index 823506b579..3104c8e448 100644 --- a/core/src/plugins/editor.codemirror/i18n/de.php +++ b/core/src/plugins/editor.codemirror/i18n/de.php @@ -31,5 +31,3 @@ "9" => "Textsuche", "10" => "Zeileneinzug" ); - -?> diff --git a/core/src/plugins/editor.codemirror/i18n/en.php b/core/src/plugins/editor.codemirror/i18n/en.php index 02bdd6c8e6..1bda7fcbae 100644 --- a/core/src/plugins/editor.codemirror/i18n/en.php +++ b/core/src/plugins/editor.codemirror/i18n/en.php @@ -31,5 +31,3 @@ "9" => "Text Search", "10" => "Indent size" ); - -?> \ No newline at end of file diff --git a/core/src/plugins/editor.codemirror/i18n/et.php b/core/src/plugins/editor.codemirror/i18n/et.php index a5e167c1f5..d562be6685 100644 --- a/core/src/plugins/editor.codemirror/i18n/et.php +++ b/core/src/plugins/editor.codemirror/i18n/et.php @@ -34,5 +34,3 @@ "9" => "Tekstiotsing", "10" => "Treppimise laius" ); - -?> diff --git a/core/src/plugins/editor.codemirror/i18n/fr.php b/core/src/plugins/editor.codemirror/i18n/fr.php index e7899b3a68..d4b6dd6e76 100644 --- a/core/src/plugins/editor.codemirror/i18n/fr.php +++ b/core/src/plugins/editor.codemirror/i18n/fr.php @@ -31,4 +31,3 @@ "9" => "Text Search", "10" => "Indent size", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.codemirror/i18n/pt.php b/core/src/plugins/editor.codemirror/i18n/pt.php index 00cbff3d33..30173a59ed 100644 --- a/core/src/plugins/editor.codemirror/i18n/pt.php +++ b/core/src/plugins/editor.codemirror/i18n/pt.php @@ -31,5 +31,3 @@ "9" => "Procurar Texto", "10" => "Tamanho de Recuo" ); - -?> \ No newline at end of file diff --git a/core/src/plugins/editor.codemirror/i18n/si.php b/core/src/plugins/editor.codemirror/i18n/si.php index a0d34e3365..f1fd9814f1 100644 --- a/core/src/plugins/editor.codemirror/i18n/si.php +++ b/core/src/plugins/editor.codemirror/i18n/si.php @@ -19,7 +19,7 @@ * The latest code can be found at . */ // Slovenian translation: April 21 2011 by Vladimir Bohinc (vladimir.bohinc@gmail.com) -// +// //--------------------------------------------------------------------------------------------------- $mess=array( "1" => "Urejevalnik izvorne kode", @@ -34,4 +34,3 @@ "9" => "Iskanje besedila", "10" => "Velikost zamika" ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.codemirror/manifest.xml b/core/src/plugins/editor.codemirror/manifest.xml index b28fbf6b5b..073359161b 100644 --- a/core/src/plugins/editor.codemirror/manifest.xml +++ b/core/src/plugins/editor.codemirror/manifest.xml @@ -14,7 +14,7 @@
    AJXP_MESSAGE[code_mirror.6] AJXP_MESSAGE[code_mirror.9] -
    +

    AJXP_MESSAGE[53]

    AJXP_MESSAGE[88]
    @@ -25,9 +25,9 @@
    AJXP_MESSAGE[code_mirror.3]
    - ]]> + ]]> - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.codepress/i18n/conf/en.php b/core/src/plugins/editor.codepress/i18n/conf/en.php index b82f07be17..8c37d92884 100644 --- a/core/src/plugins/editor.codepress/i18n/conf/en.php +++ b/core/src/plugins/editor.codepress/i18n/conf/en.php @@ -22,4 +22,3 @@ "CodePress" => "CodePress", "Legacy Syntax Highlighter" => "Legacy Syntax Highlighter", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.codepress/i18n/conf/fr.php b/core/src/plugins/editor.codepress/i18n/conf/fr.php index 5d737dc32b..883a30b1c2 100644 --- a/core/src/plugins/editor.codepress/i18n/conf/fr.php +++ b/core/src/plugins/editor.codepress/i18n/conf/fr.php @@ -22,4 +22,3 @@ "CodePress" => "CodePress", "Legacy Syntax Highlighter" => "Mise en forme de la syntaxe", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.codepress/manifest.xml b/core/src/plugins/editor.codepress/manifest.xml index f6f6c10116..e7a4f0ed17 100644 --- a/core/src/plugins/editor.codepress/manifest.xml +++ b/core/src/plugins/editor.codepress/manifest.xml @@ -17,4 +17,4 @@ - \ No newline at end of file + diff --git a/core/src/plugins/editor.diaporama/class.ImagePreviewer.php b/core/src/plugins/editor.diaporama/class.ImagePreviewer.php index 83fcba6a7e..2c1f41e102 100644 --- a/core/src/plugins/editor.diaporama/class.ImagePreviewer.php +++ b/core/src/plugins/editor.diaporama/class.ImagePreviewer.php @@ -26,164 +26,166 @@ * @package AjaXplorer_Plugins * @subpackage Editor */ -class ImagePreviewer extends AJXP_Plugin { - +class ImagePreviewer extends AJXP_Plugin +{ private $currentDimension; - public function switchAction($action, $httpVars, $filesVars){ - - if(!isSet($this->actions[$action])) return false; - - $repository = ConfService::getRepository(); - if(!$repository->detectStreamWrapper(true)){ - return false; - } - if(!isSet($this->pluginConf)){ - $this->pluginConf = array("GENERATE_THUMBNAIL"=>false); - } - - - $streamData = $repository->streamData; - $this->streamData = $streamData; - $destStreamURL = $streamData["protocol"]."://".$repository->getId(); - - if($action == "preview_data_proxy"){ - $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + public function switchAction($action, $httpVars, $filesVars) + { + if(!isSet($this->actions[$action])) return false; + + $repository = ConfService::getRepository(); + if (!$repository->detectStreamWrapper(true)) { + return false; + } + if (!isSet($this->pluginConf)) { + $this->pluginConf = array("GENERATE_THUMBNAIL"=>false); + } + + + $streamData = $repository->streamData; + $this->streamData = $streamData; + $destStreamURL = $streamData["protocol"]."://".$repository->getId(); + + if ($action == "preview_data_proxy") { + $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); if(!file_exists($destStreamURL.$file)) return; - - if(isSet($httpVars["get_thumb"]) && $this->getFilteredOption("GENERATE_THUMBNAIL", $repository->getId())){ + + if (isSet($httpVars["get_thumb"]) && $this->getFilteredOption("GENERATE_THUMBNAIL", $repository->getId())) { $dimension = 200; if(isSet($httpVars["dimension"]) && is_numeric($httpVars["dimension"])) $dimension = $httpVars["dimension"]; $this->currentDimension = $dimension; - $cacheItem = AJXP_Cache::getItem("diaporama_".$dimension, $destStreamURL.$file, array($this, "generateThumbnail")); - $data = $cacheItem->getData(); - $cId = $cacheItem->getId(); - - header("Content-Type: ".AJXP_Utils::getImageMimeType(basename($cId))."; name=\"".basename($cId)."\""); - header("Content-Length: ".strlen($data)); - header('Cache-Control: public'); + $cacheItem = AJXP_Cache::getItem("diaporama_".$dimension, $destStreamURL.$file, array($this, "generateThumbnail")); + $data = $cacheItem->getData(); + $cId = $cacheItem->getId(); + + header("Content-Type: ".AJXP_Utils::getImageMimeType(basename($cId))."; name=\"".basename($cId)."\""); + header("Content-Length: ".strlen($data)); + header('Cache-Control: public'); header("Pragma:"); header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()-10000) . " GMT"); header("Expires: " . gmdate("D, d M Y H:i:s", time()+5*24*3600) . " GMT"); - print($data); + print($data); - }else{ - //$filesize = filesize($destStreamURL.$file); + } else { + //$filesize = filesize($destStreamURL.$file); $node = new AJXP_Node($destStreamURL.$file); $fp = fopen($destStreamURL.$file, "r"); $stat = fstat($fp); $filesize = $stat["size"]; - header("Content-Type: ".AJXP_Utils::getImageMimeType(basename($file))."; name=\"".basename($file)."\""); - header("Content-Length: ".$filesize); - header('Cache-Control: public'); + header("Content-Type: ".AJXP_Utils::getImageMimeType(basename($file))."; name=\"".basename($file)."\""); + header("Content-Length: ".$filesize); + header('Cache-Control: public'); header("Pragma:"); header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()-10000) . " GMT"); header("Expires: " . gmdate("D, d M Y H:i:s", time()+5*24*3600) . " GMT"); - $class = $streamData["classname"]; - $stream = fopen("php://output", "a"); - call_user_func(array($streamData["classname"], "copyFileInStream"), $destStreamURL.$file, $stream); - fflush($stream); - fclose($stream); + $class = $streamData["classname"]; + $stream = fopen("php://output", "a"); + call_user_func(array($streamData["classname"], "copyFileInStream"), $destStreamURL.$file, $stream); + fflush($stream); + fclose($stream); AJXP_Controller::applyHook("node.read", array($node)); - } - } - } - - /** - * - * @param AJXP_Node $oldFile - * @param AJXP_Node $newFile - * @param Boolean $copy - */ - public function removeThumbnail($oldFile, $newFile = null, $copy = false){ - if($oldFile == null) return ; - if(!$this->handleMime($oldFile->getUrl())) return; - if($newFile == null || $copy == false){ - $diapoFolders = glob((defined('AJXP_SHARED_CACHE_DIR')?AJXP_SHARED_CACHE_DIR:AJXP_CACHE_DIR)."/diaporama_*",GLOB_ONLYDIR); - if($diapoFolders !== false && is_array($diapoFolders)){ - foreach($diapoFolders as $f) { + } + } + } + + /** + * + * @param AJXP_Node $oldFile + * @param AJXP_Node $newFile + * @param Boolean $copy + */ + public function removeThumbnail($oldFile, $newFile = null, $copy = false) + { + if($oldFile == null) return ; + if(!$this->handleMime($oldFile->getUrl())) return; + if ($newFile == null || $copy == false) { + $diapoFolders = glob((defined('AJXP_SHARED_CACHE_DIR')?AJXP_SHARED_CACHE_DIR:AJXP_CACHE_DIR)."/diaporama_*",GLOB_ONLYDIR); + if ($diapoFolders !== false && is_array($diapoFolders)) { + foreach ($diapoFolders as $f) { $f = basename($f); AJXP_Logger::debug("GLOB ".$f); AJXP_Cache::clearItem($f, $oldFile->getUrl()); } } - } - } + } + } - public function generateThumbnail($masterFile, $targetFile){ + public function generateThumbnail($masterFile, $targetFile) + { $size = $this->currentDimension; - require_once(AJXP_INSTALL_PATH."/plugins/editor.diaporama/PThumb.lib.php"); - $pThumb = new PThumb($this->getFilteredOption("THUMBNAIL_QUALITY")); - if(!$pThumb->isError()){ - $pThumb->remote_wrapper = $this->streamData["classname"]; + require_once(AJXP_INSTALL_PATH."/plugins/editor.diaporama/PThumb.lib.php"); + $pThumb = new PThumb($this->getFilteredOption("THUMBNAIL_QUALITY")); + if (!$pThumb->isError()) { + $pThumb->remote_wrapper = $this->streamData["classname"]; //AJXP_Logger::debug("Will fit thumbnail"); - $sizes = $pThumb->fit_thumbnail($masterFile, $size, -1, 1, true); + $sizes = $pThumb->fit_thumbnail($masterFile, $size, -1, 1, true); //AJXP_Logger::debug("Will print thumbnail"); - $pThumb->print_thumbnail($masterFile,$sizes[0],$sizes[1],false, false, $targetFile); + $pThumb->print_thumbnail($masterFile,$sizes[0],$sizes[1],false, false, $targetFile); //AJXP_Logger::debug("Done"); - if($pThumb->isError()){ - print_r($pThumb->error_array); - AJXP_Logger::logAction("error", $pThumb->error_array); - return false; - } - }else{ - print_r($pThumb->error_array); - AJXP_Logger::logAction("error", $pThumb->error_array); - return false; - } - } - - //public function extractImageMetadata($currentNode, &$metadata, $wrapperClassName, &$realFile){ - /** - * Enrich node metadata - * @param AJXP_Node $ajxpNode - */ - public function extractImageMetadata(&$ajxpNode){ - $currentPath = $ajxpNode->getUrl(); - $wrapperClassName = $ajxpNode->wrapperClassName; - $isImage = AJXP_Utils::is_image($currentPath); - $ajxpNode->is_image = $isImage; - if(!$isImage) return; - $setRemote = false; - $remoteWrappers = $this->getFilteredOption("META_EXTRACTION_REMOTEWRAPPERS"); - if(is_string($remoteWrappers)){ + if ($pThumb->isError()) { + print_r($pThumb->error_array); + AJXP_Logger::logAction("error", $pThumb->error_array); + return false; + } + } else { + print_r($pThumb->error_array); + AJXP_Logger::logAction("error", $pThumb->error_array); + return false; + } + } + + //public function extractImageMetadata($currentNode, &$metadata, $wrapperClassName, &$realFile){ + /** + * Enrich node metadata + * @param AJXP_Node $ajxpNode + */ + public function extractImageMetadata(&$ajxpNode) + { + $currentPath = $ajxpNode->getUrl(); + $wrapperClassName = $ajxpNode->wrapperClassName; + $isImage = AJXP_Utils::is_image($currentPath); + $ajxpNode->is_image = $isImage; + if(!$isImage) return; + $setRemote = false; + $remoteWrappers = $this->getFilteredOption("META_EXTRACTION_REMOTEWRAPPERS"); + if (is_string($remoteWrappers)) { $remoteWrappers = explode(",",$remoteWrappers); } - $remoteThreshold = $this->getFilteredOption("META_EXTRACTION_THRESHOLD"); - if(in_array($wrapperClassName, $remoteWrappers)){ - if($remoteThreshold != 0 && isSet($ajxpNode->bytesize)){ - $setRemote = ($ajxpNode->bytesize > $remoteThreshold); - }else{ - $setRemote = true; - } - } - if($isImage) - { - if($setRemote){ - $ajxpNode->image_type = "N/A"; - $ajxpNode->image_width = "N/A"; - $ajxpNode->image_height = "N/A"; - $ajxpNode->readable_dimension = ""; - }else{ - $realFile = $ajxpNode->getRealFile(); - list($width, $height, $type, $attr) = @getimagesize($realFile); - $ajxpNode->image_type = image_type_to_mime_type($type); - $ajxpNode->image_width = $width; - $ajxpNode->image_height = $height; - $ajxpNode->readable_dimension = $width."px X ".$height."px"; - } - } - //AJXP_Logger::debug("CURRENT NODE IN EXTRACT IMAGE METADATA ", $ajxpNode); - } - - protected function handleMime($filename){ - $mimesAtt = explode(",", $this->xPath->query("@mimes")->item(0)->nodeValue); - $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); - return in_array($ext, $mimesAtt); - } - + $remoteThreshold = $this->getFilteredOption("META_EXTRACTION_THRESHOLD"); + if (in_array($wrapperClassName, $remoteWrappers)) { + if ($remoteThreshold != 0 && isSet($ajxpNode->bytesize)) { + $setRemote = ($ajxpNode->bytesize > $remoteThreshold); + } else { + $setRemote = true; + } + } + if ($isImage) { + if ($setRemote) { + $ajxpNode->image_type = "N/A"; + $ajxpNode->image_width = "N/A"; + $ajxpNode->image_height = "N/A"; + $ajxpNode->readable_dimension = ""; + } else { + $realFile = $ajxpNode->getRealFile(); + list($width, $height, $type, $attr) = @getimagesize($realFile); + $ajxpNode->image_type = image_type_to_mime_type($type); + $ajxpNode->image_width = $width; + $ajxpNode->image_height = $height; + $ajxpNode->readable_dimension = $width."px X ".$height."px"; + } + } + //AJXP_Logger::debug("CURRENT NODE IN EXTRACT IMAGE METADATA ", $ajxpNode); + } + + protected function handleMime($filename) + { + $mimesAtt = explode(",", $this->xPath->query("@mimes")->item(0)->nodeValue); + $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + return in_array($ext, $mimesAtt); + } + } -?> \ No newline at end of file diff --git a/core/src/plugins/editor.diaporama/i18n/conf/en.php b/core/src/plugins/editor.diaporama/i18n/conf/en.php index f6ef6e621d..cde2ed6278 100644 --- a/core/src/plugins/editor.diaporama/i18n/conf/en.php +++ b/core/src/plugins/editor.diaporama/i18n/conf/en.php @@ -30,4 +30,3 @@ "Quality" => "Quality", "Thumbs quality" => "Thumbs quality", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.diaporama/i18n/conf/fr.php b/core/src/plugins/editor.diaporama/i18n/conf/fr.php index 02e4d444e8..59a850f74f 100644 --- a/core/src/plugins/editor.diaporama/i18n/conf/fr.php +++ b/core/src/plugins/editor.diaporama/i18n/conf/fr.php @@ -30,4 +30,3 @@ "Quality" => "Qualité", "Thumbs quality" => "Qualité pour le rendu de la vignette.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.diaporama/i18n/conf/pt.php b/core/src/plugins/editor.diaporama/i18n/conf/pt.php index 9085588d56..c5291bb498 100644 --- a/core/src/plugins/editor.diaporama/i18n/conf/pt.php +++ b/core/src/plugins/editor.diaporama/i18n/conf/pt.php @@ -30,4 +30,3 @@ "Quality" => "Qualidade", "Thumbs quality" => "Qualidade das miniaturas", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.diaporama/manifest.xml b/core/src/plugins/editor.diaporama/manifest.xml index 17fd5bcc02..59cec08427 100644 --- a/core/src/plugins/editor.diaporama/manifest.xml +++ b/core/src/plugins/editor.diaporama/manifest.xml @@ -40,11 +40,11 @@ - + - + @@ -55,13 +55,13 @@ - - + - + @@ -111,6 +111,6 @@ ]]> - + - \ No newline at end of file + diff --git a/core/src/plugins/editor.eml/class.EmlParser.php b/core/src/plugins/editor.eml/class.EmlParser.php index 3862ce327a..2d163827dc 100644 --- a/core/src/plugins/editor.eml/class.EmlParser.php +++ b/core/src/plugins/editor.eml/class.EmlParser.php @@ -1,482 +1,490 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * Parses an EML file and return the result as XML - * @package AjaXplorer_Plugins - * @subpackage Editor - */ -class EmlParser extends AJXP_Plugin{ - - public static $currentListingOnlyEmails; - - public function performChecks(){ - if(!AJXP_Utils::searchIncludePath("Mail/mimeDecode.php")){ - throw new Exception("Cannot find Mail/mimeDecode PEAR library"); - } - } - - public function switchAction($action, $httpVars, $filesVars){ - - if(!isSet($this->actions[$action])) return false; - - $repository = ConfService::getRepository(); - if(!$repository->detectStreamWrapper(true)){ - return false; - } - - $streamData = $repository->streamData; - $destStreamURL = $streamData["protocol"]."://".$repository->getId(); - $wrapperClassName = $streamData["classname"]; - if(empty($httpVars["file"])) return; - $file = $destStreamURL.AJXP_Utils::decodeSecureMagic($httpVars["file"]); - $mess = ConfService::getMessages(); - - $node = new AJXP_Node($file); - AJXP_Controller::applyHook("node.read", array($node)); - - - switch($action){ - case "eml_get_xml_structure": - $params = array( - 'include_bodies' => false, - 'decode_bodies' => false, - 'decode_headers' => 'UTF-8' - ); - $decoder = $this->getStructureDecoder($file, ($wrapperClassName == "imapAccessWrapper")); - $xml = $decoder->getXML($decoder->decode($params)); - if(function_exists("imap_mime_header_decode")){ - $doc = new DOMDocument(); - $doc->loadXML($xml); - $xPath = new DOMXPath($doc); - $headers = $xPath->query("//headername"); - $changes = false; - foreach ($headers as $headerNode){ - if($headerNode->firstChild->nodeValue == "Subject"){ - $headerValueNode = $headerNode->nextSibling->nextSibling; - $value = $headerValueNode->nodeValue; - $elements = imap_mime_header_decode($value); - $decoded = ""; - foreach($elements as $element){ - $decoded.=$element->text; - $charset = $element->charset; - } - if($decoded != $value){ - $value = SystemTextEncoding::changeCharset($charset, "UTF-8", $decoded); - $node = $doc->createElement("headervalue", $value); - $res = $headerNode->parentNode->replaceChild($node, $headerValueNode); - $changes = true; - } - } - } - if($changes) $xml = $doc->saveXML(); - } - print $xml; - break; - case "eml_get_bodies": - require_once("Mail/mimeDecode.php"); - $params = array( - 'include_bodies' => true, - 'decode_bodies' => true, - 'decode_headers' => false - ); - if($wrapperClassName == "imapAccessWrapper"){ - $cache = AJXP_Cache::getItem("eml_remote", $file, null, array("EmlParser", "computeCacheId")); - $content = $cache->getData(); - }else{ - $content = file_get_contents($file); - } - - $decoder = new Mail_mimeDecode($content); - $structure = $decoder->decode($params); - $html = $this->_findPartByCType($structure, "text", "html"); - $text = $this->_findPartByCType($structure, "text", "plain"); - if($html != false && isSet($html->ctype_parameters) && isSet($html->ctype_parameters["charset"])){ - $charset = $html->ctype_parameters["charset"]; - } - if(isSet($charset)){ - header('Content-Type: text/xml; charset='.$charset); - header('Cache-Control: no-cache'); - print(''); - print(''); - }else{ - AJXP_XMLWriter::header("email_body"); - } - if($html!==false){ - print('body; - print($text); - print("]]>"); - } - if($text!==false){ - print('body); - print("]]>"); - } - AJXP_XMLWriter::close("email_body"); - - break; - case "eml_dl_attachment": - $attachId = $httpVars["attachment_id"]; - if(!isset($attachId)) break; - - require_once("Mail/mimeDecode.php"); - $params = array( - 'include_bodies' => true, - 'decode_bodies' => true, - 'decode_headers' => false - ); - if($wrapperClassName == "imapAccessWrapper"){ - $cache = AJXP_Cache::getItem("eml_remote", $file, null, array("EmlParser", "computeCacheId")); - $content = $cache->getData(); - }else{ - $content = file_get_contents($file); - } - $decoder = new Mail_mimeDecode($content); - $structure = $decoder->decode($params); - $part = $this->_findAttachmentById($structure, $attachId); - if($part !== false){ - $fake = new fsAccessDriver("fake", ""); - $fake->readFile($part->body, "file", $part->d_parameters['filename'], true); - exit(); - }else{ - //var_dump($structure); - } - break; - case "eml_cp_attachment": - $attachId = $httpVars["attachment_id"]; - $destRep = AJXP_Utils::decodeSecureMagic($httpVars["destination"]); - if(!isset($attachId)) { - AJXP_XMLWriter::sendMessage(null, "Wrong Parameters"); - break; - } - - require_once("Mail/mimeDecode.php"); - $params = array( - 'include_bodies' => true, - 'decode_bodies' => true, - 'decode_headers' => false - ); - if($wrapperClassName == "imapAccessWrapper"){ - $cache = AJXP_Cache::getItem("eml_remote", $file, null, array("EmlParser", "computeCacheId")); - $content = $cache->getData(); - }else{ - $content = file_get_contents($file); - } - - $decoder = new Mail_mimeDecode($content); - $structure = $decoder->decode($params); - $part = $this->_findAttachmentById($structure, $attachId); - AJXP_XMLWriter::header(); - if($part !== false){ - if(isSet($httpVars["dest_repository_id"])){ - $destRepoId = $httpVars["dest_repository_id"]; - if(AuthService::usersEnabled()){ - $loggedUser = AuthService::getLoggedUser(); - if(!$loggedUser->canWrite($destRepoId)) throw new Exception($mess[364]); - } - $destRepoObject = ConfService::getRepositoryById($destRepoId); - $destRepoAccess = $destRepoObject->getAccessType(); - $plugin = AJXP_PluginsService::findPlugin("access", $destRepoAccess); - $destWrapperData = $plugin->detectStreamWrapper(true); - $destStreamURL = $destWrapperData["protocol"]."://$destRepoId"; - } - $destFile = $destStreamURL.$destRep."/".$part->d_parameters['filename']; - $fp = fopen($destFile, "w"); - if($fp !== false){ - fwrite($fp, $part->body, strlen($part->body)); - fclose($fp); - AJXP_XMLWriter::sendMessage(sprintf($mess["editor.eml.7"], $part->d_parameters["filename"], $destRep), NULL); - }else{ - AJXP_XMLWriter::sendMessage(null, $mess["editor.eml.8"]); - } - }else{ - AJXP_XMLWriter::sendMessage(null, $mess["editor.eml.9"]); - } - AJXP_XMLWriter::close(); - break; - - default: - break; - } - } - - /** - * @param AJXP_Node $ajxpNode - * @param Boolean $isParent - */ - public function extractMimeHeaders(&$ajxpNode, $isParent = false){ - if($isParent) return; - $currentNode = $ajxpNode->getUrl(); - $metadata = $ajxpNode->metadata; - $wrapperClassName = $ajxpNode->wrapperClassName; - - $noMail = true; - if($metadata["is_file"] && ($wrapperClassName == "imapAccessWrapper" || preg_match("/\.eml$/i",$currentNode))){ - $noMail = false; - } - if($wrapperClassName == "imapAccessWrapper" && !$metadata["is_file"]){ - $metadata["mimestring"] = "Mailbox"; - } - $parsed = parse_url($currentNode); - if( $noMail || ( isSet($parsed["fragment"]) && strpos($parsed["fragment"], "attachments") === 0 ) ){ - EmlParser::$currentListingOnlyEmails = FALSE; - return; - } - if(EmlParser::$currentListingOnlyEmails === NULL){ - EmlParser::$currentListingOnlyEmails = true; - } - if($wrapperClassName == "imapAccessWrapper"){ - $cachedFile = AJXP_Cache::getItem("eml_remote", $currentNode, null, array("EmlParser", "computeCacheId")); - $realFile = $cachedFile->getId(); - if(!is_file($realFile)){ - $cachedFile->getData();// trigger loading! - } - }else{ - $realFile = $ajxpNode->getRealFile(); - } - $cacheItem = AJXP_Cache::getItem("eml_mimes", $realFile, array($this, "mimeExtractorCallback")); - $data = unserialize($cacheItem->getData()); - $data["ajxp_mime"] = "eml"; - $data["mimestring"] = "Email"; - $metadata = array_merge($metadata, $data); - if($wrapperClassName == "imapAccessWrapper" && $metadata["eml_attachments"]!= "0" && (strpos($_SERVER["HTTP_USER_AGENT"], "ajaxplorer-ios") !== false)){ - $metadata["is_file"] = false; - $metadata["nodeName"] = basename($currentNode)."#attachments"; - } - $ajxpNode->metadata = $metadata; - } - - public function mimeExtractorCallback($masterFile, $targetFile){ - $metadata = array(); - require_once("Mail/mimeDecode.php"); - $params = array( - 'include_bodies' => true, - 'decode_bodies' => false, - 'decode_headers' => 'UTF-8' - ); - $mess = ConfService::getMessages(); - $content = file_get_contents($masterFile); - $decoder = new Mail_mimeDecode($content); - $structure = $decoder->decode($params); - $allowedHeaders = array("to", "from", "subject", "message-id", "mime-version", "date", "return-path"); - foreach ($structure->headers as $hKey => $hValue){ - if(!in_array($hKey, $allowedHeaders)) continue; - if(is_array($hValue)){ - $hValue = implode(", ", $hValue); - } - if($hKey == "date"){ - $date = strtotime($hValue); - $metadata["eml_time"] = $date; - } - $metadata["eml_".$hKey] = AJXP_Utils::xmlEntities(@htmlentities($hValue, ENT_COMPAT, "UTF-8")); - //AJXP_Logger::debug($hKey." - ".$hValue. " - ".$metadata["eml_".$hKey]); - if($metadata["eml_".$hKey] == ""){ - $metadata["eml_".$hKey] = AJXP_Utils::xmlEntities(@htmlentities($hValue)); - if(!SystemTextEncoding::isUtf8($metadata["eml_".$hKey])) { - $metadata["eml_".$hKey] = SystemTextEncoding::toUTF8($metadata["eml_".$hKey]); - } - } - $metadata["eml_".$hKey] = str_replace("&", "&", $metadata["eml_".$hKey]); - } - $metadata["eml_attachments"] = 0; - $parts = $structure->parts; - if(!empty($parts)){ - foreach($parts as $mimePart){ - if(!empty($mimePart->disposition) && $mimePart->disposition == "attachment"){ - $metadata["eml_attachments"]++; - } - } - } - $metadata["icon"] = "eml_images/ICON_SIZE/mail_mime.png"; - file_put_contents($targetFile, serialize($metadata)); - } - - public function lsPostProcess($action, $httpVars, $outputVars){ - if(!EmlParser::$currentListingOnlyEmails){ - if(isSet($httpVars["playlist"])) return; - header('Content-Type: text/xml; charset=UTF-8'); - header('Cache-Control: no-cache'); - print($outputVars["ob_output"]); - return; - } - - $config = ' - - - - - - - '; - - $dom = new DOMDocument("1.0", "UTF-8"); - $dom->loadXML($outputVars["ob_output"]); - $mobileAgent = AJXP_Utils::userAgentIsIOS() || (strpos($_SERVER["HTTP_USER_AGENT"], "ajaxplorer-ios-client")!==false); - AJXP_Logger::debug("MOBILE AGENT DETECTED?".$mobileAgent, $_SERVER["HTTP_USER_AGENT"]); - if(EmlParser::$currentListingOnlyEmails === true){ - // Replace all text attributes by the "from" value - $index = 1; - foreach ($dom->documentElement->childNodes as $child){ - if($mobileAgent){ - $from = $child->getAttribute("eml_from"); - $ar = explode("<", $from); - $from = trim(array_shift($ar)); - $text = ($index < 10?"0":"").$index.". ".$from." > ".$child->getAttribute("eml_subject"); - if((strpos($_SERVER["HTTP_USER_AGENT"], "ajaxplorer-ios-client")!==false)){ - $text = html_entity_decode($text, ENT_COMPAT, "UTF-8"); - } - $index ++; - }else{ - $text = $child->getAttribute("eml_from"); - } - $child->setAttribute("text", $text); - $child->setAttribute("ajxp_modiftime", $child->getAttribute("eml_time")); - } - } - - // Add the columns template definition - $insert = new DOMDocument("1.0", "UTF-8"); - $config = "$config"; - $insert->loadXML($config); - $imported = $dom->importNode($insert->documentElement, true); - $dom->documentElement->appendChild($imported); - header('Content-Type: text/xml; charset=UTF-8'); - header('Cache-Control: no-cache'); - print($dom->saveXML()); - } - - /** - * - * Enter description here ... - * @param string $file url - * @param boolean $cacheRemoteContent - * @return Mail_mimeDecode - */ - public function getStructureDecoder($file, $cacheRemoteContent = false){ - require_once ("Mail/mimeDecode.php"); - if ($cacheRemoteContent) { - $cache = AJXP_Cache::getItem ( "eml_remote", $file , null, array("EmlParser", "computeCacheId")); - $content = $cache->getData (); - } else { - $content = file_get_contents ( $file ); - } - $decoder = new Mail_mimeDecode ( $content ); - - header ( 'Content-Type: text/xml; charset=UTF-8' ); - header ( 'Cache-Control: no-cache' ); - return $decoder; - } - - public function listAttachments($file, $cacheRemoteContent = false, &$attachments, $structure = null){ - if($structure == null){ - $decoder = $this->getStructureDecoder($file, $cacheRemoteContent); - $params = array( - 'include_bodies' => false, - 'decode_bodies' => false, - 'decode_headers' => 'UTF-8' - ); - $structure = $decoder->decode($params); - } - if(isSet($structure->disposition) && $structure->disposition == "attachment"){ - $attachments[] = array( - "filename" => $structure->d_parameters['filename'], - "content-type" => $structure->ctype_primary."/".$structure->ctype_secondary, - "x-attachment-id" => (isSet($structure->headers["x-attachment-id"])?$structure->headers["x-attachment-id"]:count($attachments)) - ); - }else if(isset($structure->parts)){ - foreach ($structure->parts as $partObject){ - $this->listAttachments($file, true, $attachments, $partObject); - } - } - } - - public function getAttachmentBody($file, $attachmentId, $cacheRemoteContent = false, &$metadata = array()){ - $decoder = $this->getStructureDecoder($file, $cacheRemoteContent); - $params = array( - 'include_bodies' => true, - 'decode_bodies' => true, - 'decode_headers' => 'UTF-8' - ); - $structure = $decoder->decode($params); - $part = $this->_findAttachmentById($structure, $attachmentId); - if($part == false) return false; - $metadata = array( - "filename" => $part->d_parameters['filename'], - "content-type" => $part->ctype_primary."/".$part->ctype_secondary, - "x-attachment-id" => $attachmentId - ); - return $part->body; - } - - protected function _findPartByCType($structure, $primary, $secondary){ - if($structure->ctype_primary == $primary && $structure->ctype_secondary == $secondary){ - return $structure; - } - if(empty($structure->parts)) return false; - foreach($structure->parts as $part){ - $res = $this->_findPartByCType($part, $primary, $secondary); - if($res !== false){ - return $res; - } - } - return false; - } - - protected function _findAttachmentById($structure, $attachId){ - if(is_numeric($attachId)){ - $attachId = intval($attachId); - if(empty($structure->parts)) return false; - $index = 0; - foreach ($structure->parts as $part){ - if(!empty($part->disposition) && $part->disposition == "attachment"){ - if($index == $attachId) return $part; - $index++; - } - } - return false; - }else{ - if(!empty($structure->disposition) && $structure->disposition == "attachment" - && ($structure->headers["x-attachment-id"] == $attachId || $attachId == "0" )){ - return $structure; - } - if(empty($structure->parts)) return false; - foreach($structure->parts as $part){ - $res = $this->_findAttachmentById($part, $attachId); - if($res !== false){ - return $res; - } - } - return false; - } - } - - static public function computeCacheId($mailPath){ - $header = file_get_contents($mailPath."#header"); - //AJXP_Logger::debug("Headers ", $header); - return md5($header); - } - -} - -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * Parses an EML file and return the result as XML + * @package AjaXplorer_Plugins + * @subpackage Editor + */ +class EmlParser extends AJXP_Plugin +{ + public static $currentListingOnlyEmails; + + public function performChecks() + { + if (!AJXP_Utils::searchIncludePath("Mail/mimeDecode.php")) { + throw new Exception("Cannot find Mail/mimeDecode PEAR library"); + } + } + + public function switchAction($action, $httpVars, $filesVars) + { + if(!isSet($this->actions[$action])) return false; + + $repository = ConfService::getRepository(); + if (!$repository->detectStreamWrapper(true)) { + return false; + } + + $streamData = $repository->streamData; + $destStreamURL = $streamData["protocol"]."://".$repository->getId(); + $wrapperClassName = $streamData["classname"]; + if(empty($httpVars["file"])) return; + $file = $destStreamURL.AJXP_Utils::decodeSecureMagic($httpVars["file"]); + $mess = ConfService::getMessages(); + + $node = new AJXP_Node($file); + AJXP_Controller::applyHook("node.read", array($node)); + + + switch ($action) { + case "eml_get_xml_structure": + $params = array( + 'include_bodies' => false, + 'decode_bodies' => false, + 'decode_headers' => 'UTF-8' + ); + $decoder = $this->getStructureDecoder($file, ($wrapperClassName == "imapAccessWrapper")); + $xml = $decoder->getXML($decoder->decode($params)); + if (function_exists("imap_mime_header_decode")) { + $doc = new DOMDocument(); + $doc->loadXML($xml); + $xPath = new DOMXPath($doc); + $headers = $xPath->query("//headername"); + $changes = false; + foreach ($headers as $headerNode) { + if ($headerNode->firstChild->nodeValue == "Subject") { + $headerValueNode = $headerNode->nextSibling->nextSibling; + $value = $headerValueNode->nodeValue; + $elements = imap_mime_header_decode($value); + $decoded = ""; + foreach ($elements as $element) { + $decoded.=$element->text; + $charset = $element->charset; + } + if ($decoded != $value) { + $value = SystemTextEncoding::changeCharset($charset, "UTF-8", $decoded); + $node = $doc->createElement("headervalue", $value); + $res = $headerNode->parentNode->replaceChild($node, $headerValueNode); + $changes = true; + } + } + } + if($changes) $xml = $doc->saveXML(); + } + print $xml; + break; + case "eml_get_bodies": + require_once("Mail/mimeDecode.php"); + $params = array( + 'include_bodies' => true, + 'decode_bodies' => true, + 'decode_headers' => false + ); + if ($wrapperClassName == "imapAccessWrapper") { + $cache = AJXP_Cache::getItem("eml_remote", $file, null, array("EmlParser", "computeCacheId")); + $content = $cache->getData(); + } else { + $content = file_get_contents($file); + } + + $decoder = new Mail_mimeDecode($content); + $structure = $decoder->decode($params); + $html = $this->_findPartByCType($structure, "text", "html"); + $text = $this->_findPartByCType($structure, "text", "plain"); + if ($html != false && isSet($html->ctype_parameters) && isSet($html->ctype_parameters["charset"])) { + $charset = $html->ctype_parameters["charset"]; + } + if (isSet($charset)) { + header('Content-Type: text/xml; charset='.$charset); + header('Cache-Control: no-cache'); + print(''); + print(''); + } else { + AJXP_XMLWriter::header("email_body"); + } + if ($html!==false) { + print('body; + print($text); + print("]]>"); + } + if ($text!==false) { + print('body); + print("]]>"); + } + AJXP_XMLWriter::close("email_body"); + + break; + case "eml_dl_attachment": + $attachId = $httpVars["attachment_id"]; + if(!isset($attachId)) break; + + require_once("Mail/mimeDecode.php"); + $params = array( + 'include_bodies' => true, + 'decode_bodies' => true, + 'decode_headers' => false + ); + if ($wrapperClassName == "imapAccessWrapper") { + $cache = AJXP_Cache::getItem("eml_remote", $file, null, array("EmlParser", "computeCacheId")); + $content = $cache->getData(); + } else { + $content = file_get_contents($file); + } + $decoder = new Mail_mimeDecode($content); + $structure = $decoder->decode($params); + $part = $this->_findAttachmentById($structure, $attachId); + if ($part !== false) { + $fake = new fsAccessDriver("fake", ""); + $fake->readFile($part->body, "file", $part->d_parameters['filename'], true); + exit(); + } else { + //var_dump($structure); + } + break; + case "eml_cp_attachment": + $attachId = $httpVars["attachment_id"]; + $destRep = AJXP_Utils::decodeSecureMagic($httpVars["destination"]); + if (!isset($attachId)) { + AJXP_XMLWriter::sendMessage(null, "Wrong Parameters"); + break; + } + + require_once("Mail/mimeDecode.php"); + $params = array( + 'include_bodies' => true, + 'decode_bodies' => true, + 'decode_headers' => false + ); + if ($wrapperClassName == "imapAccessWrapper") { + $cache = AJXP_Cache::getItem("eml_remote", $file, null, array("EmlParser", "computeCacheId")); + $content = $cache->getData(); + } else { + $content = file_get_contents($file); + } + + $decoder = new Mail_mimeDecode($content); + $structure = $decoder->decode($params); + $part = $this->_findAttachmentById($structure, $attachId); + AJXP_XMLWriter::header(); + if ($part !== false) { + if (isSet($httpVars["dest_repository_id"])) { + $destRepoId = $httpVars["dest_repository_id"]; + if (AuthService::usersEnabled()) { + $loggedUser = AuthService::getLoggedUser(); + if(!$loggedUser->canWrite($destRepoId)) throw new Exception($mess[364]); + } + $destRepoObject = ConfService::getRepositoryById($destRepoId); + $destRepoAccess = $destRepoObject->getAccessType(); + $plugin = AJXP_PluginsService::findPlugin("access", $destRepoAccess); + $destWrapperData = $plugin->detectStreamWrapper(true); + $destStreamURL = $destWrapperData["protocol"]."://$destRepoId"; + } + $destFile = $destStreamURL.$destRep."/".$part->d_parameters['filename']; + $fp = fopen($destFile, "w"); + if ($fp !== false) { + fwrite($fp, $part->body, strlen($part->body)); + fclose($fp); + AJXP_XMLWriter::sendMessage(sprintf($mess["editor.eml.7"], $part->d_parameters["filename"], $destRep), NULL); + } else { + AJXP_XMLWriter::sendMessage(null, $mess["editor.eml.8"]); + } + } else { + AJXP_XMLWriter::sendMessage(null, $mess["editor.eml.9"]); + } + AJXP_XMLWriter::close(); + break; + + default: + break; + } + } + + /** + * @param AJXP_Node $ajxpNode + * @param Boolean $isParent + */ + public function extractMimeHeaders(&$ajxpNode, $isParent = false) + { + if($isParent) return; + $currentNode = $ajxpNode->getUrl(); + $metadata = $ajxpNode->metadata; + $wrapperClassName = $ajxpNode->wrapperClassName; + + $noMail = true; + if ($metadata["is_file"] && ($wrapperClassName == "imapAccessWrapper" || preg_match("/\.eml$/i",$currentNode))) { + $noMail = false; + } + if ($wrapperClassName == "imapAccessWrapper" && !$metadata["is_file"]) { + $metadata["mimestring"] = "Mailbox"; + } + $parsed = parse_url($currentNode); + if ( $noMail || ( isSet($parsed["fragment"]) && strpos($parsed["fragment"], "attachments") === 0 ) ) { + EmlParser::$currentListingOnlyEmails = FALSE; + return; + } + if (EmlParser::$currentListingOnlyEmails === NULL) { + EmlParser::$currentListingOnlyEmails = true; + } + if ($wrapperClassName == "imapAccessWrapper") { + $cachedFile = AJXP_Cache::getItem("eml_remote", $currentNode, null, array("EmlParser", "computeCacheId")); + $realFile = $cachedFile->getId(); + if (!is_file($realFile)) { + $cachedFile->getData();// trigger loading! + } + } else { + $realFile = $ajxpNode->getRealFile(); + } + $cacheItem = AJXP_Cache::getItem("eml_mimes", $realFile, array($this, "mimeExtractorCallback")); + $data = unserialize($cacheItem->getData()); + $data["ajxp_mime"] = "eml"; + $data["mimestring"] = "Email"; + $metadata = array_merge($metadata, $data); + if ($wrapperClassName == "imapAccessWrapper" && $metadata["eml_attachments"]!= "0" && (strpos($_SERVER["HTTP_USER_AGENT"], "ajaxplorer-ios") !== false)) { + $metadata["is_file"] = false; + $metadata["nodeName"] = basename($currentNode)."#attachments"; + } + $ajxpNode->metadata = $metadata; + } + + public function mimeExtractorCallback($masterFile, $targetFile) + { + $metadata = array(); + require_once("Mail/mimeDecode.php"); + $params = array( + 'include_bodies' => true, + 'decode_bodies' => false, + 'decode_headers' => 'UTF-8' + ); + $mess = ConfService::getMessages(); + $content = file_get_contents($masterFile); + $decoder = new Mail_mimeDecode($content); + $structure = $decoder->decode($params); + $allowedHeaders = array("to", "from", "subject", "message-id", "mime-version", "date", "return-path"); + foreach ($structure->headers as $hKey => $hValue) { + if(!in_array($hKey, $allowedHeaders)) continue; + if (is_array($hValue)) { + $hValue = implode(", ", $hValue); + } + if ($hKey == "date") { + $date = strtotime($hValue); + $metadata["eml_time"] = $date; + } + $metadata["eml_".$hKey] = AJXP_Utils::xmlEntities(@htmlentities($hValue, ENT_COMPAT, "UTF-8")); + //AJXP_Logger::debug($hKey." - ".$hValue. " - ".$metadata["eml_".$hKey]); + if ($metadata["eml_".$hKey] == "") { + $metadata["eml_".$hKey] = AJXP_Utils::xmlEntities(@htmlentities($hValue)); + if (!SystemTextEncoding::isUtf8($metadata["eml_".$hKey])) { + $metadata["eml_".$hKey] = SystemTextEncoding::toUTF8($metadata["eml_".$hKey]); + } + } + $metadata["eml_".$hKey] = str_replace("&", "&", $metadata["eml_".$hKey]); + } + $metadata["eml_attachments"] = 0; + $parts = $structure->parts; + if (!empty($parts)) { + foreach ($parts as $mimePart) { + if (!empty($mimePart->disposition) && $mimePart->disposition == "attachment") { + $metadata["eml_attachments"]++; + } + } + } + $metadata["icon"] = "eml_images/ICON_SIZE/mail_mime.png"; + file_put_contents($targetFile, serialize($metadata)); + } + + public function lsPostProcess($action, $httpVars, $outputVars) + { + if (!EmlParser::$currentListingOnlyEmails) { + if(isSet($httpVars["playlist"])) return; + header('Content-Type: text/xml; charset=UTF-8'); + header('Cache-Control: no-cache'); + print($outputVars["ob_output"]); + return; + } + + $config = ' + + + + + + + '; + + $dom = new DOMDocument("1.0", "UTF-8"); + $dom->loadXML($outputVars["ob_output"]); + $mobileAgent = AJXP_Utils::userAgentIsIOS() || (strpos($_SERVER["HTTP_USER_AGENT"], "ajaxplorer-ios-client")!==false); + AJXP_Logger::debug("MOBILE AGENT DETECTED?".$mobileAgent, $_SERVER["HTTP_USER_AGENT"]); + if (EmlParser::$currentListingOnlyEmails === true) { + // Replace all text attributes by the "from" value + $index = 1; + foreach ($dom->documentElement->childNodes as $child) { + if ($mobileAgent) { + $from = $child->getAttribute("eml_from"); + $ar = explode("<", $from); + $from = trim(array_shift($ar)); + $text = ($index < 10?"0":"").$index.". ".$from." > ".$child->getAttribute("eml_subject"); + if ((strpos($_SERVER["HTTP_USER_AGENT"], "ajaxplorer-ios-client")!==false)) { + $text = html_entity_decode($text, ENT_COMPAT, "UTF-8"); + } + $index ++; + } else { + $text = $child->getAttribute("eml_from"); + } + $child->setAttribute("text", $text); + $child->setAttribute("ajxp_modiftime", $child->getAttribute("eml_time")); + } + } + + // Add the columns template definition + $insert = new DOMDocument("1.0", "UTF-8"); + $config = "$config"; + $insert->loadXML($config); + $imported = $dom->importNode($insert->documentElement, true); + $dom->documentElement->appendChild($imported); + header('Content-Type: text/xml; charset=UTF-8'); + header('Cache-Control: no-cache'); + print($dom->saveXML()); + } + + /** + * + * Enter description here ... + * @param string $file url + * @param boolean $cacheRemoteContent + * @return Mail_mimeDecode + */ + public function getStructureDecoder($file, $cacheRemoteContent = false) + { + require_once ("Mail/mimeDecode.php"); + if ($cacheRemoteContent) { + $cache = AJXP_Cache::getItem ( "eml_remote", $file , null, array("EmlParser", "computeCacheId")); + $content = $cache->getData (); + } else { + $content = file_get_contents ( $file ); + } + $decoder = new Mail_mimeDecode ( $content ); + + header ( 'Content-Type: text/xml; charset=UTF-8' ); + header ( 'Cache-Control: no-cache' ); + return $decoder; + } + + public function listAttachments($file, $cacheRemoteContent = false, &$attachments, $structure = null) + { + if ($structure == null) { + $decoder = $this->getStructureDecoder($file, $cacheRemoteContent); + $params = array( + 'include_bodies' => false, + 'decode_bodies' => false, + 'decode_headers' => 'UTF-8' + ); + $structure = $decoder->decode($params); + } + if (isSet($structure->disposition) && $structure->disposition == "attachment") { + $attachments[] = array( + "filename" => $structure->d_parameters['filename'], + "content-type" => $structure->ctype_primary."/".$structure->ctype_secondary, + "x-attachment-id" => (isSet($structure->headers["x-attachment-id"])?$structure->headers["x-attachment-id"]:count($attachments)) + ); + } else if (isset($structure->parts)) { + foreach ($structure->parts as $partObject) { + $this->listAttachments($file, true, $attachments, $partObject); + } + } + } + + public function getAttachmentBody($file, $attachmentId, $cacheRemoteContent = false, &$metadata = array()) + { + $decoder = $this->getStructureDecoder($file, $cacheRemoteContent); + $params = array( + 'include_bodies' => true, + 'decode_bodies' => true, + 'decode_headers' => 'UTF-8' + ); + $structure = $decoder->decode($params); + $part = $this->_findAttachmentById($structure, $attachmentId); + if($part == false) return false; + $metadata = array( + "filename" => $part->d_parameters['filename'], + "content-type" => $part->ctype_primary."/".$part->ctype_secondary, + "x-attachment-id" => $attachmentId + ); + return $part->body; + } + + protected function _findPartByCType($structure, $primary, $secondary) + { + if ($structure->ctype_primary == $primary && $structure->ctype_secondary == $secondary) { + return $structure; + } + if(empty($structure->parts)) return false; + foreach ($structure->parts as $part) { + $res = $this->_findPartByCType($part, $primary, $secondary); + if ($res !== false) { + return $res; + } + } + return false; + } + + protected function _findAttachmentById($structure, $attachId) + { + if (is_numeric($attachId)) { + $attachId = intval($attachId); + if(empty($structure->parts)) return false; + $index = 0; + foreach ($structure->parts as $part) { + if (!empty($part->disposition) && $part->disposition == "attachment") { + if($index == $attachId) return $part; + $index++; + } + } + return false; + } else { + if(!empty($structure->disposition) && $structure->disposition == "attachment" + && ($structure->headers["x-attachment-id"] == $attachId || $attachId == "0" )){ + return $structure; + } + if(empty($structure->parts)) return false; + foreach ($structure->parts as $part) { + $res = $this->_findAttachmentById($part, $attachId); + if ($res !== false) { + return $res; + } + } + return false; + } + } + + public static function computeCacheId($mailPath) + { + $header = file_get_contents($mailPath."#header"); + //AJXP_Logger::debug("Headers ", $header); + return md5($header); + } + +} diff --git a/core/src/plugins/editor.eml/i18n/conf/en.php b/core/src/plugins/editor.eml/i18n/conf/en.php index 1d7fb7b029..20f1937792 100644 --- a/core/src/plugins/editor.eml/i18n/conf/en.php +++ b/core/src/plugins/editor.eml/i18n/conf/en.php @@ -22,4 +22,3 @@ "Email Viewer" => "Email Viewer", "Email reader, supports eml format and eml mimetypes. Detects if a folder contains only email and display columns accordingly." => "Email reader, supports eml format and eml mimetypes. Detects if a folder contains only email and display columns accordingly.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.eml/i18n/conf/fr.php b/core/src/plugins/editor.eml/i18n/conf/fr.php index 8807fc47cf..a149b927c3 100644 --- a/core/src/plugins/editor.eml/i18n/conf/fr.php +++ b/core/src/plugins/editor.eml/i18n/conf/fr.php @@ -22,4 +22,3 @@ "Email Viewer" => "Afficheur Mail", "Email reader, supports eml format and eml mimetypes. Detects if a folder contains only email and display columns accordingly." => "Lecteur d'email, support le format EML ou le mimetype dans les boites mails. Si un répertoire ne contient que des mails, affiche des colonnes plus adaptées.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.eml/i18n/conf/pt.php b/core/src/plugins/editor.eml/i18n/conf/pt.php index 9f76603061..d07403c789 100644 --- a/core/src/plugins/editor.eml/i18n/conf/pt.php +++ b/core/src/plugins/editor.eml/i18n/conf/pt.php @@ -22,4 +22,3 @@ "E-Mail Viewer" => "Visualizador de E-mail", "E-Mail reader, supports eml format and eml mimetypes. Detects if a folder contains only E-Mail and display columns accordingly." => "Leitor de E-mails, suporta formatos EML e tipo pequeno de EML. Consegue detectar se uma pasta apenas contém e-mails e mostra-os em colunas respectivamente.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.eml/i18n/de.php b/core/src/plugins/editor.eml/i18n/de.php index 3ef5ab7148..08f5e530b5 100644 --- a/core/src/plugins/editor.eml/i18n/de.php +++ b/core/src/plugins/editor.eml/i18n/de.php @@ -1,18 +1,17 @@ - "E-Mail Betrachter", -"title" => "E-Mail Betrachter", -"1" => "Von", -"2" => "An", -"3" => "Betreff", -"4" => "Datum", -"5" => "Anhänge", -"6" => "Download EML", -"7" => "Anhang %s wurde erfolgreich nach %s kopiert.", -"8" => "Zieldatei konnte nicht geöffnet werden!", -"9" => "Anhang wurde nicht gefunden!", -"10" => "Download ", -"11" => "Kopieren des Anhangs auf den Server", -"12" => "Cc", -); -?> + "E-Mail Betrachter", +"title" => "E-Mail Betrachter", +"1" => "Von", +"2" => "An", +"3" => "Betreff", +"4" => "Datum", +"5" => "Anhänge", +"6" => "Download EML", +"7" => "Anhang %s wurde erfolgreich nach %s kopiert.", +"8" => "Zieldatei konnte nicht geöffnet werden!", +"9" => "Anhang wurde nicht gefunden!", +"10" => "Download ", +"11" => "Kopieren des Anhangs auf den Server", +"12" => "Cc", +); diff --git a/core/src/plugins/editor.eml/i18n/en.php b/core/src/plugins/editor.eml/i18n/en.php index 60f12591cf..839e316bfa 100644 --- a/core/src/plugins/editor.eml/i18n/en.php +++ b/core/src/plugins/editor.eml/i18n/en.php @@ -1,18 +1,17 @@ - "Email Viewer", -"title" => "Email Viewer", -"1" => "From", -"2" => "To", -"3" => "Subject", -"4" => "Date", -"5" => "Attachments", -"6" => "Download EML", -"7" => "Attachment %s was successfully copied to %s", -"8" => "Could not open destination file!", -"9" => "Could not find attachment!", -"10" => "Download ", -"11" => "Copy attachment on the server", -"12" => "Cc", -); -?> \ No newline at end of file + "Email Viewer", +"title" => "Email Viewer", +"1" => "From", +"2" => "To", +"3" => "Subject", +"4" => "Date", +"5" => "Attachments", +"6" => "Download EML", +"7" => "Attachment %s was successfully copied to %s", +"8" => "Could not open destination file!", +"9" => "Could not find attachment!", +"10" => "Download ", +"11" => "Copy attachment on the server", +"12" => "Cc", +); diff --git a/core/src/plugins/editor.eml/i18n/et.php b/core/src/plugins/editor.eml/i18n/et.php index 780e4ebe11..9d4529dd8c 100644 --- a/core/src/plugins/editor.eml/i18n/et.php +++ b/core/src/plugins/editor.eml/i18n/et.php @@ -1,4 +1,4 @@ - // + updates/fixes by Kain Väljaots // Last update: 27.05.2013 @@ -19,4 +19,3 @@ "11" => "Kopeeri manus serveris", "12" => "Koopia", ); -?> diff --git a/core/src/plugins/editor.eml/i18n/fr.php b/core/src/plugins/editor.eml/i18n/fr.php index 2ddfb4a0bb..d9f50adeb8 100644 --- a/core/src/plugins/editor.eml/i18n/fr.php +++ b/core/src/plugins/editor.eml/i18n/fr.php @@ -1,18 +1,17 @@ - "Editeur Email", -"title" => "Editeur Email", -"1" => "De", -"2" => "A", -"3" => "Sujet", -"4" => "Date", -"5" => "Attachements", -"6" => "Télécharger EML", -"7" => "L'attachement %s a été copié avec succès dans %s", -"8" => "Impossible d'ouvrir le fichier de destination!", -"9" => "Impossible de trouver l'attachement", -"10" => "Télécharger ", -"11" => "Copier l'attachement sur le serveur", -"12" => "Cc", -); -?> \ No newline at end of file + "Editeur Email", +"title" => "Editeur Email", +"1" => "De", +"2" => "A", +"3" => "Sujet", +"4" => "Date", +"5" => "Attachements", +"6" => "Télécharger EML", +"7" => "L'attachement %s a été copié avec succès dans %s", +"8" => "Impossible d'ouvrir le fichier de destination!", +"9" => "Impossible de trouver l'attachement", +"10" => "Télécharger ", +"11" => "Copier l'attachement sur le serveur", +"12" => "Cc", +); diff --git a/core/src/plugins/editor.eml/i18n/pt.php b/core/src/plugins/editor.eml/i18n/pt.php index 136bc14315..92a427b9c1 100644 --- a/core/src/plugins/editor.eml/i18n/pt.php +++ b/core/src/plugins/editor.eml/i18n/pt.php @@ -1,4 +1,4 @@ - "Visualizador de E-mail", "title" => "Visualizador de E-mail", @@ -15,4 +15,3 @@ "11" => "Copiar anexo para o servidor", "12" => "Cc", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.eml/i18n/si.php b/core/src/plugins/editor.eml/i18n/si.php index 7f1dd3681f..96ae737b01 100644 --- a/core/src/plugins/editor.eml/i18n/si.php +++ b/core/src/plugins/editor.eml/i18n/si.php @@ -1,40 +1,39 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ -// Slovenian translation: April 21 2011 by Vladimir Bohinc (vladimir.bohinc@gmail.com) -// -//--------------------------------------------------------------------------------------------------- -$mess = array( -"name" => "Pregledovalnik e-pošte", -"title" => "Pregledovalnik elektronskih sporočil", -"1" => "Od", -"2" => "Za", -"3" => "Zadeva", -"4" => "Datum", -"5" => "Priloge", -"6" => "Prenesi e-pošto", -"7" => "Priloga %s je bila uspešno kopirana v %s", -"8" => "Ciljne datoteke ni bilo mogoče odpreti!", -"9" => "Priloge ni bilo mogoče najti!", -"10" => "Prenesi ", -"11" => "Kopiraj prilogo na strežnik", -"12" => "Kk", -); -?> \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ +// Slovenian translation: April 21 2011 by Vladimir Bohinc (vladimir.bohinc@gmail.com) +// +//--------------------------------------------------------------------------------------------------- +$mess = array( +"name" => "Pregledovalnik e-pošte", +"title" => "Pregledovalnik elektronskih sporočil", +"1" => "Od", +"2" => "Za", +"3" => "Zadeva", +"4" => "Datum", +"5" => "Priloge", +"6" => "Prenesi e-pošto", +"7" => "Priloga %s je bila uspešno kopirana v %s", +"8" => "Ciljne datoteke ni bilo mogoče odpreti!", +"9" => "Priloge ni bilo mogoče najti!", +"10" => "Prenesi ", +"11" => "Kopiraj prilogo na strežnik", +"12" => "Kk", +); diff --git a/core/src/plugins/editor.eml/manifest.xml b/core/src/plugins/editor.eml/manifest.xml index f08d03c4a7..a0faf61853 100644 --- a/core/src/plugins/editor.eml/manifest.xml +++ b/core/src/plugins/editor.eml/manifest.xml @@ -11,27 +11,27 @@ -
    +
    - - + ]]>
    @@ -63,10 +63,10 @@ - + - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.etherpad/class.EtherpadClient.php b/core/src/plugins/editor.etherpad/class.EtherpadClient.php index efb8b3baef..0eab53a749 100644 --- a/core/src/plugins/editor.etherpad/class.EtherpadClient.php +++ b/core/src/plugins/editor.etherpad/class.EtherpadClient.php @@ -21,20 +21,20 @@ defined('AJXP_EXEC') or die( 'Access not allowed'); -class EtherpadClient extends AJXP_Plugin{ - - var $baseURL = "http://localhost:9001"; - var $apiKey = ""; - - public function switchAction($actionName, $httpVars, $fileVars){ +class EtherpadClient extends AJXP_Plugin +{ + public $baseURL = "http://localhost:9001"; + public $apiKey = ""; + public function switchAction($actionName, $httpVars, $fileVars) + { $this->baseURL = rtrim($this->getFilteredOption("ETHERPAD_SERVER"), "/"); $this->apiKey = $this->getFilteredOption("ETHERPAD_APIKEY"); - if(isSet($httpVars["file"])){ + if (isSet($httpVars["file"])) { $repository = ConfService::getRepository(); - if(!$repository->detectStreamWrapper(false)){ + if (!$repository->detectStreamWrapper(false)) { return false; } $plugin = AJXP_PluginsService::findPlugin("access", $repository->getAccessType()); @@ -42,7 +42,7 @@ public function switchAction($actionName, $httpVars, $fileVars){ $destStreamURL = $streamData["protocol"]."://".$repository->getId()."/"; $filename = $destStreamURL. AJXP_Utils::securePath($httpVars["file"]); - if(!is_file($filename)){ + if (!is_file($filename)) { throw new Exception("Cannot find file!"); } } @@ -55,20 +55,20 @@ public function switchAction($actionName, $httpVars, $fileVars){ $res2 = $client->createGroupIfNotExistsFor("ajaxplorer"); $groupID = $res2->groupID; - if($actionName == "etherpad_create"){ + if ($actionName == "etherpad_create") { - if(isSet($httpVars["pad_name"])){ + if (isSet($httpVars["pad_name"])) { $padID = $httpVars["pad_name"]; $startContent = ""; - if($httpVars["pad_type"] && $httpVars["pad_type"] == 'free'){ + if ($httpVars["pad_type"] && $httpVars["pad_type"] == 'free') { $padID = "FREEPAD__".$padID; } - }else if(isSet($httpVars["file"])){ + } else if (isSet($httpVars["file"])) { $startContent = file_get_contents($filename); - if(strtolower(pathinfo($filename, PATHINFO_EXTENSION)) == "html"){ + if (strtolower(pathinfo($filename, PATHINFO_EXTENSION)) == "html") { $startContentHTML = $startContent; } $padID = AJXP_Utils::slugify($httpVars["file"]); @@ -79,20 +79,20 @@ public function switchAction($actionName, $httpVars, $fileVars){ $resP = $client->listPads($res2->groupID); $pads = $resP->padIDs; - if(!in_array($groupID.'$'.$padID, $pads)){ + if (!in_array($groupID.'$'.$padID, $pads)) { $res3 = $client->createGroupPad($groupID, $padID, null); - if(isSet($startContentHTML)){ + if (isSet($startContentHTML)) { $client->setHTML($groupID.'$'.$padID, $startContentHTML); - }else if(!empty($startContent)){ + } else if (!empty($startContent)) { $client->setText($groupID.'$'.$padID, $startContent); } - }else{ + } else { // Check if content needs relaunch! $test = $client->getText($groupID.'$'.$padID); - if(!empty($startContent) && $test->text != $startContent){ - if(isSet($startContentHTML)){ + if (!empty($startContent) && $test->text != $startContent) { + if (isSet($startContentHTML)) { $client->setHTML($groupID.'$'.$padID, $startContentHTML); - }else{ + } else { $client->setText($groupID.'$'.$padID, $startContent); } } @@ -114,14 +114,14 @@ public function switchAction($actionName, $httpVars, $fileVars){ HTMLWriter::charsetHeader('application/json'); echo(json_encode($data)); - }else if ($actionName == "etherpad_save"){ + } else if ($actionName == "etherpad_save") { $node = new AJXP_Node($filename); $padID = $httpVars["pad_id"]; - if(isSet($startContentHTML)){ + if (isSet($startContentHTML)) { $res = $client->getHTML($padID); - }else{ + } else { $res = $client->getText($padID); } @@ -129,17 +129,17 @@ public function switchAction($actionName, $httpVars, $fileVars){ file_put_contents($filename, $res->text); AJXP_Controller::applyHook("node.change", array($node, $node)); - }else if ($actionName == "etherpad_close"){ + } else if ($actionName == "etherpad_close") { // WE SHOULD DETECT IF THERE IS NOBODY CONNECTED ANYMORE, AND DELETE THE PAD. $sessionID = $httpVars["session_id"]; $client->deleteSession($sessionID); - }else if($actionName == "etherpad_proxy_api"){ + } else if ($actionName == "etherpad_proxy_api") { - if($httpVars["api_action"] == "list_pads"){ + if ($httpVars["api_action"] == "list_pads") { $res = $client->listPads($groupID); - }else if($httpVars["api_action"] == "list_authors_for_pad"){ + } else if ($httpVars["api_action"] == "list_authors_for_pad") { $res = $client->listAuthorsOfPad($httpVars["pad_id"]); } HTMLWriter::charsetHeader("application/json"); @@ -150,4 +150,4 @@ public function switchAction($actionName, $httpVars, $fileVars){ } -} \ No newline at end of file +} diff --git a/core/src/plugins/editor.etherpad/etherpad-client/etherpad-lite-client.php b/core/src/plugins/editor.etherpad/etherpad-client/etherpad-lite-client.php index db312ab7f0..1b3bb60cfd 100755 --- a/core/src/plugins/editor.etherpad/etherpad-client/etherpad-lite-client.php +++ b/core/src/plugins/editor.etherpad/etherpad-client/etherpad-lite-client.php @@ -1,6 +1,6 @@ apiKey = $apiKey; - if (isset($baseUrl)){ + if (isset($baseUrl)) { $this->baseUrl = $baseUrl; } - if (!filter_var($this->baseUrl, FILTER_VALIDATE_URL)){ + if (!filter_var($this->baseUrl, FILTER_VALIDATE_URL)) { throw new InvalidArgumentException("[{$this->baseUrl}] is not a valid URL"); } } - protected function get($function, array $arguments = array()){ + protected function get($function, array $arguments = array()) + { return $this->call($function, $arguments, 'GET'); } - protected function post($function, array $arguments = array()){ + protected function post($function, array $arguments = array()) + { return $this->call($function, $arguments, 'POST'); } - protected function call($function, array $arguments = array(), $method = 'GET'){ + protected function call($function, array $arguments = array(), $method = 'GET') + { $arguments['apikey'] = $this->apiKey; $arguments = http_build_query($arguments, '', '&'); $url = $this->baseUrl."/".self::API_VERSION."/".$function; - if ($method !== 'POST'){ + if ($method !== 'POST') { $url .= "?".$arguments; } // use curl of it's available - if (function_exists('curl_init')){ + if (function_exists('curl_init')) { $c = curl_init($url); curl_setopt($c, CURLOPT_RETURNTRANSFER, true); curl_setopt($c, CURLOPT_TIMEOUT, 20); - if ($method === 'POST'){ + if ($method === 'POST') { curl_setopt($c, CURLOPT_POST, true); curl_setopt($c, CURLOPT_POSTFIELDS, $arguments); } @@ -55,37 +59,38 @@ protected function call($function, array $arguments = array(), $method = 'GET'){ // fallback to plain php } else { $params = array('http' => array('method' => $method, 'ignore_errors' => true, 'header' => 'Content-Type:application/x-www-form-urlencoded')); - if ($method === 'POST'){ + if ($method === 'POST') { $params['http']['content'] = $arguments; } $context = stream_context_create($params); $fp = fopen($url, 'rb', false, $context); $result = $fp ? stream_get_contents($fp) : null; } - - if(!$result){ + + if (!$result) { throw new UnexpectedValueException("Empty or No Response from the server"); } - + $result = json_decode($result); - if ($result === null){ + if ($result === null) { throw new UnexpectedValueException("JSON response could not be decoded"); } return $this->handleResult($result); } - protected function handleResult($result){ - if (!isset($result->code)){ + protected function handleResult($result) + { + if (!isset($result->code)) { throw new RuntimeException("API response has no code"); } - if (!isset($result->message)){ + if (!isset($result->message)) { throw new RuntimeException("API response has no message"); } - if (!isset($result->data)){ + if (!isset($result->data)) { $result->data = null; } - switch ($result->code){ + switch ($result->code) { case self::CODE_OK: return $result->data; case self::CODE_INVALID_PARAMETERS: @@ -102,35 +107,40 @@ protected function handleResult($result){ // GROUPS // Pads can belong to a group. There will always be public pads that doesnt belong to a group (or we give this group the id 0) - - // creates a new group - public function createGroup(){ + + // creates a new group + public function createGroup() + { return $this->post("createGroup"); } - // this functions helps you to map your application group ids to etherpad lite group ids - public function createGroupIfNotExistsFor($groupMapper){ + // this functions helps you to map your application group ids to etherpad lite group ids + public function createGroupIfNotExistsFor($groupMapper) + { return $this->post("createGroupIfNotExistsFor", array( "groupMapper" => $groupMapper )); } - // deletes a group - public function deleteGroup($groupID){ + // deletes a group + public function deleteGroup($groupID) + { return $this->post("deleteGroup", array( "groupID" => $groupID )); } // returns all pads of this group - public function listPads($groupID){ + public function listPads($groupID) + { return $this->get("listPads", array( "groupID" => $groupID )); } - // creates a new pad in this group - public function createGroupPad($groupID, $padName, $text){ + // creates a new pad in this group + public function createGroupPad($groupID, $padName, $text) + { return $this->post("createGroupPad", array( "groupID" => $groupID, "padName" => $padName, @@ -139,22 +149,25 @@ public function createGroupPad($groupID, $padName, $text){ } // list all groups - public function listAllGroups(){ + public function listAllGroups() + { return $this->get("listAllGroups"); } // AUTHORS - // Theses authors are bind to the attributes the users choose (color and name). + // Theses authors are bind to the attributes the users choose (color and name). - // creates a new author - public function createAuthor($name){ + // creates a new author + public function createAuthor($name) + { return $this->post("createAuthor", array( "name" => $name )); } - // this functions helps you to map your application author ids to etherpad lite author ids - public function createAuthorIfNotExistsFor($authorMapper, $name){ + // this functions helps you to map your application author ids to etherpad lite author ids + public function createAuthorIfNotExistsFor($authorMapper, $name) + { return $this->post("createAuthorIfNotExistsFor", array( "authorMapper" => $authorMapper, "name" => $name @@ -162,14 +175,16 @@ public function createAuthorIfNotExistsFor($authorMapper, $name){ } // returns the ids of all pads this author as edited - public function listPadsOfAuthor($authorID){ + public function listPadsOfAuthor($authorID) + { return $this->get("listPadsOfAuthor", array( "authorID" => $authorID )); } // Gets an author's name - public function getAuthorName($authorID){ + public function getAuthorName($authorID) + { return $this->get("getAuthorName", array( "authorID" => $authorID )); @@ -180,8 +195,9 @@ public function getAuthorName($authorID){ // an author to access more than one group. The sessionID will be set as // a cookie to the client and is valid until a certian date. - // creates a new session - public function createSession($groupID, $authorID, $validUntil){ + // creates a new session + public function createSession($groupID, $authorID, $validUntil) + { return $this->post("createSession", array( "groupID" => $groupID, "authorID" => $authorID, @@ -189,29 +205,33 @@ public function createSession($groupID, $authorID, $validUntil){ )); } - // deletes a session - public function deleteSession($sessionID){ + // deletes a session + public function deleteSession($sessionID) + { return $this->post("deleteSession", array( "sessionID" => $sessionID )); } - // returns informations about a session - public function getSessionInfo($sessionID){ + // returns informations about a session + public function getSessionInfo($sessionID) + { return $this->get("getSessionInfo", array( "sessionID" => $sessionID )); } - // returns all sessions of a group - public function listSessionsOfGroup($groupID){ + // returns all sessions of a group + public function listSessionsOfGroup($groupID) + { return $this->get("listSessionsOfGroup", array( "groupID" => $groupID )); } - // returns all sessions of an author - public function listSessionsOfAuthor($authorID){ + // returns all sessions of an author + public function listSessionsOfAuthor($authorID) + { return $this->get("listSessionsOfAuthor", array( "authorID" => $authorID )); @@ -220,36 +240,40 @@ public function listSessionsOfAuthor($authorID){ // PAD CONTENT // Pad content can be updated and retrieved through the API - // returns the text of a pad - public function getText($padID, $rev=null){ + // returns the text of a pad + public function getText($padID, $rev=null) + { $params = array("padID" => $padID); - if (isset($rev)){ + if (isset($rev)) { $params["rev"] = $rev; } return $this->get("getText", $params); } // returns the text of a pad as html - public function getHTML($padID, $rev=null){ + public function getHTML($padID, $rev=null) + { $params = array("padID" => $padID); - if (isset($rev)){ + if (isset($rev)) { $params["rev"] = $rev; } return $this->get("getHTML", $params); } - // sets the text of a pad - public function setText($padID, $text){ + // sets the text of a pad + public function setText($padID, $text) + { return $this->post("setText", array( - "padID" => $padID, + "padID" => $padID, "text" => $text )); } - // sets the html text of a pad - public function setHTML($padID, $html){ + // sets the html text of a pad + public function setHTML($padID, $html) + { return $this->post("setHTML", array( - "padID" => $padID, + "padID" => $padID, "html" => $html )); } @@ -260,57 +284,65 @@ public function setHTML($padID, $html){ // forbidden for normal pads to include a $ in the name. // creates a new pad - public function createPad($padID, $text){ + public function createPad($padID, $text) + { return $this->post("createPad", array( - "padID" => $padID, + "padID" => $padID, "text" => $text ), 'POST'); } - // returns the number of revisions of this pad - public function getRevisionsCount($padID){ + // returns the number of revisions of this pad + public function getRevisionsCount($padID) + { return $this->get("getRevisionsCount", array( "padID" => $padID )); } // returns the number of users currently editing this pad - public function padUsersCount($padID){ + public function padUsersCount($padID) + { return $this->get("padUsersCount", array( "padID" => $padID )); } // return the time the pad was last edited as a Unix timestamp - public function getLastEdited($padID){ + public function getLastEdited($padID) + { return $this->get("getLastEdited", array( "padID" => $padID )); } - // deletes a pad - public function deletePad($padID){ + // deletes a pad + public function deletePad($padID) + { return $this->post("deletePad", array( "padID" => $padID )); } - // returns the read only link of a pad - public function getReadOnlyID($padID){ + // returns the read only link of a pad + public function getReadOnlyID($padID) + { return $this->get("getReadOnlyID", array( "padID" => $padID )); } // returns the ids of all authors who've edited this pad - public function listAuthorsOfPad($padID){ + public function listAuthorsOfPad($padID) + { return $this->get("listAuthorsOfPad", array( "padID" => $padID )); } - // sets a boolean for the public status of a pad - public function setPublicStatus($padID, $publicStatus){ + // sets a boolean for the public status of a pad + public function setPublicStatus($padID, $publicStatus) + { if (is_bool($publicStatus)) { $publicStatus = $publicStatus ? "true" : "false"; } @@ -320,41 +352,45 @@ public function setPublicStatus($padID, $publicStatus){ )); } - // return true of false - public function getPublicStatus($padID){ + // return true of false + public function getPublicStatus($padID) + { return $this->get("getPublicStatus", array( "padID" => $padID )); } - // returns ok or a error message - public function setPassword($padID, $password){ + // returns ok or a error message + public function setPassword($padID, $password) + { return $this->post("setPassword", array( "padID" => $padID, "password" => $password )); } - // returns true or false - public function isPasswordProtected($padID){ + // returns true or false + public function isPasswordProtected($padID) + { return $this->get("isPasswordProtected", array( "padID" => $padID )); } // Get pad users - public function padUsers($padID){ + public function padUsers($padID) + { return $this->get("padUsers", array( "padID" => $padID )); } // Send all clients a message - public function sendClientsMessage($padID, $msg){ + public function sendClientsMessage($padID, $msg) + { return $this->post("sendClientsMessage", array( "padID" => $padID, "msg" => $msg )); } } - diff --git a/core/src/plugins/editor.etherpad/i18n/conf/fr.php b/core/src/plugins/editor.etherpad/i18n/conf/fr.php index 7fbbd8a3a5..f3288f3a59 100644 --- a/core/src/plugins/editor.etherpad/i18n/conf/fr.php +++ b/core/src/plugins/editor.etherpad/i18n/conf/fr.php @@ -22,4 +22,3 @@ "Etherpad" => "Etherpad", "Collaborative edition of text files" => "Edition collaborative des fichiers", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.etherpad/i18n/en.php b/core/src/plugins/editor.etherpad/i18n/en.php index 1aa3979657..76110f0bdb 100644 --- a/core/src/plugins/editor.etherpad/i18n/en.php +++ b/core/src/plugins/editor.etherpad/i18n/en.php @@ -30,4 +30,4 @@ "7" => "Join", "8" => "Board name", "9" => "Create new board", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.etherpad/i18n/fr.php b/core/src/plugins/editor.etherpad/i18n/fr.php index 72a61fe75f..9e6b785537 100755 --- a/core/src/plugins/editor.etherpad/i18n/fr.php +++ b/core/src/plugins/editor.etherpad/i18n/fr.php @@ -30,4 +30,4 @@ "7" => "Rejoindre", "8" => "Nom de l'ardoise", "9" => "Créer une nouvelle ardoise", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.etherpad/i18n/pt.php b/core/src/plugins/editor.etherpad/i18n/pt.php index 56ee9e971e..edda537464 100644 --- a/core/src/plugins/editor.etherpad/i18n/pt.php +++ b/core/src/plugins/editor.etherpad/i18n/pt.php @@ -30,4 +30,4 @@ "7" => "Juntar", "8" => "Nome da Área", "9" => "Criar uma nova Área", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.etherpad/manifest.xml b/core/src/plugins/editor.etherpad/manifest.xml index a08e13a322..b26a9c48d9 100644 --- a/core/src/plugins/editor.etherpad/manifest.xml +++ b/core/src/plugins/editor.etherpad/manifest.xml @@ -73,4 +73,4 @@ - \ No newline at end of file + diff --git a/core/src/plugins/editor.exif/i18n/conf/en.php b/core/src/plugins/editor.exif/i18n/conf/en.php index 93ef76d8e0..ec8fb040b4 100644 --- a/core/src/plugins/editor.exif/i18n/conf/en.php +++ b/core/src/plugins/editor.exif/i18n/conf/en.php @@ -22,4 +22,3 @@ "EXIF Extractor" => "EXIF Extractor", "Display the Exif metadata contained inside the JPG files. Can locate the image on a map if it contains geolocation data." => "Display the Exif metadata contained inside the JPG files. Can locate the image on a map if it contains geolocation data.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.exif/i18n/conf/fr.php b/core/src/plugins/editor.exif/i18n/conf/fr.php index 1247a8afcd..240ccda0bc 100644 --- a/core/src/plugins/editor.exif/i18n/conf/fr.php +++ b/core/src/plugins/editor.exif/i18n/conf/fr.php @@ -22,4 +22,3 @@ "EXIF Extractor" => "Extraction EXIF", "Display the Exif metadata contained inside the JPG files. Can locate the image on a map if it contains geolocation data." => "Affichage des données exif contenues dans une image JPG.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.exif/i18n/conf/pt.php b/core/src/plugins/editor.exif/i18n/conf/pt.php index 4d06bb6513..94b79eb8f3 100644 --- a/core/src/plugins/editor.exif/i18n/conf/pt.php +++ b/core/src/plugins/editor.exif/i18n/conf/pt.php @@ -22,4 +22,3 @@ "EXIF Extractor" => "Extractor EXIF", "Display the Exif metadata contained inside the JPG files. Can locate the image on a map if it contains geolocation data." => "Mostra a informação de metadata EXIF de um ficheiro JPG. Pode localizar uma imagem num mapa caso esta contenha informações de geolocalização.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.exif/i18n/de.php b/core/src/plugins/editor.exif/i18n/de.php index 4ebf1fc0a5..4ce11d1be5 100644 --- a/core/src/plugins/editor.exif/i18n/de.php +++ b/core/src/plugins/editor.exif/i18n/de.php @@ -1,8 +1,6 @@ "Exif Reader", -"2" => "Exif Daten anzeigen", +"1" => "Exif Reader", +"2" => "Exif Daten anzeigen", ); - -?> diff --git a/core/src/plugins/editor.exif/i18n/en.php b/core/src/plugins/editor.exif/i18n/en.php index 1d90d6d860..ea40046e67 100644 --- a/core/src/plugins/editor.exif/i18n/en.php +++ b/core/src/plugins/editor.exif/i18n/en.php @@ -1,8 +1,6 @@ "Exif Reader", -"2" => "Display Exif data", +"1" => "Exif Reader", +"2" => "Display Exif data", ); - -?> \ No newline at end of file diff --git a/core/src/plugins/editor.exif/i18n/es.php b/core/src/plugins/editor.exif/i18n/es.php index 79eeedb951..343678b046 100644 --- a/core/src/plugins/editor.exif/i18n/es.php +++ b/core/src/plugins/editor.exif/i18n/es.php @@ -1,8 +1,6 @@ "Lector Exif", -"2" => "Visualizar datos Exif", +"1" => "Lector Exif", +"2" => "Visualizar datos Exif", ); - -?> diff --git a/core/src/plugins/editor.exif/i18n/et.php b/core/src/plugins/editor.exif/i18n/et.php index 97aea531f9..6a3c1ed181 100644 --- a/core/src/plugins/editor.exif/i18n/et.php +++ b/core/src/plugins/editor.exif/i18n/et.php @@ -4,8 +4,6 @@ // Last update: 27.05.2013 $mess = array( -"1" => "EXIF luger", -"2" => "Kuva EXIF andmed", +"1" => "EXIF luger", +"2" => "Kuva EXIF andmed", ); - -?> diff --git a/core/src/plugins/editor.exif/i18n/fr.php b/core/src/plugins/editor.exif/i18n/fr.php index 1c6d9cad14..94fec6e72a 100644 --- a/core/src/plugins/editor.exif/i18n/fr.php +++ b/core/src/plugins/editor.exif/i18n/fr.php @@ -22,4 +22,3 @@ "1" => "Exif Reader", "2" => "Display Exif data", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.exif/i18n/pt.php b/core/src/plugins/editor.exif/i18n/pt.php index c011de3043..d42a935016 100644 --- a/core/src/plugins/editor.exif/i18n/pt.php +++ b/core/src/plugins/editor.exif/i18n/pt.php @@ -1,8 +1,6 @@ "Leitor Exif", -"2" => "Mostra a informação Exif", +"1" => "Leitor Exif", +"2" => "Mostra a informação Exif", ); - -?> \ No newline at end of file diff --git a/core/src/plugins/editor.exif/i18n/si.php b/core/src/plugins/editor.exif/i18n/si.php index 5e6f3bd261..9ce9040fa4 100644 --- a/core/src/plugins/editor.exif/i18n/si.php +++ b/core/src/plugins/editor.exif/i18n/si.php @@ -19,10 +19,9 @@ * The latest code can be found at . */ // Slovenian translation: April 21 2011 by Vladimir Bohinc (vladimir.bohinc@gmail.com) -// +// //--------------------------------------------------------------------------------------------------- $mess = array( -"1" => "Pregledovalnik Exif", -"2" => "Prikaži Exif metapodatke", +"1" => "Pregledovalnik Exif", +"2" => "Prikaži Exif metapodatke", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.exif/manifest.xml b/core/src/plugins/editor.exif/manifest.xml index 64cab71fdd..d4ea940adb 100644 --- a/core/src/plugins/editor.exif/manifest.xml +++ b/core/src/plugins/editor.exif/manifest.xml @@ -13,11 +13,11 @@ - - ]]> + + + ]]> - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.imagick/class.IMagickPreviewer.php b/core/src/plugins/editor.imagick/class.IMagickPreviewer.php index 4f065ef11c..db201f9c40 100644 --- a/core/src/plugins/editor.imagick/class.IMagickPreviewer.php +++ b/core/src/plugins/editor.imagick/class.IMagickPreviewer.php @@ -26,185 +26,190 @@ * @package AjaXplorer_Plugins * @subpackage Editor */ -class IMagickPreviewer extends AJXP_Plugin { - - protected $extractAll = false; - protected $onTheFly = false; - protected $useOnTheFly = false; +class IMagickPreviewer extends AJXP_Plugin +{ + protected $extractAll = false; + protected $onTheFly = false; + protected $useOnTheFly = false; protected $imagickExtensions = array("pdf", "svg", "tif", "tiff", "psd", "xcf", "eps", "cr2"); protected $unoconvExtensios = array("xls", "xlsx", "ods", "doc", "docx", "odt", "ppt", "pptx", "odp", "rtf"); - public function loadConfigs($configsData){ + public function loadConfigs($configsData) + { parent::loadConfigs($configsData); - if(isSet($configsData["UNOCONV"]) && !empty($configsData["UNOCONV"])){ + if (isSet($configsData["UNOCONV"]) && !empty($configsData["UNOCONV"])) { // APPEND THE UNOCONV SUPPORTED EXTENSIONS $this->manifestDoc->documentElement->setAttribute("mimes", implode(",", array_merge($this->imagickExtensions,$this->unoconvExtensios))); - }else{ + } else { $this->manifestDoc->documentElement->setAttribute("mimes", implode(",", $this->imagickExtensions)); } } - public function switchAction($action, $httpVars, $filesVars){ - - if(!isSet($this->actions[$action])) return false; - - $repository = ConfService::getRepository(); - if(!$repository->detectStreamWrapper(true)){ - return false; - } + public function switchAction($action, $httpVars, $filesVars) + { + if(!isSet($this->actions[$action])) return false; + + $repository = ConfService::getRepository(); + if (!$repository->detectStreamWrapper(true)) { + return false; + } $convert = $this->getFilteredOption("IMAGE_MAGICK_CONVERT"); - if(empty($convert)){ - return false; - } - $streamData = $repository->streamData; - $destStreamURL = $streamData["protocol"]."://".$repository->getId(); - $flyThreshold = 1024*1024*intval($this->getFilteredOption("ONTHEFLY_THRESHOLD", $repository->getId())); - - if($action == "imagick_data_proxy"){ - $this->extractAll = false; - if(isSet($httpVars["all"])) $this->extractAll = true; - $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); + if (empty($convert)) { + return false; + } + $streamData = $repository->streamData; + $destStreamURL = $streamData["protocol"]."://".$repository->getId(); + $flyThreshold = 1024*1024*intval($this->getFilteredOption("ONTHEFLY_THRESHOLD", $repository->getId())); + + if ($action == "imagick_data_proxy") { + $this->extractAll = false; + if(isSet($httpVars["all"])) $this->extractAll = true; + $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); - if(($size = filesize($destStreamURL.$file)) === false) { - return ; - }else{ - if($size > $flyThreshold) $this->useOnTheFly = true; - else $this->useOnTheFly = false; - } + if (($size = filesize($destStreamURL.$file)) === false) { + return ; + } else { + if($size > $flyThreshold) $this->useOnTheFly = true; + else $this->useOnTheFly = false; + } - if($this->extractAll){ + if ($this->extractAll) { $node = new AJXP_Node($destStreamURL.$file); AJXP_Controller::applyHook("node.read", array($node)); } $cache = AJXP_Cache::getItem("imagick_".($this->extractAll?"full":"thumb"), $destStreamURL.$file, array($this, "generateJpegsCallback")); - $cacheData = $cache->getData(); + $cacheData = $cache->getData(); - if(!$this->useOnTheFly && $this->extractAll){ // extract all on first view - $ext = pathinfo($file, PATHINFO_EXTENSION); - $prefix = str_replace(".$ext", "", $cache->getId()); - $files = $this->listExtractedJpg($prefix); - header("Content-Type: application/json"); - print(json_encode($files)); - return; - }else if($this->extractAll){ // on the fly extract mode - $ext = pathinfo($file, PATHINFO_EXTENSION); - $prefix = str_replace(".$ext", "", $cache->getId()); - $files = $this->listPreviewFiles($destStreamURL.$file, $prefix); - header("Content-Type: application/json"); - print(json_encode($files)); - return; - }else{ - header("Content-Type: image/jpeg; name=\"".basename($file)."\""); - header("Content-Length: ".strlen($cacheData)); - header('Cache-Control: public'); + if (!$this->useOnTheFly && $this->extractAll) { // extract all on first view + $ext = pathinfo($file, PATHINFO_EXTENSION); + $prefix = str_replace(".$ext", "", $cache->getId()); + $files = $this->listExtractedJpg($prefix); + header("Content-Type: application/json"); + print(json_encode($files)); + return; + } else if ($this->extractAll) { // on the fly extract mode + $ext = pathinfo($file, PATHINFO_EXTENSION); + $prefix = str_replace(".$ext", "", $cache->getId()); + $files = $this->listPreviewFiles($destStreamURL.$file, $prefix); + header("Content-Type: application/json"); + print(json_encode($files)); + return; + } else { + header("Content-Type: image/jpeg; name=\"".basename($file)."\""); + header("Content-Length: ".strlen($cacheData)); + header('Cache-Control: public'); header("Pragma:"); header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()-10000) . " GMT"); header("Expires: " . gmdate("D, d M Y H:i:s", time()+5*24*3600) . " GMT"); print($cacheData); - return; - } - - }else if($action == "get_extracted_page" && isSet($httpVars["file"])){ - $file = (defined('AJXP_SHARED_CACHE_DIR')?AJXP_SHARED_CACHE_DIR:AJXP_CACHE_DIR)."/imagick_full/".AJXP_Utils::decodeSecureMagic($httpVars["file"]); - if(!is_file($file)){ - $srcfile = AJXP_Utils::decodeSecureMagic($httpVars["src_file"]); - $size = filesize($destStreamURL."/".$srcfile); - if($size > $flyThreshold) $this->useOnTheFly = true; - else $this->useOnTheFly = false; - - if($this->useOnTheFly) $this->onTheFly = true; - $this->generateJpegsCallback($destStreamURL.$srcfile, $file); + return; + } + + } else if ($action == "get_extracted_page" && isSet($httpVars["file"])) { + $file = (defined('AJXP_SHARED_CACHE_DIR')?AJXP_SHARED_CACHE_DIR:AJXP_CACHE_DIR)."/imagick_full/".AJXP_Utils::decodeSecureMagic($httpVars["file"]); + if (!is_file($file)) { + $srcfile = AJXP_Utils::decodeSecureMagic($httpVars["src_file"]); + $size = filesize($destStreamURL."/".$srcfile); + if($size > $flyThreshold) $this->useOnTheFly = true; + else $this->useOnTheFly = false; + + if($this->useOnTheFly) $this->onTheFly = true; + $this->generateJpegsCallback($destStreamURL.$srcfile, $file); + + } + if(!is_file($file)) return ; + header("Content-Type: image/jpeg; name=\"".basename($file)."\""); + header("Content-Length: ".filesize($file)); + header('Cache-Control: public'); + readfile($file); + exit(1); + } else if ($action == "delete_imagick_data" && isSet($httpVars["file"])) { + /* + $files = $this->listExtractedJpg(AJXP_CACHE_DIR."/".$httpVars["file"]); + foreach ($files as $file) { + if(is_file(AJXP_CACHE_DIR."/".$file["file"])) unlink(AJXP_CACHE_DIR."/".$file["file"]); + } + */ + } + } + /** + * + * @param AJXP_Node $oldNode + * @param AJXP_Node $newNode + * @param Boolean $copy + */ + public function deleteImagickCache($oldNode, $newNode = null, $copy = false) + { + if($oldNode == null) return; + $oldFile = $oldNode->getUrl(); + // Should remove imagick cache file + if(!$this->handleMime($oldFile)) return; + if ($newNode == null || $copy == false) { + AJXP_Cache::clearItem("imagick_thumb", $oldFile); + $cache = AJXP_Cache::getItem("imagick_full", $oldFile, false); + $prefix = str_replace(".".pathinfo($cache->getId(), PATHINFO_EXTENSION), "", $cache->getId()); + $files = $this->listExtractedJpg($prefix); + foreach ($files as $file) { + if(is_file((defined('AJXP_SHARED_CACHE_DIR')?AJXP_SHARED_CACHE_DIR:AJXP_CACHE_DIR)."/".$file["file"])) unlink(AJXP_CACHE_DIR."/".$file["file"]); } - if(!is_file($file)) return ; - header("Content-Type: image/jpeg; name=\"".basename($file)."\""); - header("Content-Length: ".filesize($file)); - header('Cache-Control: public'); - readfile($file); - exit(1); - }else if($action == "delete_imagick_data" && isSet($httpVars["file"])){ - /* - $files = $this->listExtractedJpg(AJXP_CACHE_DIR."/".$httpVars["file"]); - foreach ($files as $file){ - if(is_file(AJXP_CACHE_DIR."/".$file["file"])) unlink(AJXP_CACHE_DIR."/".$file["file"]); - } - */ - } - } - - /** - * - * @param AJXP_Node $oldNode - * @param AJXP_Node $newNode - * @param Boolean $copy - */ - public function deleteImagickCache($oldNode, $newNode = null, $copy = false){ - if($oldNode == null) return; - $oldFile = $oldNode->getUrl(); - // Should remove imagick cache file - if(!$this->handleMime($oldFile)) return; - if($newNode == null || $copy == false){ - AJXP_Cache::clearItem("imagick_thumb", $oldFile); - $cache = AJXP_Cache::getItem("imagick_full", $oldFile, false); - $prefix = str_replace(".".pathinfo($cache->getId(), PATHINFO_EXTENSION), "", $cache->getId()); - $files = $this->listExtractedJpg($prefix); - foreach ($files as $file){ - if(is_file((defined('AJXP_SHARED_CACHE_DIR')?AJXP_SHARED_CACHE_DIR:AJXP_CACHE_DIR)."/".$file["file"])) unlink(AJXP_CACHE_DIR."/".$file["file"]); - } - } - } - - protected function listExtractedJpg($prefix){ - $files = array(); - $index = 0; - while(is_file($prefix."-".$index.".jpg")){ - $extract = $prefix."-".$index.".jpg"; - list($width, $height, $type, $attr) = @getimagesize($extract); - $files[] = array("file" => basename($extract), "width"=>$width, "height"=>$height); - $index ++; - } - if(is_file($prefix.".jpg")){ - $extract = $prefix.".jpg"; - list($width, $height, $type, $attr) = @getimagesize($extract); - $files[] = array("file" => basename($extract), "width"=>$width, "height"=>$height); - } - return $files; - } - - protected function listPreviewFiles($file, $prefix){ - $files = array(); - $index = 0; + } + } + + protected function listExtractedJpg($prefix) + { + $files = array(); + $index = 0; + while (is_file($prefix."-".$index.".jpg")) { + $extract = $prefix."-".$index.".jpg"; + list($width, $height, $type, $attr) = @getimagesize($extract); + $files[] = array("file" => basename($extract), "width"=>$width, "height"=>$height); + $index ++; + } + if (is_file($prefix.".jpg")) { + $extract = $prefix.".jpg"; + list($width, $height, $type, $attr) = @getimagesize($extract); + $files[] = array("file" => basename($extract), "width"=>$width, "height"=>$height); + } + return $files; + } + + protected function listPreviewFiles($file, $prefix) + { + $files = array(); + $index = 0; $unoconv = $this->getFilteredOption("UNOCONV"); - if(!empty($unoconv)){ - $officeExt = array('xls', 'xlsx', 'ods', 'doc', 'docx', 'odt', 'ppt', 'pptx', 'odp', 'rtf'); - $extension = pathinfo($file, PATHINFO_EXTENSION); - if(in_array(strtolower($extension), $officeExt)){ - $unoDoc = $prefix."_unoconv.pdf"; - if(is_file($unoDoc)) $file = $unoDoc; - } - } - $count = $this->countPages($file); - while($index < $count){ - $extract = $prefix."-".$index.".jpg"; - list($width, $height, $type, $attr) = @getimagesize($extract); - $files[] = array("file" => basename($extract), "width"=>$width, "height"=>$height); - $index ++; - } - if(is_file($prefix.".jpg")){ - $extract = $prefix.".jpg"; - list($width, $height, $type, $attr) = @getimagesize($extract); - $files[] = array("file" => basename($extract), "width"=>$width, "height"=>$height); - } - return $files; - } - - public function generateJpegsCallback($masterFile, $targetFile){ + if (!empty($unoconv)) { + $officeExt = array('xls', 'xlsx', 'ods', 'doc', 'docx', 'odt', 'ppt', 'pptx', 'odp', 'rtf'); + $extension = pathinfo($file, PATHINFO_EXTENSION); + if (in_array(strtolower($extension), $officeExt)) { + $unoDoc = $prefix."_unoconv.pdf"; + if(is_file($unoDoc)) $file = $unoDoc; + } + } + $count = $this->countPages($file); + while ($index < $count) { + $extract = $prefix."-".$index.".jpg"; + list($width, $height, $type, $attr) = @getimagesize($extract); + $files[] = array("file" => basename($extract), "width"=>$width, "height"=>$height); + $index ++; + } + if (is_file($prefix.".jpg")) { + $extract = $prefix.".jpg"; + list($width, $height, $type, $attr) = @getimagesize($extract); + $files[] = array("file" => basename($extract), "width"=>$width, "height"=>$height); + } + return $files; + } + + public function generateJpegsCallback($masterFile, $targetFile) + { $unoconv = $this->getFilteredOption("UNOCONV"); - if(!empty($unoconv)){ - $officeExt = array('xls', 'xlsx', 'ods', 'doc', 'docx', 'odt', 'ppt', 'pptx', 'odp', 'rtf'); - }else{ + if (!empty($unoconv)) { + $officeExt = array('xls', 'xlsx', 'ods', 'doc', 'docx', 'odt', 'ppt', 'pptx', 'odp', 'rtf'); + } else { $unoconv = false; } @@ -212,93 +217,93 @@ public function generateJpegsCallback($masterFile, $targetFile){ $node = new AJXP_Node($masterFile); $masterFile = $node->getRealFile(); - if(DIRECTORY_SEPARATOR == "\\"){ + if (DIRECTORY_SEPARATOR == "\\") { $masterFile = str_replace("/", "\\", $masterFile); } $wrappers = stream_get_wrappers(); $wrappers_re = '(' . join('|', $wrappers) . ')'; $isStream = (preg_match( "!^$wrappers_re://!", $targetFile ) === 1); - if($isStream){ + if ($isStream) { $backToStreamTarget = $targetFile; $targetFile = tempnam(AJXP_Utils::getAjxpTmpDir(), "imagick_").".pdf"; } - $workingDir = dirname($targetFile); - $out = array(); - $return = 0; - $tmpFileThumb = str_replace(".$extension", ".jpg", $targetFile); - if(DIRECTORY_SEPARATOR == "\\"){ - $tmpFileThumb = str_replace("/", "\\", $tmpFileThumb); + $workingDir = dirname($targetFile); + $out = array(); + $return = 0; + $tmpFileThumb = str_replace(".$extension", ".jpg", $targetFile); + if (DIRECTORY_SEPARATOR == "\\") { + $tmpFileThumb = str_replace("/", "\\", $tmpFileThumb); + } + if (!$this->extractAll) { + //register_shutdown_function("unlink", $tmpFileThumb); + } else { + @set_time_limit(90); + } + chdir($workingDir); + if ($unoconv !== false && in_array(strtolower($extension), $officeExt)) { + $unoDoc = str_replace(".jpg", "_unoconv.pdf", $tmpFileThumb); + if (!is_file($tmpFileThumb)) { + // Create PDF Version now + $unoconv = "HOME=/tmp ".$unoconv." --stdout -f pdf ".escapeshellarg($masterFile)." > ".escapeshellarg(basename($unoDoc)); + exec($unoconv, $out, $return); + } + if (is_file($unoDoc)) { + $masterFile = basename($unoDoc); + } + } + + if ($this->onTheFly) { + $pageNumber = strrchr($targetFile, "-"); + $pageNumber = str_replace(array(".jpg","-"), "", $pageNumber); + $pageLimit = "[".$pageNumber."]"; + $this->extractAll = true; + } else { + if (!$this->useOnTheFly) { + $pageLimit = ($this->extractAll?"":"[0]"); + } else { + $pageLimit = "[0]"; + if($this->extractAll) $tmpFileThumb = str_replace(".jpg", "-0.jpg", $tmpFileThumb); + } } - if(!$this->extractAll){ - //register_shutdown_function("unlink", $tmpFileThumb); - }else{ - @set_time_limit(90); - } - chdir($workingDir); - if($unoconv !== false && in_array(strtolower($extension), $officeExt)){ - $unoDoc = str_replace(".jpg", "_unoconv.pdf", $tmpFileThumb); - if(!is_file($tmpFileThumb)){ - // Create PDF Version now - $unoconv = "HOME=/tmp ".$unoconv." --stdout -f pdf ".escapeshellarg($masterFile)." > ".escapeshellarg(basename($unoDoc)); - exec($unoconv, $out, $return); - } - if(is_file($unoDoc)){ - $masterFile = basename($unoDoc); - } - } - - if($this->onTheFly){ - $pageNumber = strrchr($targetFile, "-"); - $pageNumber = str_replace(array(".jpg","-"), "", $pageNumber); - $pageLimit = "[".$pageNumber."]"; - $this->extractAll = true; - }else{ - if(!$this->useOnTheFly){ - $pageLimit = ($this->extractAll?"":"[0]"); - }else{ - $pageLimit = "[0]"; - if($this->extractAll) $tmpFileThumb = str_replace(".jpg", "-0.jpg", $tmpFileThumb); - } - } $customOptions = $this->getFilteredOption("IM_CUSTOM_OPTIONS"); $customEnvPath = $this->getFilteredOption("ADDITIONAL_ENV_PATH"); $viewerQuality = $this->getFilteredOption("IM_VIEWER_QUALITY"); $thumbQuality = $this->getFilteredOption("IM_THUMB_QUALITY"); - if(empty($customOptions)){ + if (empty($customOptions)) { $customOptions = ""; } - if(!empty($customEnvPath)){ + if (!empty($customEnvPath)) { putenv("PATH=".getenv("PATH").":".$customEnvPath); } $params = ($this->extractAll?"-quality ".$viewerQuality:"-resize 250 ".$customOptions." -quality ".$thumbQuality); $cmd = $this->getFilteredOption("IMAGE_MAGICK_CONVERT")." ".escapeshellarg(($masterFile).$pageLimit)." ".$params." ".escapeshellarg($tmpFileThumb); - AJXP_Logger::debug("IMagick Command : $cmd"); - session_write_close(); // Be sure to give the hand back - exec($cmd, $out, $return); - if(is_array($out) && count($out)){ - throw new AJXP_Exception(implode("\n", $out)); - } - if(!$this->extractAll){ - rename($tmpFileThumb, $targetFile); - if($isStream){ + AJXP_Logger::debug("IMagick Command : $cmd"); + session_write_close(); // Be sure to give the hand back + exec($cmd, $out, $return); + if (is_array($out) && count($out)) { + throw new AJXP_Exception(implode("\n", $out)); + } + if (!$this->extractAll) { + rename($tmpFileThumb, $targetFile); + if ($isStream) { AJXP_Logger::debug("Copy preview file to remote", $backToStreamTarget); copy($targetFile, $backToStreamTarget); unlink($targetFile); } - }else{ - if($isStream){ - if(is_file(str_replace(".$extension", "", $targetFile))){ + } else { + if ($isStream) { + if (is_file(str_replace(".$extension", "", $targetFile))) { $targetFile = str_replace(".$extension", "", $targetFile); } - if(is_file($targetFile)){ + if (is_file($targetFile)) { AJXP_Logger::debug("Copy preview file to remote", $backToStreamTarget); copy($targetFile, $backToStreamTarget); unlink($targetFile); } AJXP_Logger::debug("Searching for ", str_replace(".jpg", "-0.jpg", $tmpFileThumb)); $i = 0; - while(file_exists(str_replace(".jpg", "-$i.jpg", $tmpFileThumb))){ + while (file_exists(str_replace(".jpg", "-$i.jpg", $tmpFileThumb))) { $page = str_replace(".jpg", "-$i.jpg", $tmpFileThumb); $remote_page = str_replace(".$extension", "-$i.jpg", $backToStreamTarget); AJXP_Logger::debug("Copy preview file to remote", $remote_page); @@ -308,33 +313,33 @@ public function generateJpegsCallback($masterFile, $targetFile){ } } } - return true; - } - - protected function handleMime($filename){ - $mimesAtt = explode(",", $this->xPath->query("@mimes")->item(0)->nodeValue); - $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); - return in_array($ext, $mimesAtt); - } - - protected function countPages($file) - { - $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); - if($ext != "pdf") return 20; - if(!file_exists($file))return null; - if (!$fp = @fopen($file,"r"))return null; - $max=0; - while(!feof($fp)) { - $line = fgets($fp, 255); - if (preg_match('/\/Count [0-9]+/', $line, $matches)){ - preg_match('/[0-9]+/',$matches[0], $matches2); - if ($max<$matches2[0]) $max=$matches2[0]; - } - } - fclose($fp); - return (int)$max; - } + return true; + } + + protected function handleMime($filename) + { + $mimesAtt = explode(",", $this->xPath->query("@mimes")->item(0)->nodeValue); + $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + return in_array($ext, $mimesAtt); + } + + protected function countPages($file) + { + $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + if($ext != "pdf") return 20; + if(!file_exists($file))return null; + if (!$fp = @fopen($file,"r"))return null; + $max=0; + while (!feof($fp)) { + $line = fgets($fp, 255); + if (preg_match('/\/Count [0-9]+/', $line, $matches)) { + preg_match('/[0-9]+/',$matches[0], $matches2); + if ($max<$matches2[0]) $max=$matches2[0]; + } + } + fclose($fp); + return (int) $max; + } + - } -?> \ No newline at end of file diff --git a/core/src/plugins/editor.imagick/i18n/conf/en.php b/core/src/plugins/editor.imagick/i18n/conf/en.php index 984151845e..940648d957 100644 --- a/core/src/plugins/editor.imagick/i18n/conf/en.php +++ b/core/src/plugins/editor.imagick/i18n/conf/en.php @@ -28,4 +28,3 @@ "Viewer Quality" => "Viewer Quality", "Quality used for generation the high scale images" => "Quality used for generation the high scale images", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.imagick/i18n/conf/fr.php b/core/src/plugins/editor.imagick/i18n/conf/fr.php index 28a52abf05..e215f90290 100644 --- a/core/src/plugins/editor.imagick/i18n/conf/fr.php +++ b/core/src/plugins/editor.imagick/i18n/conf/fr.php @@ -28,4 +28,3 @@ "Viewer Quality" => "Qualité viewer", "Quality used for generation the high scale images" => "Qualité pour le rendu des pages en grand écran.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.imagick/i18n/conf/pt.php b/core/src/plugins/editor.imagick/i18n/conf/pt.php index 06e2926175..53da39f4c7 100644 --- a/core/src/plugins/editor.imagick/i18n/conf/pt.php +++ b/core/src/plugins/editor.imagick/i18n/conf/pt.php @@ -28,4 +28,3 @@ "Viewer Quality" => "Qualidade de Visualização", "Quality used for generation the high scale images" => "Qualidade a ser usada para gerar imagens de grandes dimensões", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.imagick/manifest.xml b/core/src/plugins/editor.imagick/manifest.xml index 6c8f1df349..7624d09b2a 100644 --- a/core/src/plugins/editor.imagick/manifest.xml +++ b/core/src/plugins/editor.imagick/manifest.xml @@ -19,7 +19,7 @@ - + @@ -42,5 +42,5 @@ - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.infopanel/manifest.xml b/core/src/plugins/editor.infopanel/manifest.xml index b7d7e0a2ca..2bf80031bc 100644 --- a/core/src/plugins/editor.infopanel/manifest.xml +++ b/core/src/plugins/editor.infopanel/manifest.xml @@ -34,4 +34,4 @@ - \ No newline at end of file + diff --git a/core/src/plugins/editor.openlayer/i18n/conf/en.php b/core/src/plugins/editor.openlayer/i18n/conf/en.php index c366b33cfa..c26e2c2fe4 100644 --- a/core/src/plugins/editor.openlayer/i18n/conf/en.php +++ b/core/src/plugins/editor.openlayer/i18n/conf/en.php @@ -22,4 +22,3 @@ "Map viewer" => "Map viewer", "Geolocation feature to either display a WMS layer or simply place an exif-localized photo. Requires OpenLayers" => "Geolocation feature to either display a WMS layer or simply place an exif-localized photo. Requires OpenLayers", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.openlayer/i18n/conf/fr.php b/core/src/plugins/editor.openlayer/i18n/conf/fr.php index d7467c9dc7..bf4b684732 100644 --- a/core/src/plugins/editor.openlayer/i18n/conf/fr.php +++ b/core/src/plugins/editor.openlayer/i18n/conf/fr.php @@ -22,4 +22,3 @@ "Map viewer" => "Cartes", "Geolocation feature to either display a WMS layer or simply place an exif-localized photo. Requires OpenLayers" => "Basé sur la librairie OpenLayers, affiche la géolocalisation d'une photo, ou un layer WMS.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.openlayer/i18n/conf/pt.php b/core/src/plugins/editor.openlayer/i18n/conf/pt.php index db05c7f8c0..cb3c55e298 100644 --- a/core/src/plugins/editor.openlayer/i18n/conf/pt.php +++ b/core/src/plugins/editor.openlayer/i18n/conf/pt.php @@ -22,4 +22,3 @@ "Map viewer" => "Visualizador de Mapas", "Geolocation feature to either display a WMS layer or simply place an exif-localized photo. Requires OpenLayers" => "Função de Geolocalização que mostra uma camada WMS ou simplesmente localiza a informação EXIF de uma fotografia. Requer o Serviço OpenLayers", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.openlayer/i18n/de.php b/core/src/plugins/editor.openlayer/i18n/de.php index 2261fdff49..bd38fb435b 100644 --- a/core/src/plugins/editor.openlayer/i18n/de.php +++ b/core/src/plugins/editor.openlayer/i18n/de.php @@ -11,6 +11,4 @@ "8" => "Filter", "9" => "Suchen", "10" => "Löschen", -) - -?> +); diff --git a/core/src/plugins/editor.openlayer/i18n/en.php b/core/src/plugins/editor.openlayer/i18n/en.php index 1ec87efbf8..4847b02609 100644 --- a/core/src/plugins/editor.openlayer/i18n/en.php +++ b/core/src/plugins/editor.openlayer/i18n/en.php @@ -11,6 +11,4 @@ "8" => "Filter", "9" => "Search", "10" => "Clear", -) - -?> \ No newline at end of file +); diff --git a/core/src/plugins/editor.openlayer/i18n/es.php b/core/src/plugins/editor.openlayer/i18n/es.php index 7bf84e05d7..255f790b3d 100644 --- a/core/src/plugins/editor.openlayer/i18n/es.php +++ b/core/src/plugins/editor.openlayer/i18n/es.php @@ -11,6 +11,4 @@ "8" => "Filtrar", "9" => "Buscar", "10" => "Limpiar", -) - -?> +); diff --git a/core/src/plugins/editor.openlayer/i18n/et.php b/core/src/plugins/editor.openlayer/i18n/et.php index 04092b4aae..dcfe460c19 100644 --- a/core/src/plugins/editor.openlayer/i18n/et.php +++ b/core/src/plugins/editor.openlayer/i18n/et.php @@ -15,5 +15,3 @@ "9" => "Otsi", "10" => "Puhasta", ); - -?> diff --git a/core/src/plugins/editor.openlayer/i18n/fr.php b/core/src/plugins/editor.openlayer/i18n/fr.php index 6677105f5a..f2bd035b89 100644 --- a/core/src/plugins/editor.openlayer/i18n/fr.php +++ b/core/src/plugins/editor.openlayer/i18n/fr.php @@ -11,6 +11,4 @@ "8" => "Filtre", "9" => "Chercher", "10" => "Effacer", -) - -?> \ No newline at end of file +); diff --git a/core/src/plugins/editor.openlayer/i18n/pt.php b/core/src/plugins/editor.openlayer/i18n/pt.php index 1d333528bc..9775021684 100644 --- a/core/src/plugins/editor.openlayer/i18n/pt.php +++ b/core/src/plugins/editor.openlayer/i18n/pt.php @@ -11,6 +11,4 @@ "8" => "Filtro", "9" => "Procurar", "10" => "Limpar", -) - -?> \ No newline at end of file +); diff --git a/core/src/plugins/editor.openlayer/i18n/si.php b/core/src/plugins/editor.openlayer/i18n/si.php index e8c5137251..829bf0c962 100644 --- a/core/src/plugins/editor.openlayer/i18n/si.php +++ b/core/src/plugins/editor.openlayer/i18n/si.php @@ -19,7 +19,7 @@ * The latest code can be found at . */ // Slovenian translation: April 21 2011 by Vladimir Bohinc (vladimir.bohinc@gmail.com) -// +// //--------------------------------------------------------------------------------------------------- $mess=array( "1" => "Zemljevid OpenLayers", @@ -33,4 +33,3 @@ "9" => "Najdi", "10" => "Počisti", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.openlayer/manifest.xml b/core/src/plugins/editor.openlayer/manifest.xml index 86ee67f738..ac30ef22ce 100644 --- a/core/src/plugins/editor.openlayer/manifest.xml +++ b/core/src/plugins/editor.openlayer/manifest.xml @@ -30,7 +30,7 @@ } return true; ]]> - +
    @@ -73,10 +73,10 @@
    - + ]]>
    - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.other/manifest.xml b/core/src/plugins/editor.other/manifest.xml index f73711d3cd..1ad738962b 100644 --- a/core/src/plugins/editor.other/manifest.xml +++ b/core/src/plugins/editor.other/manifest.xml @@ -22,7 +22,7 @@ - + ]]> - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.other/resources/i18n/ca.php b/core/src/plugins/editor.other/resources/i18n/ca.php index 50e36a07e8..ec60dc1ebc 100644 --- a/core/src/plugins/editor.other/resources/i18n/ca.php +++ b/core/src/plugins/editor.other/resources/i18n/ca.php @@ -24,5 +24,4 @@ "3" => "Triar un altre editor per obrir aquest fitxer", "4" => "Alerta, aquests editors do tenen el fitxer declarat com a suportat, el seu comportament pot ser impredictible!", "5" => "Netejar les associacions existents", -); -?> +); diff --git a/core/src/plugins/editor.other/resources/i18n/conf/en.php b/core/src/plugins/editor.other/resources/i18n/conf/en.php index 34e5d13525..2abbc9dcac 100644 --- a/core/src/plugins/editor.other/resources/i18n/conf/en.php +++ b/core/src/plugins/editor.other/resources/i18n/conf/en.php @@ -22,4 +22,3 @@ "Open in..." => "Open in...", "Simple Picker to open any type of file in any available editor." => "Simple Picker to open any type of file in any available editor.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.other/resources/i18n/conf/fr.php b/core/src/plugins/editor.other/resources/i18n/conf/fr.php index 0b08e57958..026a63fec2 100644 --- a/core/src/plugins/editor.other/resources/i18n/conf/fr.php +++ b/core/src/plugins/editor.other/resources/i18n/conf/fr.php @@ -22,4 +22,3 @@ "Open in..." => "Ouvrir dans...", "Simple Picker to open any type of file in any available editor." => "Choisir n'importe quel éditeur pour ouvrir n'importe quel fichier.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.other/resources/i18n/conf/pt.php b/core/src/plugins/editor.other/resources/i18n/conf/pt.php index 873106ee63..b52f2fcb11 100644 --- a/core/src/plugins/editor.other/resources/i18n/conf/pt.php +++ b/core/src/plugins/editor.other/resources/i18n/conf/pt.php @@ -22,4 +22,3 @@ "Open in..." => "Abrir em...", "Simple Picker to open any type of file in any available editor." => "Seleccionador Simples para abrir qualquer tipo de ficheiro em qualquer um dos editores disponíveis.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.other/resources/i18n/de.php b/core/src/plugins/editor.other/resources/i18n/de.php index e48b3cd862..507e706c2c 100644 --- a/core/src/plugins/editor.other/resources/i18n/de.php +++ b/core/src/plugins/editor.other/resources/i18n/de.php @@ -24,5 +24,4 @@ "3" => "Einen anderen Editor zum Öffnen dieser Datei wählen", "4" => "Achtung dieser Editor ist nicht geeignet zum Öffnen dieses Dateityps, das Verhalten ist nicht vorhersehbar!", "5" => "Clear existing associations", -); -?> +); diff --git a/core/src/plugins/editor.other/resources/i18n/en.php b/core/src/plugins/editor.other/resources/i18n/en.php index dd19bb7122..47977d8801 100644 --- a/core/src/plugins/editor.other/resources/i18n/en.php +++ b/core/src/plugins/editor.other/resources/i18n/en.php @@ -24,5 +24,4 @@ "3" => "Select another editor to open this file", "4" => "Warning, these editors do not declare to be supporting this file type, their behaviour maybe unpredictable!", "5" => "Clear existing associations", -); -?> \ No newline at end of file +); diff --git a/core/src/plugins/editor.other/resources/i18n/es.php b/core/src/plugins/editor.other/resources/i18n/es.php index 06df6b0de2..fa17077d08 100644 --- a/core/src/plugins/editor.other/resources/i18n/es.php +++ b/core/src/plugins/editor.other/resources/i18n/es.php @@ -24,5 +24,4 @@ "3" => "Elija otro editor para abrir este fichero", "4" => "Atención, estos editores no parecen soportar este tipo de archivos, su comportamiento puede ser impredecible!", "5" => "Borrar las asociaciones existentes", -); -?> +); diff --git a/core/src/plugins/editor.other/resources/i18n/et.php b/core/src/plugins/editor.other/resources/i18n/et.php index b8686915cb..75e56bcda8 100644 --- a/core/src/plugins/editor.other/resources/i18n/et.php +++ b/core/src/plugins/editor.other/resources/i18n/et.php @@ -27,5 +27,4 @@ "3" => "Vali selle faili muutmiseks muu redaktor", "4" => "Tähelepanu, need redaktorid ei avalda, et oskavad sellist failitüüpi käsitleda. Tulemust ei pruugi vastata ootustele!", "5" => "Tühista olemas olevad seosed", -); -?> +); diff --git a/core/src/plugins/editor.other/resources/i18n/fr.php b/core/src/plugins/editor.other/resources/i18n/fr.php index f324337f73..33fbbc2e41 100644 --- a/core/src/plugins/editor.other/resources/i18n/fr.php +++ b/core/src/plugins/editor.other/resources/i18n/fr.php @@ -25,4 +25,3 @@ "4" => "Warning, these editors do not declare to be supporting this file type, their behaviour maybe unpredictable!", "5" => "Clear existing associations", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.other/resources/i18n/pt.php b/core/src/plugins/editor.other/resources/i18n/pt.php index 3e918778b8..47df1ba030 100644 --- a/core/src/plugins/editor.other/resources/i18n/pt.php +++ b/core/src/plugins/editor.other/resources/i18n/pt.php @@ -24,5 +24,4 @@ "3" => "seleccione outro editor para abrir este ficheiro", "4" => "ATENÇÃO: Estes editores declaram que não suportam este tipo de ficheiro, o comportamento dos mesmos pode ser imprevisível!", "5" => "Apagar todas as associações existentes", -); -?> \ No newline at end of file +); diff --git a/core/src/plugins/editor.pixlr/class.PixlrEditor.php b/core/src/plugins/editor.pixlr/class.PixlrEditor.php index 75bebb5b72..232d6252e3 100644 --- a/core/src/plugins/editor.pixlr/class.PixlrEditor.php +++ b/core/src/plugins/editor.pixlr/class.PixlrEditor.php @@ -26,26 +26,26 @@ * @package AjaXplorer_Plugins * @subpackage Editor */ -class PixlrEditor extends AJXP_Plugin { - - public function switchAction($action, $httpVars, $filesVars){ - +class PixlrEditor extends AJXP_Plugin +{ + public function switchAction($action, $httpVars, $filesVars) + { if(!isSet($this->actions[$action])) return false; - + $repository = ConfService::getRepository(); - if(!$repository->detectStreamWrapper(true)){ + if (!$repository->detectStreamWrapper(true)) { return false; } - + $streamData = $repository->streamData; $destStreamURL = $streamData["protocol"]."://".$repository->getId(); - - if($action == "post_to_server"){ - + + if ($action == "post_to_server") { + $file = base64_decode($httpVars["file"]); $file = SystemTextEncoding::magicDequote(AJXP_Utils::securePath($file)); $target = base64_decode($httpVars["parent_url"])."/plugins/editor.pixlr"; - $tmp = call_user_func(array($streamData["classname"], "getRealFSReference"), $destStreamURL.$file); + $tmp = call_user_func(array($streamData["classname"], "getRealFSReference"), $destStreamURL.$file); $tmp = SystemTextEncoding::fromUTF8($tmp); $fData = array("tmp_name" => $tmp, "name" => urlencode(basename($file)), "type" => "image/jpg"); //var_dump($fData); @@ -55,10 +55,10 @@ public function switchAction($action, $httpVars, $filesVars){ $httpClient = new HttpClient("pixlr.com"); //$httpClient->setDebug(true); - $postData = array(); + $postData = array(); $httpClient->setHandleRedirects(false); $saveTarget = $target."/fake_save_pixlr.php"; - if($this->getFilteredOption("CHECK_SECURITY_TOKEN", $repository->getId())){ + if ($this->getFilteredOption("CHECK_SECURITY_TOKEN", $repository->getId())) { $saveTarget = $target."/fake_save_pixlr_".md5($httpVars["secure_token"]).".php"; } $params = array( @@ -75,8 +75,8 @@ public function switchAction($action, $httpVars, $filesVars){ $httpClient->postFile("/editor/", $params, "image", $fData); $loc = $httpClient->getHeader("location"); header("Location:$loc"); - - }else if($action == "retrieve_pixlr_image"){ + + } else if ($action == "retrieve_pixlr_image") { $file = AJXP_Utils::decodeSecureMagic($httpVars["original_file"]); $node = new AJXP_Node($destStreamURL.$file); $node->loadNodeInfo(); @@ -84,28 +84,28 @@ public function switchAction($action, $httpVars, $filesVars){ $url = $httpVars["new_url"]; $urlParts = parse_url($url); $query = $urlParts["query"]; - if($this->getFilteredOption("CHECK_SECURITY_TOKEN", $repository->getId())){ + if ($this->getFilteredOption("CHECK_SECURITY_TOKEN", $repository->getId())) { $scriptName = basename($urlParts["path"]); $token = str_replace(array("fake_save_pixlr_", ".php"), "", $scriptName); - if($token != md5($httpVars["secure_token"])){ + if ($token != md5($httpVars["secure_token"])) { throw new AJXP_Exception("Invalid Token, this could mean some security problem!"); } } $params = array(); parse_str($query, $params); - $image = $params['image']; + $image = $params['image']; $headers = get_headers($image, 1); $content_type = explode("/", $headers['Content-Type']); - if ($content_type[0] != "image"){ + if ($content_type[0] != "image") { throw new AJXP_Exception("Invalid File Type"); } $content_length = intval($headers["Content-Length"]); if($content_length != 0) AJXP_Controller::applyHook("node.before_change", array(&$node, $content_length)); - + $orig = fopen($image, "r"); $target = fopen($destStreamURL.$file, "w"); - while(!feof($orig)){ + while (!feof($orig)) { fwrite($target, fread($orig, 4096)); } fclose($orig); @@ -114,13 +114,12 @@ public function switchAction($action, $httpVars, $filesVars){ AJXP_Controller::applyHook("node.change", array(&$node)); //header("Content-Type:text/plain"); //print($mess[115]); - + } - - + + return ; - + } - + } -?> \ No newline at end of file diff --git a/core/src/plugins/editor.pixlr/fake_close_pixlr.php b/core/src/plugins/editor.pixlr/fake_close_pixlr.php index ad313d54a9..cfb3ee3ff3 100644 --- a/core/src/plugins/editor.pixlr/fake_close_pixlr.php +++ b/core/src/plugins/editor.pixlr/fake_close_pixlr.php @@ -2,4 +2,4 @@


    -
    Please wait while closing Pixlr editor...
    \ No newline at end of file +
    Please wait while closing Pixlr editor...
    diff --git a/core/src/plugins/editor.pixlr/fake_save_pixlr.php b/core/src/plugins/editor.pixlr/fake_save_pixlr.php index 8049f40b38..22901fd964 100644 --- a/core/src/plugins/editor.pixlr/fake_save_pixlr.php +++ b/core/src/plugins/editor.pixlr/fake_save_pixlr.php @@ -2,4 +2,4 @@


    -
    Please wait while saving Pixlr image...
    \ No newline at end of file +
    Please wait while saving Pixlr image...
    diff --git a/core/src/plugins/editor.pixlr/i18n/conf/en.php b/core/src/plugins/editor.pixlr/i18n/conf/en.php index 66bce366b0..86eb8f5f07 100644 --- a/core/src/plugins/editor.pixlr/i18n/conf/en.php +++ b/core/src/plugins/editor.pixlr/i18n/conf/en.php @@ -24,4 +24,3 @@ "Add a secure token to the target script to make sure that we are downloading an authorized image. The .htaccess file contained in the plugin must be correctly configured (apache)" => "Add a secure token to the target script to make sure that we are downloading an authorized image. The .htaccess file contained in the plugin must be correctly configured (apache)", "Secure Token" => "Secure Token", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.pixlr/i18n/conf/fr.php b/core/src/plugins/editor.pixlr/i18n/conf/fr.php index fc4766f500..4261779243 100644 --- a/core/src/plugins/editor.pixlr/i18n/conf/fr.php +++ b/core/src/plugins/editor.pixlr/i18n/conf/fr.php @@ -24,4 +24,3 @@ "Add a secure token to the target script to make sure that we are downloading an authorized image. The .htaccess file contained in the plugin must be correctly configured (apache)" => "Ajouter un jeton de sécurité dans la communication entre votre serveur et le service Pixlr. Le fichier .htaccess doit être correctement configuré.", "Secure Token" => "Jeton de Sécurité", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.pixlr/i18n/conf/pt.php b/core/src/plugins/editor.pixlr/i18n/conf/pt.php index 9a5a563778..3cd3e86089 100644 --- a/core/src/plugins/editor.pixlr/i18n/conf/pt.php +++ b/core/src/plugins/editor.pixlr/i18n/conf/pt.php @@ -24,4 +24,3 @@ "Add a secure token to the target script to make sure that we are downloading an authorized image. The .htaccess file contained in the plugin must be correctly configured (apache)" => "Adicionar um código de segurança ao script de destino para se certificar de que pode fazer a transferência de uma imagem. O ficheiro .htaccess presente neste plugin tem que estar correctamente configurado (apache)", "Secure Token" => "Código de Segurança", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.pixlr/manifest.xml b/core/src/plugins/editor.pixlr/manifest.xml index f18e2b6ea4..3aa3813c25 100644 --- a/core/src/plugins/editor.pixlr/manifest.xml +++ b/core/src/plugins/editor.pixlr/manifest.xml @@ -15,9 +15,9 @@ +
    -
    + ]]>
    @@ -36,5 +36,5 @@ - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.soundmanager/i18n/conf/en.php b/core/src/plugins/editor.soundmanager/i18n/conf/en.php index d41607fdde..d6d71f0594 100644 --- a/core/src/plugins/editor.soundmanager/i18n/conf/en.php +++ b/core/src/plugins/editor.soundmanager/i18n/conf/en.php @@ -22,4 +22,3 @@ "Audio Player" => "Sound Player", "Uses HTML5 or Flash to play a sound" => "Uses HTML5 or Flash to play a sound", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.soundmanager/i18n/conf/pt.php b/core/src/plugins/editor.soundmanager/i18n/conf/pt.php index 6189f9e8fe..f084c87c62 100644 --- a/core/src/plugins/editor.soundmanager/i18n/conf/pt.php +++ b/core/src/plugins/editor.soundmanager/i18n/conf/pt.php @@ -22,4 +22,3 @@ "Audio Player" => "Reprodutor de Música", "Uses HTML5 or Flash to play a sound" => "Utiliza um reprodutor HTML5 ou Flash para reproduzir música", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.soundmanager/i18n/en.php b/core/src/plugins/editor.soundmanager/i18n/en.php index ae03662478..ceef62cee6 100644 --- a/core/src/plugins/editor.soundmanager/i18n/en.php +++ b/core/src/plugins/editor.soundmanager/i18n/en.php @@ -21,4 +21,4 @@ $mess=array( "1" => "Sound Volume", "2" => "Sound Player", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.soundmanager/i18n/et.php b/core/src/plugins/editor.soundmanager/i18n/et.php index e67d6f9906..53be11a9ba 100644 --- a/core/src/plugins/editor.soundmanager/i18n/et.php +++ b/core/src/plugins/editor.soundmanager/i18n/et.php @@ -26,4 +26,3 @@ "1" => "Helitugevus", "2" => "Helimängija", ); -?> diff --git a/core/src/plugins/editor.soundmanager/i18n/pt.php b/core/src/plugins/editor.soundmanager/i18n/pt.php index f523659ebf..436c675199 100644 --- a/core/src/plugins/editor.soundmanager/i18n/pt.php +++ b/core/src/plugins/editor.soundmanager/i18n/pt.php @@ -21,4 +21,4 @@ $mess=array( "1" => "Volume", "2" => "Reprodutor de Música", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.soundmanager/manifest.xml b/core/src/plugins/editor.soundmanager/manifest.xml index 4156f9dd44..490ed1d46f 100644 --- a/core/src/plugins/editor.soundmanager/manifest.xml +++ b/core/src/plugins/editor.soundmanager/manifest.xml @@ -1,35 +1,35 @@ - - - - - - - - - - - - - -
    -
    - - ]]>
    - - - - - - - - - -
    \ No newline at end of file + + + + + + + + + + + + + +
    +
    + + ]]>
    + + + + + + + + + +
    diff --git a/core/src/plugins/editor.text/i18n/conf/en.php b/core/src/plugins/editor.text/i18n/conf/en.php index e791926d27..3408873774 100644 --- a/core/src/plugins/editor.text/i18n/conf/en.php +++ b/core/src/plugins/editor.text/i18n/conf/en.php @@ -22,4 +22,3 @@ "Text Editor" => "Text Editor", "Very basic text editor" => "Very basic text editor", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.text/i18n/conf/fr.php b/core/src/plugins/editor.text/i18n/conf/fr.php index 6a361cf3f6..7730119b57 100644 --- a/core/src/plugins/editor.text/i18n/conf/fr.php +++ b/core/src/plugins/editor.text/i18n/conf/fr.php @@ -22,4 +22,3 @@ "Text Editor" => "Editeur Text", "Very basic text editor" => "editeur text basique", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.text/i18n/conf/pt.php b/core/src/plugins/editor.text/i18n/conf/pt.php index 5518cf00af..471382b39b 100644 --- a/core/src/plugins/editor.text/i18n/conf/pt.php +++ b/core/src/plugins/editor.text/i18n/conf/pt.php @@ -22,4 +22,3 @@ "Text Editor" => "Editor de Texto", "Very basic text editor" => "Editor de Texto básico", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.text/manifest.xml b/core/src/plugins/editor.text/manifest.xml index 18f32926f8..676357df8d 100644 --- a/core/src/plugins/editor.text/manifest.xml +++ b/core/src/plugins/editor.text/manifest.xml @@ -12,10 +12,10 @@ AJXP_MESSAGE[53]
    AJXP_MESSAGE[53]
    AJXP_MESSAGE[88]
    AJXP_MESSAGE[88]
    - - ]]> + + ]]> - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.video/class.VideoReader.php b/core/src/plugins/editor.video/class.VideoReader.php index b2a8d03962..3255a0ad78 100644 --- a/core/src/plugins/editor.video/class.VideoReader.php +++ b/core/src/plugins/editor.video/class.VideoReader.php @@ -26,116 +26,112 @@ * @package AjaXplorer_Plugins * @subpackage Editor */ -class VideoReader extends AJXP_Plugin { - - public function switchAction($action, $httpVars, $filesVars){ - - if(!isSet($this->actions[$action])) return false; - - $repository = ConfService::getRepository(); - if(!$repository->detectStreamWrapper(true)){ - return false; - } - - $streamData = $repository->streamData; - $destStreamURL = $streamData["protocol"]."://".$repository->getId(); - - if($action == "read_video_data"){ - AJXP_Logger::debug("Reading video"); +class VideoReader extends AJXP_Plugin +{ + public function switchAction($action, $httpVars, $filesVars) + { + if(!isSet($this->actions[$action])) return false; + + $repository = ConfService::getRepository(); + if (!$repository->detectStreamWrapper(true)) { + return false; + } + + $streamData = $repository->streamData; + $destStreamURL = $streamData["protocol"]."://".$repository->getId(); + + if ($action == "read_video_data") { + AJXP_Logger::debug("Reading video"); $file = AJXP_Utils::decodeSecureMagic($httpVars["file"]); $node = new AJXP_Node($destStreamURL.$file); session_write_close(); $filesize = filesize($destStreamURL.$file); - $filename = $destStreamURL.$file; + $filename = $destStreamURL.$file; //$fp = fopen($destStreamURL.$file, "r"); - if(preg_match("/\.ogv$/", $file)){ - header("Content-Type: video/ogg; name=\"".basename($file)."\""); - }else if(preg_match("/\.mp4$/", $file)){ - header("Content-Type: video/mp4; name=\"".basename($file)."\""); - }else if(preg_match("/\.m4v$/", $file)){ - header("Content-Type: video/x-m4v; name=\"".basename($file)."\""); - }else if(preg_match("/\.webm$/", $file)){ - header("Content-Type: video/webm; name=\"".basename($file)."\""); - } + if (preg_match("/\.ogv$/", $file)) { + header("Content-Type: video/ogg; name=\"".basename($file)."\""); + } else if (preg_match("/\.mp4$/", $file)) { + header("Content-Type: video/mp4; name=\"".basename($file)."\""); + } else if (preg_match("/\.m4v$/", $file)) { + header("Content-Type: video/x-m4v; name=\"".basename($file)."\""); + } else if (preg_match("/\.webm$/", $file)) { + header("Content-Type: video/webm; name=\"".basename($file)."\""); + } - if ( isset($_SERVER['HTTP_RANGE']) && $filesize != 0 ) - { - AJXP_Logger::debug("Http range", array($_SERVER['HTTP_RANGE'])); - // multiple ranges, which can become pretty complex, so ignore it for now - $ranges = explode('=', $_SERVER['HTTP_RANGE']); - $offsets = explode('-', $ranges[1]); - $offset = floatval($offsets[0]); + if ( isset($_SERVER['HTTP_RANGE']) && $filesize != 0 ) { + AJXP_Logger::debug("Http range", array($_SERVER['HTTP_RANGE'])); + // multiple ranges, which can become pretty complex, so ignore it for now + $ranges = explode('=', $_SERVER['HTTP_RANGE']); + $offsets = explode('-', $ranges[1]); + $offset = floatval($offsets[0]); - $length = floatval($offsets[1]) - $offset; - if (!$length) $length = $filesize - $offset; - if ($length + $offset > $filesize || $length < 0) $length = $filesize - $offset; - header('HTTP/1.1 206 Partial Content'); + $length = floatval($offsets[1]) - $offset; + if (!$length) $length = $filesize - $offset; + if ($length + $offset > $filesize || $length < 0) $length = $filesize - $offset; + header('HTTP/1.1 206 Partial Content'); - header('Content-Range: bytes ' . $offset . '-' . ($offset + $length - 1) . '/' . $filesize); - header('Accept-Ranges:bytes'); - header("Content-Length: ". $length); - $file = fopen($filename, 'rb'); - fseek($file, 0); - $relOffset = $offset; - while ($relOffset > 2.0E9) - { - // seek to the requested offset, this is 0 if it's not a partial content request - fseek($file, 2000000000, SEEK_CUR); - $relOffset -= 2000000000; - // This works because we never overcome the PHP 32 bit limit - } - fseek($file, $relOffset, SEEK_CUR); + header('Content-Range: bytes ' . $offset . '-' . ($offset + $length - 1) . '/' . $filesize); + header('Accept-Ranges:bytes'); + header("Content-Length: ". $length); + $file = fopen($filename, 'rb'); + fseek($file, 0); + $relOffset = $offset; + while ($relOffset > 2.0E9) { + // seek to the requested offset, this is 0 if it's not a partial content request + fseek($file, 2000000000, SEEK_CUR); + $relOffset -= 2000000000; + // This works because we never overcome the PHP 32 bit limit + } + fseek($file, $relOffset, SEEK_CUR); while(ob_get_level()) ob_end_flush(); - $readSize = 0.0; - while (!feof($file) && $readSize < $length && connection_status() == 0) - { - echo fread($file, 2048); - $readSize += 2048.0; - flush(); - } - fclose($file); - } else { - $fp = fopen($filename, "rb"); - header("Content-Length: ".$filesize); - header("Content-Range: bytes 0-" . ($filesize - 1) . "/" . $filesize. ";"); - header('Cache-Control: public'); - - $class = $streamData["classname"]; - $stream = fopen("php://output", "a"); - call_user_func(array($streamData["classname"], "copyFileInStream"), $destStreamURL.$file, $stream); - fflush($stream); - fclose($stream); - } + $readSize = 0.0; + while (!feof($file) && $readSize < $length && connection_status() == 0) { + echo fread($file, 2048); + $readSize += 2048.0; + flush(); + } + fclose($file); + } else { + $fp = fopen($filename, "rb"); + header("Content-Length: ".$filesize); + header("Content-Range: bytes 0-" . ($filesize - 1) . "/" . $filesize. ";"); + header('Cache-Control: public'); + + $class = $streamData["classname"]; + $stream = fopen("php://output", "a"); + call_user_func(array($streamData["classname"], "copyFileInStream"), $destStreamURL.$file, $stream); + fflush($stream); + fclose($stream); + } AJXP_Controller::applyHook("node.read", array($node)); - }else if($action == "get_sess_id"){ - HTMLWriter::charsetHeader("text/plain"); - print(session_id()); - } - } + } else if ($action == "get_sess_id") { + HTMLWriter::charsetHeader("text/plain"); + print(session_id()); + } + } /** * @param AJXP_Node $ajxpNode */ - public function videoAlternateVersions(&$ajxpNode){ + public function videoAlternateVersions(&$ajxpNode) + { if(!preg_match('/\.mpg$|\.mp4$|\.ogv$|\.webm$/i', $ajxpNode->getLabel())) return; - if(file_exists(str_replace(".mpg","_PREVIEW.mp4", $ajxpNode->getUrl()))){ + if (file_exists(str_replace(".mpg","_PREVIEW.mp4", $ajxpNode->getUrl()))) { $ajxpNode->mergeMetadata(array("video_altversion_mp4" => str_replace(".mpg","_PREVIEW.mp4", $ajxpNode->getPath()))); } $rotating = array("mp4","ogv", "webm"); - foreach($rotating as $ext){ - if(preg_match('/\.'.$ext.'$/i', $ajxpNode->getLabel())){ - foreach($rotating as $other){ + foreach ($rotating as $ext) { + if (preg_match('/\.'.$ext.'$/i', $ajxpNode->getLabel())) { + foreach ($rotating as $other) { if($other == $ext) continue; - if(file_exists(str_replace($ext, $other,$ajxpNode->getUrl()))){ + if (file_exists(str_replace($ext, $other,$ajxpNode->getUrl()))) { $ajxpNode->mergeMetadata(array("video_altversion_".$other => str_replace($ext, $other, $ajxpNode->getPath()))); } } } } } - -} -?> \ No newline at end of file +} diff --git a/core/src/plugins/editor.video/i18n/conf/en.php b/core/src/plugins/editor.video/i18n/conf/en.php index 7483483c80..98303993f7 100644 --- a/core/src/plugins/editor.video/i18n/conf/en.php +++ b/core/src/plugins/editor.video/i18n/conf/en.php @@ -21,4 +21,4 @@ $mess=array( "Video Player" => "Video Player", "Inserts a video player in the info panel, either HTML5 or Flash depending on the format." => "Inserts a video player in the info panel, either HTML5 or Flash depending on the format.", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.video/i18n/conf/fr.php b/core/src/plugins/editor.video/i18n/conf/fr.php index 9cf8f828c0..364d911b02 100644 --- a/core/src/plugins/editor.video/i18n/conf/fr.php +++ b/core/src/plugins/editor.video/i18n/conf/fr.php @@ -22,4 +22,3 @@ "Video Player" => "Player Video", "Inserts a video player in the info panel, either HTML5 or Flash depending on the format." => "Player HTML5 avec fallback en flash pour pouvoir visualiser un maximum de vidéos en ligne.", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.video/i18n/conf/pt.php b/core/src/plugins/editor.video/i18n/conf/pt.php index 80e0c14c3d..0401d36efc 100644 --- a/core/src/plugins/editor.video/i18n/conf/pt.php +++ b/core/src/plugins/editor.video/i18n/conf/pt.php @@ -21,4 +21,4 @@ $mess=array( "Video Player" => "Reprodutor de Vídeo", "Inserts a video player in the info panel, either HTML5 or Flash depending on the format." => "Insere um reprodutor de vídeo no painel de informações no formato HTML5 ou Flash dependendo do formato do vídeo.", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.video/i18n/en.php b/core/src/plugins/editor.video/i18n/en.php index f5b5642425..9f124c071e 100644 --- a/core/src/plugins/editor.video/i18n/en.php +++ b/core/src/plugins/editor.video/i18n/en.php @@ -20,4 +20,4 @@ */ $mess=array( "1" => "Media Player", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.video/i18n/pt.php b/core/src/plugins/editor.video/i18n/pt.php index 6dd063efe2..cd8c9e716e 100644 --- a/core/src/plugins/editor.video/i18n/pt.php +++ b/core/src/plugins/editor.video/i18n/pt.php @@ -20,4 +20,4 @@ */ $mess=array( "1" => "Reprodutor de Media", -); \ No newline at end of file +); diff --git a/core/src/plugins/editor.video/manifest.xml b/core/src/plugins/editor.video/manifest.xml index de797a3388..3ff709f431 100644 --- a/core/src/plugins/editor.video/manifest.xml +++ b/core/src/plugins/editor.video/manifest.xml @@ -39,5 +39,5 @@ - - \ No newline at end of file + + diff --git a/core/src/plugins/editor.zoho/agent/save_zoho.php b/core/src/plugins/editor.zoho/agent/save_zoho.php index 9ce82ce798..5939aae74a 100644 --- a/core/src/plugins/editor.zoho/agent/save_zoho.php +++ b/core/src/plugins/editor.zoho/agent/save_zoho.php @@ -1,17 +1,14 @@ \ No newline at end of file diff --git a/core/src/plugins/editor.zoho/class.ZohoEditor.php b/core/src/plugins/editor.zoho/class.ZohoEditor.php index 8fd4bb4cab..23ebee7a4c 100644 --- a/core/src/plugins/editor.zoho/class.ZohoEditor.php +++ b/core/src/plugins/editor.zoho/class.ZohoEditor.php @@ -28,28 +28,29 @@ * @package AjaXplorer_Plugins * @subpackage Editor */ -class ZohoEditor extends AJXP_Plugin { - - public function performChecks(){ - if(!extension_loaded("openssl")){ +class ZohoEditor extends AJXP_Plugin +{ + public function performChecks() + { + if (!extension_loaded("openssl")) { throw new Exception("Zoho plugin requires PHP 'openssl' extension, as posting the document to the Zoho server requires the Https protocol."); } } - public function switchAction($action, $httpVars, $filesVars){ - - if(!isSet($this->actions[$action])) return false; - - $repository = ConfService::getRepository(); - if(!$repository->detectStreamWrapper(true)){ - return false; - } - - $streamData = $repository->streamData; - $destStreamURL = $streamData["protocol"]."://".$repository->getId(); - - if($action == "post_to_zohoserver"){ + public function switchAction($action, $httpVars, $filesVars) + { + if(!isSet($this->actions[$action])) return false; + + $repository = ConfService::getRepository(); + if (!$repository->detectStreamWrapper(true)) { + return false; + } + + $streamData = $repository->streamData; + $destStreamURL = $streamData["protocol"]."://".$repository->getId(); + + if ($action == "post_to_zohoserver") { $sheetExt = explode(",", "xls,xlsx,ods,sxc,csv,tsv"); $presExt = explode(",", "ppt,pps,odp,sxi"); @@ -57,31 +58,31 @@ public function switchAction($action, $httpVars, $filesVars){ require_once(AJXP_BIN_FOLDER."/http_class/http_class.php"); - $file = base64_decode($httpVars["file"]); - $file = SystemTextEncoding::magicDequote(AJXP_Utils::securePath($file)); - $target = base64_decode($httpVars["parent_url"]); - $tmp = call_user_func(array($streamData["classname"], "getRealFSReference"), $destStreamURL.$file); - $tmp = SystemTextEncoding::fromUTF8($tmp); + $file = base64_decode($httpVars["file"]); + $file = SystemTextEncoding::magicDequote(AJXP_Utils::securePath($file)); + $target = base64_decode($httpVars["parent_url"]); + $tmp = call_user_func(array($streamData["classname"], "getRealFSReference"), $destStreamURL.$file); + $tmp = SystemTextEncoding::fromUTF8($tmp); $node = new AJXP_Node($destStreamURL.$file); AJXP_Controller::applyHook("node.read", array($node)); $extension = strtolower(pathinfo(urlencode(basename($file)), PATHINFO_EXTENSION)); - $httpClient = new http_class(); + $httpClient = new http_class(); $httpClient->request_method = "POST"; $secureToken = $httpVars["secure_token"]; $_SESSION["ZOHO_CURRENT_EDITED"] = $destStreamURL.$file; $_SESSION["ZOHO_CURRENT_UUID"] = md5(rand()."-".microtime()); - if($this->getFilteredOption("USE_ZOHO_AGENT", $repository->getId())){ + if ($this->getFilteredOption("USE_ZOHO_AGENT", $repository->getId())) { $saveUrl = $this->getFilteredOption("ZOHO_AGENT_URL", $repository->getId()); - }else{ + } else { $saveUrl = $target."/".AJXP_PLUGINS_FOLDER."/editor.zoho/agent/save_zoho.php"; } - $params = array( + $params = array( 'id' => $_SESSION["ZOHO_CURRENT_UUID"], 'apikey' => $this->getFilteredOption("ZOHO_API_KEY", $repository->getId()), 'output' => 'url', @@ -91,14 +92,14 @@ public function switchAction($action, $httpVars, $filesVars){ 'format' => $extension, 'mode' => 'normaledit', 'saveurl' => $saveUrl - ); + ); $service = "exportwriter"; - if(in_array($extension, $sheetExt)){ + if (in_array($extension, $sheetExt)) { $service = "sheet"; - }else if(in_array($extension, $presExt)){ + } else if (in_array($extension, $presExt)) { $service = "show"; - }else if(in_array($extension, $docExt)){ + } else if (in_array($extension, $docExt)) { $service = "exportwriter"; } $arguments = array(); @@ -108,11 +109,11 @@ public function switchAction($action, $httpVars, $filesVars){ "content" => array("FileName" => $tmp, "Content-Type" => "automatic/name") ); $err = $httpClient->Open($arguments); - if(empty($err)){ + if (empty($err)) { $err = $httpClient->SendRequest($arguments); - if(empty($err)){ + if (empty($err)) { $response = ""; - while(true){ + while (true) { $body = ""; $error = $httpClient->ReadReplyBody($body, 1000); if($error != "" || strlen($body) == 0) break; @@ -121,13 +122,13 @@ public function switchAction($action, $httpVars, $filesVars){ $result = trim($response); $matchlines = explode("\n", $result); $resultValues = array(); - foreach($matchlines as $line){ + foreach ($matchlines as $line) { list($key, $val) = explode("=", $line, 2); $resultValues[$key] = $val; } - if($resultValues["RESULT"] == "TRUE" && isSet($resultValues["URL"])){ + if ($resultValues["RESULT"] == "TRUE" && isSet($resultValues["URL"])) { header("Location: ".$resultValues["URL"]); - }else{ + } else { echo "Zoho API Error ".$resultValues["ERROR_CODE"]." : ".$resultValues["WARNING"]; echo ""; } @@ -135,21 +136,21 @@ public function switchAction($action, $httpVars, $filesVars){ $httpClient->Close(); } - }else if($action == "retrieve_from_zohoagent"){ + } else if ($action == "retrieve_from_zohoagent") { $targetFile = $_SESSION["ZOHO_CURRENT_EDITED"]; $id = $_SESSION["ZOHO_CURRENT_UUID"].".".pathinfo($targetFile, PATHINFO_EXTENSION); $node = new AJXP_Node($targetFile); $node->loadNodeInfo(); AJXP_Controller::applyHook("node.before_change", array(&$node)); - if($this->getFilteredOption("USE_ZOHO_AGENT",$repository->getId()) ){ + if ($this->getFilteredOption("USE_ZOHO_AGENT",$repository->getId()) ) { $data = AJXP_Utils::getRemoteContent( $this->getFilteredOption("ZOHO_AGENT_URL",$repository->getId())."?ajxp_action=get_file&name=".$id); - if(strlen($data)){ + if (strlen($data)) { file_put_contents($targetFile, $data); echo "MODIFIED"; } - }else{ - if(is_file(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/editor.zoho/agent/files/".$id)){ + } else { + if (is_file(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/editor.zoho/agent/files/".$id)) { copy(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/editor.zoho/agent/files/".$id, $targetFile); unlink(AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/editor.zoho/agent/files/".$id); echo "MODIFIED"; @@ -159,6 +160,6 @@ public function switchAction($action, $httpVars, $filesVars){ } - } - + } + } diff --git a/core/src/plugins/editor.zoho/i18n/conf/en.php b/core/src/plugins/editor.zoho/i18n/conf/en.php index 84191bd163..b74fac6170 100644 --- a/core/src/plugins/editor.zoho/i18n/conf/en.php +++ b/core/src/plugins/editor.zoho/i18n/conf/en.php @@ -28,4 +28,3 @@ "If you use the agent, enter its URL here." => "If you use the agent, enter its URL here.", "Z-Agent URL" => "Z-Agent URL", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.zoho/i18n/conf/fr.php b/core/src/plugins/editor.zoho/i18n/conf/fr.php index c83e0f4772..5640a7a8a9 100644 --- a/core/src/plugins/editor.zoho/i18n/conf/fr.php +++ b/core/src/plugins/editor.zoho/i18n/conf/fr.php @@ -28,4 +28,3 @@ "If you use the agent, enter its URL here." => "Si vous utilisez le mode Z-Agent, entrez son URL complète ici, de type http://domain/path/to/agent/save_zoho.php", "Z-Agent URL" => "URL Z-agent", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.zoho/i18n/conf/pt.php b/core/src/plugins/editor.zoho/i18n/conf/pt.php index c604f2faa3..b6b7eba525 100644 --- a/core/src/plugins/editor.zoho/i18n/conf/pt.php +++ b/core/src/plugins/editor.zoho/i18n/conf/pt.php @@ -28,4 +28,3 @@ "If you use the agent, enter its URL here." => "Se usar este agente, coloque o seu URL aqui.", "Z-Agent URL" => "URL Z-Agent", ); -?> \ No newline at end of file diff --git a/core/src/plugins/editor.zoho/i18n/en.php b/core/src/plugins/editor.zoho/i18n/en.php index 4b67a05d44..23cb21e80a 100644 --- a/core/src/plugins/editor.zoho/i18n/en.php +++ b/core/src/plugins/editor.zoho/i18n/en.php @@ -25,4 +25,3 @@ "4" => "Presentation Document", "5" => "Spreadsheet Document", ); -?> diff --git a/core/src/plugins/editor.zoho/i18n/et.php b/core/src/plugins/editor.zoho/i18n/et.php index a4952e0768..0981e11f34 100644 --- a/core/src/plugins/editor.zoho/i18n/et.php +++ b/core/src/plugins/editor.zoho/i18n/et.php @@ -29,4 +29,3 @@ "4" => "Esitlusdokument", "5" => "Tabelarvutusdokument", ); -?> diff --git a/core/src/plugins/editor.zoho/manifest.xml b/core/src/plugins/editor.zoho/manifest.xml index 716781d7b8..818b6d8444 100644 --- a/core/src/plugins/editor.zoho/manifest.xml +++ b/core/src/plugins/editor.zoho/manifest.xml @@ -15,9 +15,9 @@ +
    -
    + ]]>
    @@ -58,5 +58,5 @@ - + diff --git a/core/src/plugins/feed.sql/class.AJXP_SqlFeedStore.php b/core/src/plugins/feed.sql/class.AJXP_SqlFeedStore.php index 6d2eec617f..b16e735c8d 100644 --- a/core/src/plugins/feed.sql/class.AJXP_SqlFeedStore.php +++ b/core/src/plugins/feed.sql/class.AJXP_SqlFeedStore.php @@ -1,181 +1,187 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die('Access not allowed'); - -/** - * @package AjaXplorer_Plugins - * @subpackage Feed - */ -class AJXP_SqlFeedStore extends AJXP_Plugin implements AJXP_FeedStore -{ - - private $sqlDriver; - - public function init($options){ - $this->sqlDriver = AJXP_Utils::cleanDibiDriverParameters($options["SQL_DRIVER"]); - parent::init($options); - } - - public function performChecks(){ - if(!isSet($this->options)) return; - $test = AJXP_Utils::cleanDibiDriverParameters($this->options["SQL_DRIVER"]); - if(!count($test)){ - throw new Exception("Please define an SQL connexion in the core configuration"); - } - } - - - /** - * @param string $hookName - * @param mixed $data - * @param string $repositoryId - * @param string $repositoryScope - * @param string $repositoryOwner - * @param string $userId - * @param string $userGroup - * @return void - */ - public function persistEvent($hookName, $data, $repositoryId, $repositoryScope, $repositoryOwner, $userId, $userGroup) - { - if($this->sqlDriver["password"] == "XXXX") return; - require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); - dibi::connect($this->sqlDriver); - try{ - dibi::query("INSERT INTO [ajxp_feed] ([edate],[etype],[htype],[user_id],[repository_id],[repository_owner],[user_group],[repository_scope],[content]) VALUES (%i,%s,%s,%s,%s,%s,%s,%s,%bin)", time(), "event", "node.change", $userId, $repositoryId, $repositoryOwner, $userGroup, ($repositoryScope !== false ? $repositoryScope : "ALL"), serialize($data)); - }catch (DibiException $e){ - AJXP_Logger::logAction("error: (trying to persist event)". $e->getMessage()); - } - } - - /** - * @param array $filterByRepositories - * @param string $userId - * @param string $userGroup - * @param integer $offset - * @param integer $limit - * @return An array of stdClass objects with keys hookname, arguments, author, date, repository - */ - public function loadEvents($filterByRepositories, $userId, $userGroup, $offset = 0, $limit = 10) - { - if($this->sqlDriver["password"] == "XXXX") return array(); - require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); - dibi::connect($this->sqlDriver); - $res = dibi::query("SELECT * FROM [ajxp_feed] WHERE [etype] = %s AND - ( [repository_id] IN (%s) OR [repository_owner] = %s ) - AND ( - [repository_scope] = 'ALL' - OR ([repository_scope] = 'USER' AND [user_id] = %s ) - OR ([repository_scope] = 'GROUP' AND [user_group] = %s ) - ) - ORDER BY [edate] DESC LIMIT $offset,$limit ", "event", $filterByRepositories, $userId, $userId, $userGroup); - $data = array(); - foreach($res as $n => $row){ - $object = new stdClass(); - $object->hookname = $row->htype; - $object->arguments = unserialize($row->content); - $object->author = $row->user_id; - $object->date = $row->edate; - $object->repository = $row->repository_id; - $object->event_id = $row->id; - $data[] = $object; - } - return $data; - } - - /** - * @abstract - * @param AJXP_Notification $notif - * @return mixed - */ - public function persistAlert(AJXP_Notification $notif){ - if(!$notif->getNode()) return; - $repositoryId = $notif->getNode()->getRepositoryId(); - $userId = $notif->getTarget(); - if($this->sqlDriver["password"] == "XXXX") return; - require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); - dibi::connect($this->sqlDriver); - try{ - dibi::query("INSERT INTO [ajxp_feed] ([edate],[etype],[htype],[user_id],[repository_id],[content]) VALUES (%i,%s,%s,%s,%s,%bin)", - time(), "alert", "notification", $userId, $repositoryId, serialize($notif)); - }catch (DibiException $e){ - AJXP_Logger::logAction("error: (trying to persist alert)". $e->getMessage()); - } - } - - /** - * @abstract - * @param $userId - * @param null $repositoryIdFilter - * @return mixed - */ - public function loadAlerts($userId, $repositoryIdFilter = null){ - if($this->sqlDriver["password"] == "XXXX") return array(); - require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); - dibi::connect($this->sqlDriver); - if($repositoryIdFilter != null){ - $res = dibi::query("SELECT * FROM [ajxp_feed] WHERE [etype] = %s AND [repository_id] = %s AND [user_id] = %s ORDER BY [edate] DESC LIMIT 0,100 ", "alert", $repositoryIdFilter, $userId); - }else{ - $res = dibi::query("SELECT * FROM [ajxp_feed] WHERE [etype] = %s AND [user_id] = %s ORDER BY [edate] DESC LIMIT 0,100 ", "alert", $userId); - } - $data = array(); - foreach($res as $n => $row){ - $test = unserialize($row->content); - if(is_a($test, "AJXP_Notification")){ - $test->alert_id = $row->id; - $data[] = $test; - } - } - return $data; - } - - /** - * @param $occurrences - * @param $alertId - */ - public function dismissAlertById($alertId, $occurrences = 1){ - require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); - dibi::connect($this->sqlDriver); - $userId = AuthService::getLoggedUser()->getId(); - if($occurrences == 1){ - dibi::query("DELETE FROM [ajxp_feed] WHERE [id] = %i AND [user_id] = %s", $alertId, $userId); - }else{ - $res = dibi::query("SELECT * FROM [ajxp_feed] WHERE [id] = %i AND [user_id] = %s", $alertId, $userId); - foreach($res as $n => $row){ - $startEventRow = $row; - break; - } - $startEventNotif = new AJXP_Notification(); - $startEventNotif = unserialize($startEventRow->content); - $url = $startEventNotif->getNode()->getUrl(); - $date = $startEventRow->edate; - $newRes = dibi::query("SELECT [id] FROM [ajxp_feed] WHERE [etype] = %s AND [user_id] = %s AND [edate] <= %s AND content LIKE %s ORDER BY [edate] DESC LIMIT 0,$occurrences", "alert", $userId, $date, "%\"$url\"%"); - $a = $newRes->fetchPairs(); - dibi::query("DELETE FROM [ajxp_feed] WHERE [id] IN (%s)", $a); - } - } - - public function installSQLTables($param){ - $p = AJXP_Utils::cleanDibiDriverParameters($param["SQL_DRIVER"]); - return AJXP_Utils::runCreateTablesQuery($p, $this->getBaseDir()."/create.sql"); - } - -} \ No newline at end of file + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die('Access not allowed'); + +/** + * @package AjaXplorer_Plugins + * @subpackage Feed + */ +class AJXP_SqlFeedStore extends AJXP_Plugin implements AJXP_FeedStore +{ + + private $sqlDriver; + + public function init($options) + { + $this->sqlDriver = AJXP_Utils::cleanDibiDriverParameters($options["SQL_DRIVER"]); + parent::init($options); + } + + public function performChecks() + { + if(!isSet($this->options)) return; + $test = AJXP_Utils::cleanDibiDriverParameters($this->options["SQL_DRIVER"]); + if (!count($test)) { + throw new Exception("Please define an SQL connexion in the core configuration"); + } + } + + + /** + * @param string $hookName + * @param mixed $data + * @param string $repositoryId + * @param string $repositoryScope + * @param string $repositoryOwner + * @param string $userId + * @param string $userGroup + * @return void + */ + public function persistEvent($hookName, $data, $repositoryId, $repositoryScope, $repositoryOwner, $userId, $userGroup) + { + if($this->sqlDriver["password"] == "XXXX") return; + require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); + dibi::connect($this->sqlDriver); + try { + dibi::query("INSERT INTO [ajxp_feed] ([edate],[etype],[htype],[user_id],[repository_id],[repository_owner],[user_group],[repository_scope],[content]) VALUES (%i,%s,%s,%s,%s,%s,%s,%s,%bin)", time(), "event", "node.change", $userId, $repositoryId, $repositoryOwner, $userGroup, ($repositoryScope !== false ? $repositoryScope : "ALL"), serialize($data)); + } catch (DibiException $e) { + AJXP_Logger::logAction("error: (trying to persist event)". $e->getMessage()); + } + } + + /** + * @param array $filterByRepositories + * @param string $userId + * @param string $userGroup + * @param integer $offset + * @param integer $limit + * @return An array of stdClass objects with keys hookname, arguments, author, date, repository + */ + public function loadEvents($filterByRepositories, $userId, $userGroup, $offset = 0, $limit = 10) + { + if($this->sqlDriver["password"] == "XXXX") return array(); + require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); + dibi::connect($this->sqlDriver); + $res = dibi::query("SELECT * FROM [ajxp_feed] WHERE [etype] = %s AND + ( [repository_id] IN (%s) OR [repository_owner] = %s ) + AND ( + [repository_scope] = 'ALL' + OR ([repository_scope] = 'USER' AND [user_id] = %s ) + OR ([repository_scope] = 'GROUP' AND [user_group] = %s ) + ) + ORDER BY [edate] DESC LIMIT $offset,$limit ", "event", $filterByRepositories, $userId, $userId, $userGroup); + $data = array(); + foreach ($res as $n => $row) { + $object = new stdClass(); + $object->hookname = $row->htype; + $object->arguments = unserialize($row->content); + $object->author = $row->user_id; + $object->date = $row->edate; + $object->repository = $row->repository_id; + $object->event_id = $row->id; + $data[] = $object; + } + return $data; + } + + /** + * @abstract + * @param AJXP_Notification $notif + * @return mixed + */ + public function persistAlert(AJXP_Notification $notif) + { + if(!$notif->getNode()) return; + $repositoryId = $notif->getNode()->getRepositoryId(); + $userId = $notif->getTarget(); + if($this->sqlDriver["password"] == "XXXX") return; + require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); + dibi::connect($this->sqlDriver); + try { + dibi::query("INSERT INTO [ajxp_feed] ([edate],[etype],[htype],[user_id],[repository_id],[content]) VALUES (%i,%s,%s,%s,%s,%bin)", + time(), "alert", "notification", $userId, $repositoryId, serialize($notif)); + } catch (DibiException $e) { + AJXP_Logger::logAction("error: (trying to persist alert)". $e->getMessage()); + } + } + + /** + * @abstract + * @param $userId + * @param null $repositoryIdFilter + * @return mixed + */ + public function loadAlerts($userId, $repositoryIdFilter = null) + { + if($this->sqlDriver["password"] == "XXXX") return array(); + require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); + dibi::connect($this->sqlDriver); + if ($repositoryIdFilter != null) { + $res = dibi::query("SELECT * FROM [ajxp_feed] WHERE [etype] = %s AND [repository_id] = %s AND [user_id] = %s ORDER BY [edate] DESC LIMIT 0,100 ", "alert", $repositoryIdFilter, $userId); + } else { + $res = dibi::query("SELECT * FROM [ajxp_feed] WHERE [etype] = %s AND [user_id] = %s ORDER BY [edate] DESC LIMIT 0,100 ", "alert", $userId); + } + $data = array(); + foreach ($res as $n => $row) { + $test = unserialize($row->content); + if (is_a($test, "AJXP_Notification")) { + $test->alert_id = $row->id; + $data[] = $test; + } + } + return $data; + } + + /** + * @param $occurrences + * @param $alertId + */ + public function dismissAlertById($alertId, $occurrences = 1) + { + require_once(AJXP_BIN_FOLDER."/dibi.compact.php"); + dibi::connect($this->sqlDriver); + $userId = AuthService::getLoggedUser()->getId(); + if ($occurrences == 1) { + dibi::query("DELETE FROM [ajxp_feed] WHERE [id] = %i AND [user_id] = %s", $alertId, $userId); + } else { + $res = dibi::query("SELECT * FROM [ajxp_feed] WHERE [id] = %i AND [user_id] = %s", $alertId, $userId); + foreach ($res as $n => $row) { + $startEventRow = $row; + break; + } + $startEventNotif = new AJXP_Notification(); + $startEventNotif = unserialize($startEventRow->content); + $url = $startEventNotif->getNode()->getUrl(); + $date = $startEventRow->edate; + $newRes = dibi::query("SELECT [id] FROM [ajxp_feed] WHERE [etype] = %s AND [user_id] = %s AND [edate] <= %s AND content LIKE %s ORDER BY [edate] DESC LIMIT 0,$occurrences", "alert", $userId, $date, "%\"$url\"%"); + $a = $newRes->fetchPairs(); + dibi::query("DELETE FROM [ajxp_feed] WHERE [id] IN (%s)", $a); + } + } + + public function installSQLTables($param) + { + $p = AJXP_Utils::cleanDibiDriverParameters($param["SQL_DRIVER"]); + return AJXP_Utils::runCreateTablesQuery($p, $this->getBaseDir()."/create.sql"); + } + +} diff --git a/core/src/plugins/feed.sql/manifest.xml b/core/src/plugins/feed.sql/manifest.xml index 18711f267b..91a91e4228 100644 --- a/core/src/plugins/feed.sql/manifest.xml +++ b/core/src/plugins/feed.sql/manifest.xml @@ -1,10 +1,10 @@ - - - - - - - - \ No newline at end of file + + + + + + + + diff --git a/core/src/plugins/gui.ajax/ajxpclient_actions.xml b/core/src/plugins/gui.ajax/ajxpclient_actions.xml index 2dfa0eaddc..bb996098b5 100644 --- a/core/src/plugins/gui.ajax/ajxpclient_actions.xml +++ b/core/src/plugins/gui.ajax/ajxpclient_actions.xml @@ -1,179 +1,179 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> - - - - - - - - - - -
    -
    -
    - - ]]>
    -
    -
    -
    -
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ]]> + + + + + + + + + + +
    +
    +
    + + ]]>
    +
    +
    +
    +
    diff --git a/core/src/plugins/gui.ajax/class.AJXP_ClientDriver.php b/core/src/plugins/gui.ajax/class.AJXP_ClientDriver.php index 7a22ea1519..6f55400e3a 100644 --- a/core/src/plugins/gui.ajax/class.AJXP_ClientDriver.php +++ b/core/src/plugins/gui.ajax/class.AJXP_ClientDriver.php @@ -1,377 +1,379 @@ - - * This file is part of AjaXplorer. - * - * AjaXplorer is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AjaXplorer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with AjaXplorer. If not, see . - * - * The latest code can be found at . - */ - -defined('AJXP_EXEC') or die( 'Access not allowed'); - -/** - * User Interface main implementation - * @package AjaXplorer_Plugins - * @subpackage Gui - */ -class AJXP_ClientDriver extends AJXP_Plugin -{ - private static $loadedBookmarks; - - public function isEnabled(){ - return true; - } - - public function loadConfigs($configData){ - parent::loadConfigs($configData); - if(preg_match('/MSIE 7/',$_SERVER['HTTP_USER_AGENT'])){ - // Force legacy theme for the moment - $this->pluginConf["GUI_THEME"] = "oxygen"; - } - if(!defined("AJXP_THEME_FOLDER")){ - define("CLIENT_RESOURCES_FOLDER", AJXP_PLUGINS_FOLDER."/gui.ajax/res"); - define("AJXP_THEME_FOLDER", CLIENT_RESOURCES_FOLDER."/themes/".$this->pluginConf["GUI_THEME"]); - } - if(!isSet($configData["CLIENT_TIMEOUT_TIME"])){ - $this->pluginConf["CLIENT_TIMEOUT_TIME"] = intval(ini_get("session.gc_maxlifetime")); - } - } - - function switchAction($action, $httpVars, $fileVars) - { - if(!isSet($this->actions[$action])) return; - if(preg_match('/MSIE 7/',$_SERVER['HTTP_USER_AGENT'])){ - // Force legacy theme for the moment - $this->pluginConf["GUI_THEME"] = "oxygen"; - } - if(!defined("AJXP_THEME_FOLDER")){ - define("CLIENT_RESOURCES_FOLDER", AJXP_PLUGINS_FOLDER."/gui.ajax/res"); - define("AJXP_THEME_FOLDER", CLIENT_RESOURCES_FOLDER."/themes/".$this->pluginConf["GUI_THEME"]); - } - foreach($httpVars as $getName=>$getValue){ - $$getName = AJXP_Utils::securePath($getValue); - } - if(isSet($dir) && $action != "upload") $dir = SystemTextEncoding::fromUTF8($dir); - $mess = ConfService::getMessages(); - - switch ($action){ - //------------------------------------ - // GET AN HTML TEMPLATE - //------------------------------------ - case "get_template": - - HTMLWriter::charsetHeader(); - $folder = CLIENT_RESOURCES_FOLDER."/html"; - if(isSet($httpVars["pluginName"])){ - $folder = AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/".AJXP_Utils::securePath($httpVars["pluginName"]); - if(isSet($httpVars["pluginPath"])){ - $folder.= "/".AJXP_Utils::securePath($httpVars["pluginPath"]); - } - } - $crtTheme = $this->pluginConf["GUI_THEME"]; - $thFolder = AJXP_THEME_FOLDER."/html"; - if(isset($template_name)) - { - if(is_file($thFolder."/".$template_name)){ - include($thFolder."/".$template_name); - }else if(is_file($folder."/".$template_name)){ - include($folder."/".$template_name); - } - } - - break; - - //------------------------------------ - // GET I18N MESSAGES - //------------------------------------ - case "get_i18n_messages": - - $refresh = false; - if(isSet($httpVars["lang"])){ - ConfService::setLanguage($httpVars["lang"]); - $refresh = true; - } - HTMLWriter::charsetHeader('text/javascript'); - HTMLWriter::writeI18nMessagesClass(ConfService::getMessages($refresh)); - - break; - - //------------------------------------ - // SEND XML REGISTRY - //------------------------------------ - case "get_xml_registry" : - - $regDoc = AJXP_PluginsService::getXmlRegistry(); - $changes = AJXP_Controller::filterRegistryFromRole($regDoc); - if($changes) AJXP_PluginsService::updateXmlRegistry($regDoc); - - $clone = $regDoc->cloneNode(true); - $clonePath = new DOMXPath($clone); - $serverCallbacks = $clonePath->query("//serverCallback|hooks"); - foreach($serverCallbacks as $callback){ - $processing = $callback->parentNode->removeChild($callback); - } - - if(isSet($_GET["xPath"])){ - //$regPath = new DOMXPath($regDoc); - $nodes = $clonePath->query($_GET["xPath"]); - AJXP_XMLWriter::header("ajxp_registry_part", array("xPath"=>$_GET["xPath"])); - if($nodes->length){ - print(AJXP_XMLWriter::replaceAjxpXmlKeywords($clone->saveXML($nodes->item(0)))); - } - AJXP_XMLWriter::close("ajxp_registry_part"); - }else{ - AJXP_Utils::safeIniSet("zlib.output_compression", "4096"); - header('Content-Type: application/xml; charset=UTF-8'); - print(AJXP_XMLWriter::replaceAjxpXmlKeywords($clone->saveXML())); - } - - break; - - //------------------------------------ - // DISPLAY DOC - //------------------------------------ - case "display_doc": - - HTMLWriter::charsetHeader(); - echo HTMLWriter::getDocFile(AJXP_Utils::securePath(htmlentities($_GET["doc_file"]))); - - break; - - - //------------------------------------ - // GET BOOT GUI - //------------------------------------ - case "get_boot_gui": - - HTMLWriter::internetExplorerMainDocumentHeader(); - HTMLWriter::charsetHeader(); - - if(!is_file(TESTS_RESULT_FILE)){ - $outputArray = array(); - $testedParams = array(); - $passed = AJXP_Utils::runTests($outputArray, $testedParams); - if(!$passed && !isset($_GET["ignore_tests"])){ - die(AJXP_Utils::testResultsToTable($outputArray, $testedParams)); - }else{ - AJXP_Utils::testResultsToFile($outputArray, $testedParams); - } - } - - $START_PARAMETERS = array( - "BOOTER_URL"=>"index.php?get_action=get_boot_conf", - "MAIN_ELEMENT" => "ajxp_desktop" - ); - if(AuthService::usersEnabled()) - { - AuthService::preLogUser((isSet($httpVars["remote_session"])?$httpVars["remote_session"]:"")); - AuthService::bootSequence($START_PARAMETERS); - if(AuthService::getLoggedUser() != null || AuthService::logUser(null, null) == 1) - { - if(AuthService::getDefaultRootId() == -1){ - AuthService::disconnect(); - }else{ - $loggedUser = AuthService::getLoggedUser(); - if(!$loggedUser->canRead(ConfService::getCurrentRepositoryId()) - && AuthService::getDefaultRootId() != ConfService::getCurrentRepositoryId()) - { - ConfService::switchRootDir(AuthService::getDefaultRootId()); - } - } - } - } - - AJXP_Utils::parseApplicationGetParameters($_GET, $START_PARAMETERS, $_SESSION); - - $confErrors = ConfService::getErrors(); - if(count($confErrors)){ - $START_PARAMETERS["ALERT"] = implode(", ", array_values($confErrors)); - } - // PRECOMPUTE BOOT CONF - if(!preg_match('/MSIE 7/',$_SERVER['HTTP_USER_AGENT']) && !preg_match('/MSIE 8/',$_SERVER['HTTP_USER_AGENT'])){ - $START_PARAMETERS["PRELOADED_BOOT_CONF"] = $this->computeBootConf(); - } - - // PRECOMPUTE REGISTRY - if(!isSet($START_PARAMETERS["FORCE_REGISTRY_RELOAD"])){ - $regDoc = AJXP_PluginsService::getXmlRegistry(); - $changes = AJXP_Controller::filterRegistryFromRole($regDoc); - if($changes) AJXP_PluginsService::updateXmlRegistry($regDoc); - $clone = $regDoc->cloneNode(true); - $clonePath = new DOMXPath($clone); - $serverCallbacks = $clonePath->query("//serverCallback|hooks"); - foreach($serverCallbacks as $callback){ - $callback->parentNode->removeChild($callback); - } - $START_PARAMETERS["PRELOADED_REGISTRY"] = AJXP_XMLWriter::replaceAjxpXmlKeywords($clone->saveXML()); - } - - $JSON_START_PARAMETERS = json_encode($START_PARAMETERS); - $crtTheme = $this->pluginConf["GUI_THEME"]; - if(ConfService::getConf("JS_DEBUG")){ - if(!isSet($mess)){ - $mess = ConfService::getMessages(); - } - if(is_file(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/themes/$crtTheme/html/gui_debug.html")){ - include(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/themes/$crtTheme/html/gui_debug.html"); - }else{ - include(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/html/gui_debug.html"); - } - }else{ - if(is_file(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/themes/$crtTheme/html/gui.html")){ - $content = file_get_contents(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/themes/$crtTheme/html/gui.html"); - }else{ - $content = file_get_contents(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/html/gui.html"); - } - if(preg_match('/MSIE 7/',$_SERVER['HTTP_USER_AGENT']) || preg_match('/MSIE 8/',$_SERVER['HTTP_USER_AGENT'])){ - $content = str_replace("ajaxplorer_boot.js", "ajaxplorer_boot_protolegacy.js", $content); - } - $content = AJXP_XMLWriter::replaceAjxpXmlKeywords($content, false); - if($JSON_START_PARAMETERS){ - $content = str_replace("//AJXP_JSON_START_PARAMETERS", "startParameters = ".$JSON_START_PARAMETERS.";", $content); - } - print($content); - } - break; - //------------------------------------ - // GET CONFIG FOR BOOT - //------------------------------------ - case "get_boot_conf": - - $out = array(); - AJXP_Utils::parseApplicationGetParameters($_GET, $out, $_SESSION); - $config = $this->computeBootConf(); - header("Content-type:application/json;charset=UTF-8"); - print(json_encode($config)); - - break; - - default; - break; - } - - return false; - } - - function computeBootConf(){ - if(isSet($_GET["server_prefix_uri"])){ - $_SESSION["AJXP_SERVER_PREFIX_URI"] = str_replace("_UP_", "..", $_GET["server_prefix_uri"]); - } - $config = array(); - $config["ajxpResourcesFolder"] = "plugins/gui.ajax/res"; - if(session_name() == "AjaXplorer_Shared"){ - $config["ajxpServerAccess"] = "index_shared.php"; - }else{ - $config["ajxpServerAccess"] = AJXP_SERVER_ACCESS; - } - $config["zipEnabled"] = ConfService::zipEnabled(); - $config["multipleFilesDownloadEnabled"] = ConfService::getCoreConf("ZIP_CREATION"); - $config["customWording"] = array( - "welcomeMessage" => $this->getFilteredOption("CUSTOM_WELCOME_MESSAGE"), - "title" => ConfService::getCoreConf("APPLICATION_TITLE"), - "icon" => $this->getFilteredOption("CUSTOM_ICON"), - "iconWidth" => $this->getFilteredOption("CUSTOM_ICON_WIDTH"), - "iconHeight" => $this->getFilteredOption("CUSTOM_ICON_HEIGHT"), - "iconOnly" => $this->getFilteredOption("CUSTOM_ICON_ONLY"), - "titleFontSize" => $this->getFilteredOption("CUSTOM_FONT_SIZE") - ); - $cIcBin = $this->getFilteredOption("CUSTOM_ICON_BINARY"); - if(!empty($cIcBin)){ - $config["customWording"]["icon_binary_url"] = "get_action=get_global_binary_param&binary_id=".$cIcBin; - } - $config["usersEnabled"] = AuthService::usersEnabled(); - $config["loggedUser"] = (AuthService::getLoggedUser()!=null); - $config["currentLanguage"] = ConfService::getLanguage(); - $config["session_timeout"] = intval(ini_get("session.gc_maxlifetime")); - $timeoutTime = $this->getFilteredOption("CLIENT_TIMEOUT_TIME"); - if(empty($timeoutTime)){ - $to = $config["session_timeout"]; - }else{ - $to = $timeoutTime; - } - $config["client_timeout"] = $to; - $config["client_timeout_warning"] = $this->getFilteredOption("CLIENT_TIMEOUT_WARN"); - $config["availableLanguages"] = ConfService::getConf("AVAILABLE_LANG"); - $config["usersEditable"] = ConfService::getAuthDriverImpl()->usersEditable(); - $config["ajxpVersion"] = AJXP_VERSION; - $config["ajxpVersionDate"] = AJXP_VERSION_DATE; - if(stristr($_SERVER["HTTP_USER_AGENT"], "msie 6")){ - $config["cssResources"] = array("css/pngHack/pngHack.css"); - } - $analytic = $this->getFilteredOption('GOOGLE_ANALYTICS_ID'); - if(!empty($analytic)) { - $config["googleAnalyticsData"] = array( - "id"=> $analytic, - "domain" => $this->getFilteredOption('GOOGLE_ANALYTICS_DOMAIN'), - "event" => $this->getFilteredOption('GOOGLE_ANALYTICS_EVENT') - ); - } - $config["i18nMessages"] = ConfService::getMessages(); - $config["password_min_length"] = ConfService::getCoreConf("PASSWORD_MINLENGTH", "auth"); - $config["SECURE_TOKEN"] = AuthService::generateSecureToken(); - $config["streaming_supported"] = "true"; - $config["theme"] = $this->pluginConf["GUI_THEME"]; - return $config; - } - - /** - * @param AJXP_Node $ajxpNode - * @return void - */ - function nodeBookmarkMetadata(&$ajxpNode){ - $user = AuthService::getLoggedUser(); - if($user == null) return; - $metadata = $ajxpNode->retrieveMetadata("ajxp_bookmarked", true, AJXP_METADATA_SCOPE_REPOSITORY, true); - if(is_array($metadata) && count($metadata)){ - $ajxpNode->mergeMetadata(array( - "ajxp_bookmarked" => "true", - "overlay_icon" => "bookmark.png" - ), true); - return; - } - if(!isSet(self::$loadedBookmarks)){ - self::$loadedBookmarks = $user->getBookmarks(); - } - foreach(self::$loadedBookmarks as $bm){ - if($bm["PATH"] == $ajxpNode->getPath()){ - $ajxpNode->mergeMetadata(array( - "ajxp_bookmarked" => "true", - "overlay_icon" => "bookmark.png" - ), true); - $ajxpNode->setMetadata("ajxp_bookmarked", array("ajxp_bookmarked"=> "true"), true, AJXP_METADATA_SCOPE_REPOSITORY, true); - } - } - } - - static function filterXml(&$value){ - $instance = AJXP_PluginsService::getInstance()->findPlugin("gui", "ajax"); - if($instance === false) return ; - $confs = $instance->getConfigs(); - $theme = $confs["GUI_THEME"]; - if(!defined("AJXP_THEME_FOLDER")){ - define("CLIENT_RESOURCES_FOLDER", AJXP_PLUGINS_FOLDER."/gui.ajax/res"); - define("AJXP_THEME_FOLDER", CLIENT_RESOURCES_FOLDER."/themes/".$theme); - } - $value = str_replace(array("AJXP_CLIENT_RESOURCES_FOLDER", "AJXP_CURRENT_VERSION"), array(CLIENT_RESOURCES_FOLDER, AJXP_VERSION), $value); - if(isSet($_SESSION["AJXP_SERVER_PREFIX_URI"])){ - $value = str_replace("AJXP_THEME_FOLDER", $_SESSION["AJXP_SERVER_PREFIX_URI"]."plugins/gui.ajax/res/themes/".$theme, $value); - }else{ - $value = str_replace("AJXP_THEME_FOLDER", "plugins/gui.ajax/res/themes/".$theme, $value); - } - return $value; - } -} - -AJXP_Controller::registerIncludeHook("xml.filter", array("AJXP_ClientDriver", "filterXml")); + + * This file is part of AjaXplorer. + * + * AjaXplorer is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AjaXplorer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with AjaXplorer. If not, see . + * + * The latest code can be found at . + */ + +defined('AJXP_EXEC') or die( 'Access not allowed'); + +/** + * User Interface main implementation + * @package AjaXplorer_Plugins + * @subpackage Gui + */ +class AJXP_ClientDriver extends AJXP_Plugin +{ + private static $loadedBookmarks; + + public function isEnabled() + { + return true; + } + + public function loadConfigs($configData) + { + parent::loadConfigs($configData); + if (preg_match('/MSIE 7/',$_SERVER['HTTP_USER_AGENT'])) { + // Force legacy theme for the moment + $this->pluginConf["GUI_THEME"] = "oxygen"; + } + if (!defined("AJXP_THEME_FOLDER")) { + define("CLIENT_RESOURCES_FOLDER", AJXP_PLUGINS_FOLDER."/gui.ajax/res"); + define("AJXP_THEME_FOLDER", CLIENT_RESOURCES_FOLDER."/themes/".$this->pluginConf["GUI_THEME"]); + } + if (!isSet($configData["CLIENT_TIMEOUT_TIME"])) { + $this->pluginConf["CLIENT_TIMEOUT_TIME"] = intval(ini_get("session.gc_maxlifetime")); + } + } + + public function switchAction($action, $httpVars, $fileVars) + { + if(!isSet($this->actions[$action])) return; + if (preg_match('/MSIE 7/',$_SERVER['HTTP_USER_AGENT'])) { + // Force legacy theme for the moment + $this->pluginConf["GUI_THEME"] = "oxygen"; + } + if (!defined("AJXP_THEME_FOLDER")) { + define("CLIENT_RESOURCES_FOLDER", AJXP_PLUGINS_FOLDER."/gui.ajax/res"); + define("AJXP_THEME_FOLDER", CLIENT_RESOURCES_FOLDER."/themes/".$this->pluginConf["GUI_THEME"]); + } + foreach ($httpVars as $getName=>$getValue) { + $$getName = AJXP_Utils::securePath($getValue); + } + if(isSet($dir) && $action != "upload") $dir = SystemTextEncoding::fromUTF8($dir); + $mess = ConfService::getMessages(); + + switch ($action) { + //------------------------------------ + // GET AN HTML TEMPLATE + //------------------------------------ + case "get_template": + + HTMLWriter::charsetHeader(); + $folder = CLIENT_RESOURCES_FOLDER."/html"; + if (isSet($httpVars["pluginName"])) { + $folder = AJXP_INSTALL_PATH."/".AJXP_PLUGINS_FOLDER."/".AJXP_Utils::securePath($httpVars["pluginName"]); + if (isSet($httpVars["pluginPath"])) { + $folder.= "/".AJXP_Utils::securePath($httpVars["pluginPath"]); + } + } + $crtTheme = $this->pluginConf["GUI_THEME"]; + $thFolder = AJXP_THEME_FOLDER."/html"; + if (isset($template_name)) { + if (is_file($thFolder."/".$template_name)) { + include($thFolder."/".$template_name); + } else if (is_file($folder."/".$template_name)) { + include($folder."/".$template_name); + } + } + + break; + + //------------------------------------ + // GET I18N MESSAGES + //------------------------------------ + case "get_i18n_messages": + + $refresh = false; + if (isSet($httpVars["lang"])) { + ConfService::setLanguage($httpVars["lang"]); + $refresh = true; + } + HTMLWriter::charsetHeader('text/javascript'); + HTMLWriter::writeI18nMessagesClass(ConfService::getMessages($refresh)); + + break; + + //------------------------------------ + // SEND XML REGISTRY + //------------------------------------ + case "get_xml_registry" : + + $regDoc = AJXP_PluginsService::getXmlRegistry(); + $changes = AJXP_Controller::filterRegistryFromRole($regDoc); + if($changes) AJXP_PluginsService::updateXmlRegistry($regDoc); + + $clone = $regDoc->cloneNode(true); + $clonePath = new DOMXPath($clone); + $serverCallbacks = $clonePath->query("//serverCallback|hooks"); + foreach ($serverCallbacks as $callback) { + $processing = $callback->parentNode->removeChild($callback); + } + + if (isSet($_GET["xPath"])) { + //$regPath = new DOMXPath($regDoc); + $nodes = $clonePath->query($_GET["xPath"]); + AJXP_XMLWriter::header("ajxp_registry_part", array("xPath"=>$_GET["xPath"])); + if ($nodes->length) { + print(AJXP_XMLWriter::replaceAjxpXmlKeywords($clone->saveXML($nodes->item(0)))); + } + AJXP_XMLWriter::close("ajxp_registry_part"); + } else { + AJXP_Utils::safeIniSet("zlib.output_compression", "4096"); + header('Content-Type: application/xml; charset=UTF-8'); + print(AJXP_XMLWriter::replaceAjxpXmlKeywords($clone->saveXML())); + } + + break; + + //------------------------------------ + // DISPLAY DOC + //------------------------------------ + case "display_doc": + + HTMLWriter::charsetHeader(); + echo HTMLWriter::getDocFile(AJXP_Utils::securePath(htmlentities($_GET["doc_file"]))); + + break; + + + //------------------------------------ + // GET BOOT GUI + //------------------------------------ + case "get_boot_gui": + + HTMLWriter::internetExplorerMainDocumentHeader(); + HTMLWriter::charsetHeader(); + + if (!is_file(TESTS_RESULT_FILE)) { + $outputArray = array(); + $testedParams = array(); + $passed = AJXP_Utils::runTests($outputArray, $testedParams); + if (!$passed && !isset($_GET["ignore_tests"])) { + die(AJXP_Utils::testResultsToTable($outputArray, $testedParams)); + } else { + AJXP_Utils::testResultsToFile($outputArray, $testedParams); + } + } + + $START_PARAMETERS = array( + "BOOTER_URL"=>"index.php?get_action=get_boot_conf", + "MAIN_ELEMENT" => "ajxp_desktop" + ); + if (AuthService::usersEnabled()) { + AuthService::preLogUser((isSet($httpVars["remote_session"])?$httpVars["remote_session"]:"")); + AuthService::bootSequence($START_PARAMETERS); + if (AuthService::getLoggedUser() != null || AuthService::logUser(null, null) == 1) { + if (AuthService::getDefaultRootId() == -1) { + AuthService::disconnect(); + } else { + $loggedUser = AuthService::getLoggedUser(); + if(!$loggedUser->canRead(ConfService::getCurrentRepositoryId()) + && AuthService::getDefaultRootId() != ConfService::getCurrentRepositoryId()) + { + ConfService::switchRootDir(AuthService::getDefaultRootId()); + } + } + } + } + + AJXP_Utils::parseApplicationGetParameters($_GET, $START_PARAMETERS, $_SESSION); + + $confErrors = ConfService::getErrors(); + if (count($confErrors)) { + $START_PARAMETERS["ALERT"] = implode(", ", array_values($confErrors)); + } + // PRECOMPUTE BOOT CONF + if (!preg_match('/MSIE 7/',$_SERVER['HTTP_USER_AGENT']) && !preg_match('/MSIE 8/',$_SERVER['HTTP_USER_AGENT'])) { + $START_PARAMETERS["PRELOADED_BOOT_CONF"] = $this->computeBootConf(); + } + + // PRECOMPUTE REGISTRY + if (!isSet($START_PARAMETERS["FORCE_REGISTRY_RELOAD"])) { + $regDoc = AJXP_PluginsService::getXmlRegistry(); + $changes = AJXP_Controller::filterRegistryFromRole($regDoc); + if($changes) AJXP_PluginsService::updateXmlRegistry($regDoc); + $clone = $regDoc->cloneNode(true); + $clonePath = new DOMXPath($clone); + $serverCallbacks = $clonePath->query("//serverCallback|hooks"); + foreach ($serverCallbacks as $callback) { + $callback->parentNode->removeChild($callback); + } + $START_PARAMETERS["PRELOADED_REGISTRY"] = AJXP_XMLWriter::replaceAjxpXmlKeywords($clone->saveXML()); + } + + $JSON_START_PARAMETERS = json_encode($START_PARAMETERS); + $crtTheme = $this->pluginConf["GUI_THEME"]; + if (ConfService::getConf("JS_DEBUG")) { + if (!isSet($mess)) { + $mess = ConfService::getMessages(); + } + if (is_file(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/themes/$crtTheme/html/gui_debug.html")) { + include(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/themes/$crtTheme/html/gui_debug.html"); + } else { + include(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/html/gui_debug.html"); + } + } else { + if (is_file(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/themes/$crtTheme/html/gui.html")) { + $content = file_get_contents(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/themes/$crtTheme/html/gui.html"); + } else { + $content = file_get_contents(AJXP_INSTALL_PATH."/plugins/gui.ajax/res/html/gui.html"); + } + if (preg_match('/MSIE 7/',$_SERVER['HTTP_USER_AGENT']) || preg_match('/MSIE 8/',$_SERVER['HTTP_USER_AGENT'])) { + $content = str_replace("ajaxplorer_boot.js", "ajaxplorer_boot_protolegacy.js", $content); + } + $content = AJXP_XMLWriter::replaceAjxpXmlKeywords($content, false); + if ($JSON_START_PARAMETERS) { + $content = str_replace("//AJXP_JSON_START_PARAMETERS", "startParameters = ".$JSON_START_PARAMETERS.";", $content); + } + print($content); + } + break; + //------------------------------------ + // GET CONFIG FOR BOOT + //------------------------------------ + case "get_boot_conf": + + $out = array(); + AJXP_Utils::parseApplicationGetParameters($_GET, $out, $_SESSION); + $config = $this->computeBootConf(); + header("Content-type:application/json;charset=UTF-8"); + print(json_encode($config)); + + break; + + default; + break; + } + + return false; + } + + public function computeBootConf() + { + if (isSet($_GET["server_prefix_uri"])) { + $_SESSION["AJXP_SERVER_PREFIX_URI"] = str_replace("_UP_", "..", $_GET["server_prefix_uri"]); + } + $config = array(); + $config["ajxpResourcesFolder"] = "plugins/gui.ajax/res"; + if (session_name() == "AjaXplorer_Shared") { + $config["ajxpServerAccess"] = "index_shared.php"; + } else { + $config["ajxpServerAccess"] = AJXP_SERVER_ACCESS; + } + $config["zipEnabled"] = ConfService::zipEnabled(); + $config["multipleFilesDownloadEnabled"] = ConfService::getCoreConf("ZIP_CREATION"); + $config["customWording"] = array( + "welcomeMessage" => $this->getFilteredOption("CUSTOM_WELCOME_MESSAGE"), + "title" => ConfService::getCoreConf("APPLICATION_TITLE"), + "icon" => $this->getFilteredOption("CUSTOM_ICON"), + "iconWidth" => $this->getFilteredOption("CUSTOM_ICON_WIDTH"), + "iconHeight" => $this->getFilteredOption("CUSTOM_ICON_HEIGHT"), + "iconOnly" => $this->getFilteredOption("CUSTOM_ICON_ONLY"), + "titleFontSize" => $this->getFilteredOption("CUSTOM_FONT_SIZE") + ); + $cIcBin = $this->getFilteredOption("CUSTOM_ICON_BINARY"); + if (!empty($cIcBin)) { + $config["customWording"]["icon_binary_url"] = "get_action=get_global_binary_param&binary_id=".$cIcBin; + } + $config["usersEnabled"] = AuthService::usersEnabled(); + $config["loggedUser"] = (AuthService::getLoggedUser()!=null); + $config["currentLanguage"] = ConfService::getLanguage(); + $config["session_timeout"] = intval(ini_get("session.gc_maxlifetime")); + $timeoutTime = $this->getFilteredOption("CLIENT_TIMEOUT_TIME"); + if (empty($timeoutTime)) { + $to = $config["session_timeout"]; + } else { + $to = $timeoutTime; + } + $config["client_timeout"] = $to; + $config["client_timeout_warning"] = $this->getFilteredOption("CLIENT_TIMEOUT_WARN"); + $config["availableLanguages"] = ConfService::getConf("AVAILABLE_LANG"); + $config["usersEditable"] = ConfService::getAuthDriverImpl()->usersEditable(); + $config["ajxpVersion"] = AJXP_VERSION; + $config["ajxpVersionDate"] = AJXP_VERSION_DATE; + if (stristr($_SERVER["HTTP_USER_AGENT"], "msie 6")) { + $config["cssResources"] = array("css/pngHack/pngHack.css"); + } + $analytic = $this->getFilteredOption('GOOGLE_ANALYTICS_ID'); + if (!empty($analytic)) { + $config["googleAnalyticsData"] = array( + "id"=> $analytic, + "domain" => $this->getFilteredOption('GOOGLE_ANALYTICS_DOMAIN'), + "event" => $this->getFilteredOption('GOOGLE_ANALYTICS_EVENT') + ); + } + $config["i18nMessages"] = ConfService::getMessages(); + $config["password_min_length"] = ConfService::getCoreConf("PASSWORD_MINLENGTH", "auth"); + $config["SECURE_TOKEN"] = AuthService::generateSecureToken(); + $config["streaming_supported"] = "true"; + $config["theme"] = $this->pluginConf["GUI_THEME"]; + return $config; + } + + /** + * @param AJXP_Node $ajxpNode + * @return void + */ + public function nodeBookmarkMetadata(&$ajxpNode) + { + $user = AuthService::getLoggedUser(); + if($user == null) return; + $metadata = $ajxpNode->retrieveMetadata("ajxp_bookmarked", true, AJXP_METADATA_SCOPE_REPOSITORY, true); + if (is_array($metadata) && count($metadata)) { + $ajxpNode->mergeMetadata(array( + "ajxp_bookmarked" => "true", + "overlay_icon" => "bookmark.png" + ), true); + return; + } + if (!isSet(self::$loadedBookmarks)) { + self::$loadedBookmarks = $user->getBookmarks(); + } + foreach (self::$loadedBookmarks as $bm) { + if ($bm["PATH"] == $ajxpNode->getPath()) { + $ajxpNode->mergeMetadata(array( + "ajxp_bookmarked" => "true", + "overlay_icon" => "bookmark.png" + ), true); + $ajxpNode->setMetadata("ajxp_bookmarked", array("ajxp_bookmarked"=> "true"), true, AJXP_METADATA_SCOPE_REPOSITORY, true); + } + } + } + + public static function filterXml(&$value) + { + $instance = AJXP_PluginsService::getInstance()->findPlugin("gui", "ajax"); + if($instance === false) return ; + $confs = $instance->getConfigs(); + $theme = $confs["GUI_THEME"]; + if (!defined("AJXP_THEME_FOLDER")) { + define("CLIENT_RESOURCES_FOLDER", AJXP_PLUGINS_FOLDER."/gui.ajax/res"); + define("AJXP_THEME_FOLDER", CLIENT_RESOURCES_FOLDER."/themes/".$theme); + } + $value = str_replace(array("AJXP_CLIENT_RESOURCES_FOLDER", "AJXP_CURRENT_VERSION"), array(CLIENT_RESOURCES_FOLDER, AJXP_VERSION), $value); + if (isSet($_SESSION["AJXP_SERVER_PREFIX_URI"])) { + $value = str_replace("AJXP_THEME_FOLDER", $_SESSION["AJXP_SERVER_PREFIX_URI"]."plugins/gui.ajax/res/themes/".$theme, $value); + } else { + $value = str_replace("AJXP_THEME_FOLDER", "plugins/gui.ajax/res/themes/".$theme, $value); + } + return $value; + } +} + +AJXP_Controller::registerIncludeHook("xml.filter", array("AJXP_ClientDriver", "filterXml")); diff --git a/core/src/plugins/gui.ajax/manifest.xml b/core/src/plugins/gui.ajax/manifest.xml index 4e18288ed2..2156e99001 100644 --- a/core/src/plugins/gui.ajax/manifest.xml +++ b/core/src/plugins/gui.ajax/manifest.xml @@ -162,7 +162,7 @@
    -
    + ]]>