/** * 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, "file"); } catch (Exception $e) { AJXP_Logger::error(__CLASS__, "stream_open", "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; } }
public function init($options) { parent::init($options); if (!extension_loaded("openssl")) { return; } $keyFile = $this->getPluginWorkDir(true) . "/agent.pem"; if (file_exists($keyFile)) { return; } $config = array("digest_alg" => "sha1", "private_key_bits" => 1024, "private_key_type" => OPENSSL_KEYTYPE_RSA); // Create the private and public key $res = openssl_pkey_new($config); if ($res === false) { AJXP_Logger::error(__CLASS__, __FUNCTION__, "Warning, OpenSSL is active but could not correctly generate a key for Zoho Editor. Please make sure the openssl.cnf file is correctly set up."); while ($message = openssl_error_string()) { AJXP_Logger::debug(__CLASS__, __FUNCTION__, "Open SSL Error: " . $message); } } else { openssl_pkey_export_to_file($res, $keyFile); } }
public function checkPassword($login, $password, $seed) { //Our default value. $passwordVerified = false; try { //Send the request. $result = $this->apiCall('POST', 'session', array("login" => $login, "password" => $password)); //Check the returned status. switch ($result->status) { //Proper login. case 201: //Check the user is not blocked. if ($result->body->state !== 'active') { AJXP_Logger::warning(__CLASS__ . '.checkPassword.201', 'Blocked user attempted login [' . $login . ']', ""); } else { $passwordVerified = true; AJXP_Safe::storeCredentials($login, $result->body->private_token); $_SESSION['Auth.GitLab.RemoteAdmin'] = $result->body->is_admin === true; } break; //Proper failure. //Proper failure. case 401: AJXP_Logger::info(__CLASS__ . '.checkPassword.401', 'Not authorized for login [' . $login . ']', ""); break; //We're not sure. //We're not sure. default: AJXP_Logger::info(__CLASS__ . '.checkPassword.###', 'Unknown status code. ' . var_export($result, true), ""); break; } } catch (Exception $e) { AJXP_Logger::error(__CLASS__ . '.checkPassword.ex', $e->getMessage(), ""); } return $passwordVerified; }
/** * See static method * @param Repository|null $repository * @throws AJXP_Exception|Exception * @return AbstractAccessDriver */ private function loadRepositoryDriverInst(&$repository = null) { $rest = false; if ($repository == null) { if (isset($this->configs["ACCESS_DRIVER"]) && is_a($this->configs["ACCESS_DRIVER"], "AbstractAccessDriver")) { return $this->configs["ACCESS_DRIVER"]; } $this->switchRootDirInst(); $repository = $this->getRepositoryInst(); if ($repository == null) { throw new Exception("No active repository found for user!"); } } else { $rest = true; if (isset($repository->driverInstance)) { return $repository->driverInstance; } } /** * @var AbstractAccessDriver $plugInstance */ $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, $repository); } catch (Exception $e) { AJXP_Logger::error(__CLASS__, 'Meta plugin', 'Cannot instanciate Meta plugin, reason : ' . $e->getMessage()); $this->errors[] = $e->getMessage(); } } } // INIT MAIN DRIVER $plugInstance->init($repository); try { $plugInstance->initRepository(); $repository->driverInstance = $plugInstance; } catch (Exception $e) { if (!$rest) { // Remove repositories from the lists if (!is_a($e, "AJXP_UserAlertException")) { $this->removeRepositoryFromCache($repository->getId()); } if (isset($_SESSION["PREVIOUS_REPO_ID"]) && $_SESSION["PREVIOUS_REPO_ID"] != $repository->getId()) { $this->switchRootDir($_SESSION["PREVIOUS_REPO_ID"]); } else { $this->switchRootDir(); } } throw $e; } AJXP_PluginsService::deferBuildingRegistry(); $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())); if (!method_exists($instance, "initMeta")) { throw new Exception("Meta Source {$plugId} does not implement the initMeta method."); } $instance->initMeta($plugInstance); } catch (Exception $e) { AJXP_Logger::error(__CLASS__, 'Meta plugin', 'Cannot instanciate Meta plugin, reason : ' . $e->getMessage()); $this->errors[] = $e->getMessage(); } $pServ->setPluginActive($split[0], $split[1]); } } AJXP_PluginsService::flushDeferredRegistryBuilding(); if (count($this->errors) > 0) { $e = new AJXP_Exception("Error while loading repository feature : " . implode(",", $this->errors)); if (!$rest) { // Remove repositories from the lists $this->removeRepositoryFromCache($repository->getId()); if (isset($_SESSION["PREVIOUS_REPO_ID"]) && $_SESSION["PREVIOUS_REPO_ID"] != $repository->getId()) { $this->switchRootDir($_SESSION["PREVIOUS_REPO_ID"]); } else { $this->switchRootDir(); } } throw $e; } if ($rest) { $ctxId = $this->getContextRepositoryId(); if ((!empty($ctxId) || $ctxId === 0) && $ctxId == $repository->getId()) { $this->configs["REPOSITORY"] = $repository; $this->cacheRepository($ctxId, $repository); } } else { $this->configs["ACCESS_DRIVER"] = $plugInstance; } return $plugInstance; }
public function client($params, $purl) { //var_dump($params); static $regexp = array('^added interface ip=(.*) bcast=(.*) nmask=(.*)$' => 'skip', 'Anonymous login successful' => 'skip', '^Domain=\\[(.*)\\] OS=\\[(.*)\\] Server=\\[(.*)\\]$' => 'skip', '^\\tSharename[ ]+Type[ ]+Comment$' => 'shares', '^\\t---------[ ]+----[ ]+-------$' => 'skip', '^\\tServer [ ]+Comment$' => 'servers', '^\\t---------[ ]+-------$' => 'skip', '^\\tWorkgroup[ ]+Master$' => 'workg', '^\\t(.*)[ ]+(Disk|IPC)[ ]+IPC.*$' => 'skip', '^\\tIPC\\\\$(.*)[ ]+IPC' => 'skip', '^\\t(.*)[ ]+(Disk)[ ]+(.*)$' => 'share', '^\\t(.*)[ ]+(Printer)[ ]+(.*)$' => 'skip', '([0-9]+) blocks of size ([0-9]+)\\. ([0-9]+) blocks available' => 'skip', 'Got a positive name query response from ' => 'skip', '^(session setup failed): (.*)$' => 'error', '^(.*): ERRSRV - ERRbadpw' => 'error', '^Error returning browse list: (.*)$' => 'error', '^tree connect failed: (.*)$' => 'error', '^(Connection to .* failed)$' => 'error', '^NT_STATUS_(.*) ' => 'error', '^NT_STATUS_(.*)\\$' => 'error', 'ERRDOS - ERRbadpath \\((.*).\\)' => 'error', 'cd (.*): (.*)$' => 'error', '^cd (.*): NT_STATUS_(.*)' => 'error', '^\\t(.*)$' => 'srvorwg', '^([0-9]+)[ ]+([0-9]+)[ ]+(.*)$' => 'skip', '^Job ([0-9]+) cancelled' => 'skip', '^[ ]+(.*)[ ]+([0-9]+)[ ]+(Mon|Tue|Wed|Thu|Fri|Sat|Sun)[ ](Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[ ]+([0-9]+)[ ]+([0-9]{2}:[0-9]{2}:[0-9]{2})[ ]([0-9]{4})$' => 'files', '^message start: ERRSRV - (ERRmsgoff)' => 'error'); if (SMB4PHP_AUTHMODE == 'env') { putenv("USER={$purl['user']}%{$purl['pass']}"); $auth = ''; } else { //$purl['pass'] = preg_replace('/@/', '\@', $purl['pass']); $auth = $purl['user'] != '' ? ' -U ' . escapeshellarg($purl['user'] . '__SEP__' . $purl['pass']) : ''; $auth = str_replace("__SEP__", "%", $auth); //self::debug($auth); } if ($purl['domain'] != '') { $auth .= ' -W ' . escapeshellarg($purl['domain']); } $port = $purl['port'] != 139 ? ' -p ' . escapeshellarg($purl['port']) : ''; $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"); //$output = popen (SMB4PHP_SMBCLIENT." -N {$options} {$port} {$options} {$params} 2>/dev/null {$auth}", 'r'); $info = array(); if (PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows") { $params = ConvSmbParameterToWinOs($params); } $cmd = SMB4PHP_SMBCLIENT . " -N {$options} {$port} {$options} {$params} {$auth}"; $descriptorspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "rw")); $env = null; if (defined('AJXP_LOCALE') && stripos(PHP_OS, "win") === false) { $env = array("LC_ALL" => AJXP_LOCALE); } $process = proc_open($cmd, $descriptorspec, $pipes, null, $env); if (is_resource($process)) { fclose($pipes[0]); $error = stream_get_contents($pipes[2]); fclose($pipes[2]); if ($error != "") { $error = strtolower($error); // common error if (strstr($error, "command not found") !== false) { fclose($pipes[1]); throw new Exception($error); } else { if (strstr($error, "domain") !== false && strstr($error, "os") !== false) { self::debug("Smbclient alternate stream : " . $error); } else { AJXP_Logger::error(__CLASS__, "Smbclient error", $error); } } } $output = $pipes[1]; } if (isset($output) && is_resource($output)) { while ($line = fgets($output, 4096)) { if (PHP_OS == "WIN32" || PHP_OS == "WINNT" || PHP_OS == "Windows") { $line = SystemTextEncoding::fromUTF8($line); } list($tag, $regs, $i) = array('skip', array(), array()); reset($regexp); foreach ($regexp as $r => $t) { if (preg_match('/' . $r . '/', $line, $regs)) { $tag = $t; break; } } switch ($tag) { case 'skip': continue; case 'shares': $mode = 'shares'; break; case 'servers': $mode = 'servers'; break; case 'workg': $mode = 'workgroups'; break; case 'share': list($name, $type) = array(trim(substr($line, 1, 15)), trim(strtolower(substr($line, 17, 10)))); $i = $type != 'disk' && preg_match('/^(.*) Disk/', $line, $regs) ? array(trim($regs[1]), 'disk') : array($name, 'disk'); break; case 'srvorwg': list($name, $master) = array(strtolower(trim(substr($line, 1, 21))), strtolower(trim(substr($line, 22)))); $i = $mode == 'servers' ? array($name, "server") : array($name, "workgroup", $master); break; case 'files': list($attr, $name) = preg_match("/^(.*)[ ]+([D|A|H|S|R]+)\$/", trim($regs[1]), $regs2) ? array(trim($regs2[2]), trim($regs2[1])) : array('', trim($regs[1])); list($his, $im) = array(explode(':', $regs[6]), 1 + strpos("JanFebMarAprMayJunJulAugSepOctNovDec", $regs[4]) / 3); $i = $name != '.' && $name != '..' ? array($name, strpos($attr, 'D') === FALSE ? 'file' : 'folder', 'attr' => $attr, 'size' => intval($regs[2]), 'time' => mktime($his[0], $his[1], $his[2], $im, $regs[5], $regs[7])) : array(); break; case 'error': if (strstr($regs[1], "NO_SUCH_FILE") == 0) { return "NOT_FOUND"; } trigger_error($regs[1], E_USER_ERROR); } if ($i) { switch ($i[1]) { case 'file': case 'folder': $info['info'][$i[0]] = $i; case 'disk': case 'server': case 'workgroup': $info[$i[1]][] = $i[0]; } } } //pclose($output); fclose($output); } //self::debug(print_r($info, true)); return $info; //return; }
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::error(__CLASS__, __FUNCTION__, array("context" => "Applying hook " . get_class($callback[0]) . "::" . $callback[1], "message" => $e->getMessage())); } } }
/** * @inheritdoc */ public function rename($from, $to) { $fromUrl = parse_url($from); $repoId = $fromUrl["host"]; $repoObject = ConfService::getRepositoryById($repoId); $isViPR = $repoObject->getOption("IS_VIPR"); $isDir = false; if ($isViPR === true) { if (is_dir($from . "/")) { $from .= '/'; $to .= '/'; $isDir = true; } } if ($isDir === true || is_dir($from)) { AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Renaming dir {$from} to {$to}"); require_once "aws-v2.phar"; $fromUrl = parse_url($from); $repoId = $fromUrl["host"]; $repoObject = ConfService::getRepositoryById($repoId); if (!isset($repoObject)) { $e = new Exception("Cannot find repository with id " . $repoId); self::$lastException = $e; throw $e; } $s3Client = self::getClientForRepository($repoObject, false); $bucket = $repoObject->getOption("CONTAINER"); $basePath = $repoObject->getOption("PATH"); $fromKeyname = trim(str_replace("//", "/", $basePath . parse_url($from, PHP_URL_PATH)), '/'); $toKeyname = trim(str_replace("//", "/", $basePath . parse_url($to, PHP_URL_PATH)), '/'); if ($isViPR) { $toKeyname .= '/'; $parts = explode('/', $bucket); $bucket = $parts[0]; if (isset($parts[1])) { $fromKeyname = $parts[1] . "/" . $fromKeyname; } } // Perform a batch of CopyObject operations. $batch = array(); $failed = array(); $iterator = $s3Client->getIterator('ListObjects', array('Bucket' => $bucket, 'Prefix' => $fromKeyname . "/")); $toDelete = array(); AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Got iterator looking for prefix " . $fromKeyname . "/ , and toKeyName=" . $toKeyname); foreach ($iterator as $object) { $currentFrom = $object['Key']; $currentTo = $toKeyname . substr($currentFrom, strlen($fromKeyname)); if ($isViPR) { if (isset($parts[1])) { $currentTo = $parts[1] . "/" . $currentTo; } } AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Should move one object " . $currentFrom . " to new key :" . $currentTo); $batch[] = $s3Client->getCommand('CopyObject', array('Bucket' => $bucket, 'Key' => "{$currentTo}", 'CopySource' => "{$bucket}/" . rawurlencode($currentFrom))); $toDelete[] = $currentFrom; } AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Execute batch on " . count($batch) . " objects"); ConfService::getConfStorageImpl()->_loadPluginConfig("access.s3", $globalOptions); $sdkVersion = $globalOptions["SDK_VERSION"]; if ($sdkVersion === "v3") { foreach ($batch as $command) { $successful = $s3Client->execute($command); } //We must delete the "/" in $fromKeyname because we want to delete the folder $clear = \Aws\S3\BatchDelete::fromIterator($s3Client, $bucket, $s3Client->getIterator('ListObjects', array('Bucket' => $bucket, 'Prefix' => $fromKeyname))); $clear->delete(); } else { try { $successful = $s3Client->execute($batch); $clear = new \Aws\S3\Model\ClearBucket($s3Client, $bucket); $iterator->rewind(); $clear->setIterator($iterator); $clear->clear(); $failed = array(); } catch (\Guzzle\Service\Exception\CommandTransferException $e) { $successful = $e->getSuccessfulCommands(); $failed = $e->getFailedCommands(); } } if (count($failed)) { foreach ($failed as $c) { // $c is a Aws\S3\Command\S3Command AJXP_Logger::error("S3Wrapper", __FUNCTION__, "Error while copying: " . $c->getOperation()->getServiceDescription()); } self::$lastException = new Exception("Failed moving folder: " . count($failed)); return false; } return true; } else { AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Execute standard rename on " . $from . " to " . $to); return parent::rename($from, $to); } }
/** * 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 */ public static function catchError($code, $message, $fichier, $ligne, $context) { if (error_reporting() == 0) { return; } AJXP_Logger::error(basename($fichier), "error l.{$ligne}", array("message" => $message)); if (ConfService::getConf("SERVER_DEBUG")) { $stack = debug_backtrace(); $stackLen = count($stack); for ($i = 1; $i < $stackLen; $i++) { $entry = $stack[$i]; $func = $entry['function'] . '('; $argsLen = count($entry['args']); for ($j = 0; $j < $argsLen; $j++) { $s = $entry['args'][$j]; if (is_string($s)) { $func .= $s; } else { if (is_object($s)) { $func .= get_class($s); } } if ($j < $argsLen - 1) { $func .= ', '; } } $func .= ')'; $message .= "\n" . str_replace(dirname(__FILE__), '', $entry['file']) . ':' . $entry['line'] . ' - ' . $func . PHP_EOL; } } if (!headers_sent()) { AJXP_XMLWriter::header(); } if (!empty($context) && is_object($context) && is_a($context, "AJXP_PromptException")) { AJXP_XMLWriter::write("<prompt type=\"" . $context->getPromptType() . "\"><message>" . $message . "</message><data><![CDATA[" . json_encode($context->getPromptData()) . "]]></data></prompt>", true); } else { AJXP_XMLWriter::sendMessage(null, SystemTextEncoding::toUTF8($message), true); } AJXP_XMLWriter::close(); exit(1); }
/** * 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, $repository); } catch (Exception $e) { AJXP_Logger::error(__CLASS__, 'Meta plugin', '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; } AJXP_PluginsService::deferBuildingRegistry(); $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())); if (!method_exists($instance, "initMeta")) { throw new Exception("Meta Source {$plugId} does not implement the initMeta method."); } $instance->initMeta($plugInstance); } catch (Exception $e) { AJXP_Logger::error(__CLASS__, 'Meta plugin', 'Cannot instanciate Meta plugin, reason : ' . $e->getMessage()); $this->errors[] = $e->getMessage(); } $pServ->setPluginActive($split[0], $split[1]); } } AJXP_PluginsService::flushDeferredRegistryBuilding(); 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; if (is_array($this->configs["REPOSITORIES"])) { $this->configs["REPOSITORIES"][$_SESSION['REPO_ID']] = $repository; } } return $plugInstance; }
/** * 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 array $options * @param array $context * @return unknown */ public function stream_open($path, $mode, $options, &$context) { try { $this->realPath = $this->initPath($path); } catch (Exception $e) { AJXP_Logger::error(__CLASS__, "stream_open", "Error while opening stream {$path}"); return false; } $this->fp = fopen($this->realPath, $mode, $options); return $this->fp !== false; }
public function start($baseUri = "/") { $this->uniqueBaseFile = $this->pointToBaseFile(); $this->setBaseUri($baseUri); $authBackend = new AuthSharingBackend($this->rootCollection); $authPlugin = new Sabre\DAV\Auth\Plugin($authBackend, \ConfService::getCoreConf("WEBDAV_DIGESTREALM")); $this->addPlugin($authPlugin); if (!is_dir(AJXP_DATA_PATH . "/plugins/server.sabredav")) { mkdir(AJXP_DATA_PATH . "/plugins/server.sabredav", 0755); $fp = fopen(AJXP_DATA_PATH . "/plugins/server.sabredav/locks", "w"); fwrite($fp, ""); fclose($fp); } $lockBackend = new Sabre\DAV\Locks\Backend\File(AJXP_DATA_PATH . "/plugins/server.sabredav/locks"); $lockPlugin = new Sabre\DAV\Locks\Plugin($lockBackend); $this->addPlugin($lockPlugin); if (\ConfService::getCoreConf("WEBDAV_BROWSER_LISTING")) { $browerPlugin = new \AJXP_Sabre_BrowserPlugin(isset($repository) ? $repository->getDisplay() : null); $extPlugin = new Sabre\DAV\Browser\GuessContentType(); $this->addPlugin($browerPlugin); $this->addPlugin($extPlugin); } try { $this->exec(); } catch (\Exception $e) { \AJXP_Logger::error(__CLASS__, "Exception", $e->getMessage()); } }
/** * Initialise the cache driver based on config * * @param array $options array of options specific to the cache driver. * @access public * @return null */ public function init($options) { parent::init($options); $driverOptions = $this->getFilteredOption("DRIVER"); if (!is_array($driverOptions) || !isset($driverOptions['driver'])) { return; } switch ($driverOptions['driver']) { case "apc": if (!APC_EXTENSION_LOADED) { AJXP_Logger::error(__CLASS__, "init", "The APC extension package must be installed!"); return; } break; case "memcache": if (!MEMCACHE_EXTENSION_LOADED) { AJXP_Logger::error(__CLASS__, "init", "The Memcache extension package must be installed!"); return; } break; case "memcached": if (!MEMCACHED_EXTENSION_LOADED) { AJXP_Logger::error(__CLASS__, "init", "The Memcached extension package must be installed!"); return; } break; case "redis": if (!REDIS_EXTENSION_LOADED) { AJXP_Logger::error(__CLASS__, "init", "The Redis extension package must be installed!"); return; } break; case "xcache": if (!XCACHE_EXTENSION_LOADED) { AJXP_Logger::error(__CLASS__, "init", "The XCache extension package must be installed!"); return; } break; default: break; } }
/** * @param AJXP_Node $oldNode * @param AJXP_Node $newNode * @param bool $copy */ public function updateNodesIndex($oldNode = null, $newNode = null, $copy = false) { require_once AJXP_BIN_FOLDER . "/dibi.compact.php"; try { if ($newNode == null) { $repoId = $this->computeIdentifier($oldNode->getRepository()); // DELETE dibi::query("DELETE FROM [ajxp_index] WHERE [node_path] LIKE %like~ AND [repository_identifier] = %s", $oldNode->getPath(), $repoId); } else { if ($oldNode == null) { // CREATE $stat = stat($newNode->getUrl()); $res = dibi::query("INSERT INTO [ajxp_index]", array("node_path" => $newNode->getPath(), "bytesize" => $stat["size"], "mtime" => $stat["mtime"], "md5" => $newNode->isLeaf() ? md5_file($newNode->getUrl()) : "directory", "repository_identifier" => $repoId = $this->computeIdentifier($newNode->getRepository()))); } else { $repoId = $this->computeIdentifier($oldNode->getRepository()); if ($oldNode->getPath() == $newNode->getPath()) { // CONTENT CHANGE clearstatcache(); $stat = stat($newNode->getUrl()); $this->logDebug("Content changed", "current stat size is : " . $stat["size"]); dibi::query("UPDATE [ajxp_index] SET ", array("bytesize" => $stat["size"], "mtime" => $stat["mtime"], "md5" => md5_file($newNode->getUrl())), "WHERE [node_path] = %s AND [repository_identifier] = %s", $oldNode->getPath(), $repoId); } else { // PATH CHANGE ONLY $newNode->loadNodeInfo(); if ($newNode->isLeaf()) { dibi::query("UPDATE [ajxp_index] SET ", array("node_path" => $newNode->getPath()), "WHERE [node_path] = %s AND [repository_identifier] = %s", $oldNode->getPath(), $repoId); } else { dibi::query("UPDATE [ajxp_index] SET [node_path]=REPLACE( REPLACE(CONCAT('\$\$\$',[node_path]), CONCAT('\$\$\$', %s), CONCAT('\$\$\$', %s)) , '\$\$\$', '') ", $oldNode->getPath(), $newNode->getPath(), "WHERE [node_path] LIKE %like~ AND [repository_identifier] = %s", $oldNode->getPath(), $repoId); } } } } } catch (Exception $e) { AJXP_Logger::error("[meta.syncable]", "Indexation", $e->getMessage()); } }
/** * 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; } AJXP_Logger::error(basename($fichier), "error l.{$ligne}", array("message" => $message)); $loggedUser = AuthService::getLoggedUser(); if (ConfService::getConf("SERVER_DEBUG")) { $stack = debug_backtrace(); $stackLen = count($stack); for ($i = 1; $i < $stackLen; $i++) { $entry = $stack[$i]; $func = $entry['function'] . '('; $argsLen = count($entry['args']); for ($j = 0; $j < $argsLen; $j++) { $s = $entry['args'][$j]; if (is_string($s)) { $func .= $s; } else { if (is_object($s)) { $func .= get_class($s); } } if ($j < $argsLen - 1) { $func .= ', '; } } $func .= ')'; $message .= "\n" . str_replace(dirname(__FILE__), '', $entry['file']) . ':' . $entry['line'] . ' - ' . $func . PHP_EOL; } } if (!headers_sent()) { AJXP_XMLWriter::header(); } AJXP_XMLWriter::sendMessage(null, SystemTextEncoding::toUTF8($message), true); AJXP_XMLWriter::close(); exit(1); }
function tryToLogUser(&$httpVars, $isLast = false) { if (isset($_SESSION["CURRENT_MINISITE"])) { return false; } $this->loadConfig(); if (isset($_SESSION['AUTHENTICATE_BY_CAS'])) { $flag = $_SESSION['AUTHENTICATE_BY_CAS']; } else { $flag = 0; } $pgtIou = !empty($httpVars['pgtIou']); $logged = isset($_SESSION['LOGGED_IN_BY_CAS']); $enre = !empty($httpVars['put_action_enable_redirect']); $ticket = !empty($httpVars['ticket']); $pgt = !empty($_SESSION['phpCAS']['pgt']); $clientModeTicketPendding = isset($_SESSION['AUTHENTICATE_BY_CAS_CLIENT_MOD_TICKET_PENDDING']); if ($this->cas_modify_login_page) { if ($flag == 0 && $enre && !$logged && !$pgtIou) { $_SESSION['AUTHENTICATE_BY_CAS'] = 1; } elseif ($flag == 1 && !$enre && !$logged && !$pgtIou && !$ticket && !$pgt) { $_SESSION['AUTHENTICATE_BY_CAS'] = 0; } elseif ($flag == 1 && $enre && !$logged && !$pgtIou) { $_SESSION['AUTHENTICATE_BY_CAS'] = 1; } elseif ($pgtIou || $pgt) { $_SESSION['AUTHENTICATE_BY_CAS'] = 1; } elseif ($ticket) { $_SESSION['AUTHENTICATE_BY_CAS'] = 1; $_SESSION['AUTHENTICATE_BY_CAS_CLIENT_MOD_TICKET_PENDDING'] = 1; } elseif ($logged && $pgtIou) { $_SESSION['AUTHENTICATE_BY_CAS'] = 2; } else { $_SESSION['AUTHENTICATE_BY_CAS'] = 0; } if ($_SESSION['AUTHENTICATE_BY_CAS'] < 1) { if ($clientModeTicketPendding) { unset($_SESSION['AUTHENTICATE_BY_CAS_CLIENT_MOD_TICKET_PENDDING']); } else { return false; } } } /** * Depend on phpCAS mode configuration */ switch ($this->cas_mode) { case PHPCAS_MODE_CLIENT: if ($this->checkConfigurationForClientMode()) { AJXP_Logger::info(__FUNCTION__, "Start phpCAS mode Client: ", "sucessfully"); phpCAS::client(CAS_VERSION_2_0, $this->cas_server, $this->cas_port, $this->cas_uri, false); if (!empty($this->cas_certificate_path)) { phpCAS::setCasServerCACert($this->cas_certificate_path); } else { phpCAS::setNoCasServerValidation(); } /** * Debug */ if ($this->cas_debug_mode) { // logfile name by date: $today = getdate(); $file_path = AJXP_DATA_PATH . '/logs/phpcas_' . $today['year'] . '-' . $today['month'] . '-' . $today['mday'] . '.txt'; empty($this->cas_debug_file) ? $file_path : ($file_path = $this->cas_debug_file); phpCAS::setDebug($file_path); } phpCAS::forceAuthentication(); } else { AJXP_Logger::error(__FUNCTION__, "Could not start phpCAS mode CLIENT, please verify the configuration", ""); return false; } break; case PHPCAS_MODE_PROXY: /** * If in login page, user click on login via CAS, the page will be reload with manuallyredirectocas is set. * Or force redirect to cas login page even the force redirect is set in configuration of this module * */ if ($this->checkConfigurationForProxyMode()) { AJXP_Logger::info(__FUNCTION__, "Start phpCAS mode Proxy: ", "sucessfully"); /** * init phpCAS in mode proxy */ phpCAS::proxy(CAS_VERSION_2_0, $this->cas_server, $this->cas_port, $this->cas_uri, false); if (!empty($this->cas_certificate_path)) { phpCAS::setCasServerCACert($this->cas_certificate_path); } else { phpCAS::setNoCasServerValidation(); } /** * Debug */ if ($this->cas_debug_mode) { // logfile name by date: $today = getdate(); $file_path = AJXP_DATA_PATH . '/logs/phpcas_' . $today['year'] . '-' . $today['month'] . '-' . $today['mday'] . '.txt'; empty($this->cas_debug_file) ? $file_path : ($file_path = $this->cas_debug_file); phpCAS::setDebug($file_path); } if (!empty($this->cas_setFixedCallbackURL)) { phpCAS::setFixedCallbackURL($this->cas_setFixedCallbackURL); } // /** * PTG storage */ $this->setPTGStorage(); phpCAS::forceAuthentication(); /** * Get proxy ticket (PT) for SAMBA to authentication at CAS via pam_cas * In fact, we can use any other service. Of course, it should be enabled in CAS * */ $err_code = null; $serviceURL = $this->cas_proxied_service; AJXP_Logger::debug(__FUNCTION__, "Try to get proxy ticket for service: ", $serviceURL); $res = phpCAS::serviceSMB($serviceURL, $err_code); if (!empty($res)) { $_SESSION['PROXYTICKET'] = $res; AJXP_Logger::info(__FUNCTION__, "Get Proxy ticket successfully ", ""); } else { AJXP_Logger::info(__FUNCTION__, "Could not get Proxy ticket. ", ""); } break; } else { AJXP_Logger::error(__FUNCTION__, "Could not start phpCAS mode PROXY, please verify the configuration", ""); return false; } default: return false; break; } AJXP_Logger::debug(__FUNCTION__, "Call phpCAS::getUser() after forceAuthentication ", ""); $cas_user = phpCAS::getUser(); if (!AuthService::userExists($cas_user) && $this->is_AutoCreateUser) { AuthService::createUser($cas_user, openssl_random_pseudo_bytes(20)); } if (AuthService::userExists($cas_user)) { $res = AuthService::logUser($cas_user, "", true); if ($res > 0) { AJXP_Safe::storeCredentials($cas_user, $_SESSION['PROXYTICKET']); $_SESSION['LOGGED_IN_BY_CAS'] = true; if (!empty($this->cas_additional_role)) { $userObj = ConfService::getConfStorageImpl()->createUserObject($cas_user); $roles = $userObj->getRoles(); $cas_RoleID = $this->cas_additional_role; $userObj->addRole(AuthService::getRole($cas_RoleID, true)); AuthService::updateUser($userObj); } return true; } } return false; }
/** * Opens the strem * * @param String $path Maybe in the form "ajxp.fs://repositoryId/pathToFile" * @param String $mode * @param string $options * @param resource $context * @return bool */ public function stream_open($path, $mode, $options, &$context) { try { $this->realPath = AJXP_Utils::securePath(self::initPath($path, "file")); } catch (Exception $e) { AJXP_Logger::error(__CLASS__, "stream_open", "Error while opening stream {$path} (" . $e->getMessage() . ")"); 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 rename($from, $to) { $fromUrl = parse_url($from); $repoId = $fromUrl["host"]; $repoObject = ConfService::getRepositoryById($repoId); $isViPR = $repoObject->getOption("IS_VIPR"); $isDir = false; if ($isViPR === true) { if (is_dir($from . "/")) { $from .= '/'; $to .= '/'; $isDir = true; } } if ($isDir === true || is_dir($from)) { AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Renaming dir {$from} to {$to}"); require_once "aws.phar"; $fromUrl = parse_url($from); $repoId = $fromUrl["host"]; $repoObject = ConfService::getRepositoryById($repoId); if (!isset($repoObject)) { $e = new Exception("Cannot find repository with id " . $repoId); self::$lastException = $e; throw $e; } // Get a client $options = array('key' => $repoObject->getOption("API_KEY"), 'secret' => $repoObject->getOption("SECRET_KEY")); $baseURL = $repoObject->getOption("STORAGE_URL"); if (!empty($baseURL)) { $options["base_url"] = $baseURL; } else { $options["region"] = $repoObject->getOption("REGION"); } $proxy = $repoObject->getOption("PROXY"); if (!empty($proxy)) { $options['request.options'] = array('proxy' => $proxy); } $s3Client = S3Client::factory($options); $bucket = $repoObject->getOption("CONTAINER"); $basePath = $repoObject->getOption("PATH"); $fromKeyname = trim(str_replace("//", "/", $basePath . parse_url($from, PHP_URL_PATH)), '/'); $toKeyname = trim(str_replace("//", "/", $basePath . parse_url($to, PHP_URL_PATH)), '/'); if ($isViPR) { $toKeyname .= '/'; $parts = explode('/', $bucket); $bucket = $parts[0]; if (isset($parts[1])) { $fromKeyname = $parts[1] . "/" . $fromKeyname; } } // Perform a batch of CopyObject operations. $batch = array(); $iterator = $s3Client->getIterator('ListObjects', array('Bucket' => $bucket, 'Prefix' => $fromKeyname . "/")); $toDelete = array(); AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Got iterator looking for prefix " . $fromKeyname . "/ , and toKeyName=" . $toKeyname); foreach ($iterator as $object) { $currentFrom = $object['Key']; $currentTo = $toKeyname . substr($currentFrom, strlen($fromKeyname)); if ($isViPR) { if (isset($parts[1])) { $currentTo = $parts[1] . "/" . $currentTo; } } AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Should move one object " . $currentFrom . " to new key :" . $currentTo); $batch[] = $s3Client->getCommand('CopyObject', array('Bucket' => $bucket, 'Key' => "{$currentTo}", 'CopySource' => "{$bucket}/" . rawurlencode($currentFrom))); $toDelete[] = $currentFrom; } try { AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Execute batch on " . count($batch) . " objects"); $successful = $s3Client->execute($batch); $failed = array(); $iterator->rewind(); $clear = new \Aws\S3\Model\ClearBucket($s3Client, $bucket); $clear->setIterator($iterator); $clear->clear(); } catch (\Guzzle\Service\Exception\CommandTransferException $e) { $successful = $e->getSuccessfulCommands(); $failed = $e->getFailedCommands(); } if (count($failed)) { foreach ($failed as $c) { // $c is a Aws\S3\Command\S3Command AJXP_Logger::error("S3Wrapper", __FUNCTION__, "Error while copying: " . $c->getOperation()->getServiceDescription()); } self::$lastException = new Exception("Failed moving folder: " . count($failed)); return false; } return true; } else { AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Execute standard rename on " . $from . " to " . $to); return parent::rename($from, $to); } }
$rootDir = new AJXP_Sabre_RootCollection("root"); $server = new Sabre\DAV\Server($rootDir); $server->setBaseUri($baseURI); } if ((AJXP_Sabre_AuthBackendBasic::detectBasicHeader() || ConfService::getCoreConf("WEBDAV_FORCE_BASIC")) && ConfService::getAuthDriverImpl()->getOption("TRANSMIT_CLEAR_PASS")) { $authBackend = new AJXP_Sabre_AuthBackendBasic($rId); } else { $authBackend = new AJXP_Sabre_AuthBackendDigest($rId); } $authPlugin = new Sabre\DAV\Auth\Plugin($authBackend, ConfService::getCoreConf("WEBDAV_DIGESTREALM")); $server->addPlugin($authPlugin); if (!is_dir(AJXP_DATA_PATH . "/plugins/server.sabredav")) { mkdir(AJXP_DATA_PATH . "/plugins/server.sabredav", 0755); $fp = fopen(AJXP_DATA_PATH . "/plugins/server.sabredav/locks", "w"); fwrite($fp, ""); fclose($fp); } $lockBackend = new Sabre\DAV\Locks\Backend\File(AJXP_DATA_PATH . "/plugins/server.sabredav/locks"); $lockPlugin = new Sabre\DAV\Locks\Plugin($lockBackend); $server->addPlugin($lockPlugin); if (ConfService::getCoreConf("WEBDAV_BROWSER_LISTING")) { $browerPlugin = new AJXP_Sabre_BrowserPlugin(isset($repository) ? $repository->getDisplay() : null); $extPlugin = new Sabre\DAV\Browser\GuessContentType(); $server->addPlugin($browerPlugin); $server->addPlugin($extPlugin); } try { $server->exec(); } catch (Exception $e) { AJXP_Logger::error(__CLASS__, "Exception", $e->getMessage()); }
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(); $index = 0; while (count($this->callbacks)) { $arguments = array_shift($this->callbacks); $callback = array_shift($arguments); try { call_user_func_array($callback, $arguments); } catch (\Exception $e) { AJXP_Logger::error(__CLASS__, __FUNCTION__, array("context" => "Applying hook " . get_class($callback[0]) . "::" . $callback[1], "message" => $e->getMessage())); } $index++; if ($index > 200) { AJXP_Logger::error(__CLASS__, __FUNCTION__, "Breaking ShutdownScheduler loop, seems too big (200)"); break; } } }
/** * 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, "file"); } catch (Exception $e) { AJXP_Logger::error(__CLASS__, "stream_open", "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(__CLASS__,__FUNCTION__,"I opened an smb stream."); return $this->fp !== false; } }
/** * Call the preLogUser() functino on the auth driver implementation * @static * @param Array $httpVars * @return void */ public static function preLogUser($httpVars) { if (self::getLoggedUser() != null && self::getLoggedUser()->getId() != "guest") { return; } $frontends = AJXP_PluginsService::getInstance()->getActivePluginsForType("authfront"); $index = 0; /** * @var AbstractAuthFrontend $frontendPlugin */ foreach ($frontends as $frontendPlugin) { if (!$frontendPlugin->isEnabled()) { continue; } if (!method_exists($frontendPlugin, "tryToLogUser")) { AJXP_Logger::error(__CLASS__, __FUNCTION__, "Trying to use an authfront plugin without tryToLogUser method. Wrongly initialized?"); continue; } $res = $frontendPlugin->tryToLogUser($httpVars, $index == count($frontends) - 1); $index++; if ($res) { break; } } // Keep old-fashioned test, should be removed $authDriver = ConfService::getAuthDriverImpl(); $authDriver->preLogUser(isset($httpVars["remote_session"]) ? $httpVars["remote_session"] : ""); return; }
/** * @param AJXP_Node $oldNode * @param AJXP_Node $newNode * @param bool $copy */ public function updateNodesIndex($oldNode = null, $newNode = null, $copy = false) { if (!dibi::isConnected()) { dibi::connect($this->sqlDriver); } //$this->logInfo("Syncable index", array($oldNode == null?'null':$oldNode->getUrl(), $newNode == null?'null':$newNode->getUrl())); try { if ($newNode != null && $this->excludeNode($newNode)) { // CREATE if ($oldNode == null) { AJXP_Logger::debug("Ignoring " . $newNode->getUrl() . " for indexation"); return; } else { AJXP_Logger::debug("Target node is excluded, see it as a deletion: " . $newNode->getUrl()); $newNode = null; } } if ($newNode == null) { $repoId = $this->computeIdentifier($oldNode->getRepository(), $oldNode->getUser()); // DELETE $this->logDebug('DELETE', $oldNode->getUrl()); dibi::query("DELETE FROM [ajxp_index] WHERE [node_path] LIKE %like~ AND [repository_identifier] = %s", SystemTextEncoding::toUTF8($oldNode->getPath()), $repoId); } else { if ($oldNode == null || $copy) { // CREATE $stat = stat($newNode->getUrl()); $newNode->setLeaf(!($stat['mode'] & 040000)); $this->logDebug('INSERT', $newNode->getUrl()); dibi::query("INSERT INTO [ajxp_index]", array("node_path" => SystemTextEncoding::toUTF8($newNode->getPath()), "bytesize" => $stat["size"], "mtime" => $stat["mtime"], "md5" => $newNode->isLeaf() ? md5_file($newNode->getUrl()) : "directory", "repository_identifier" => $repoId = $this->computeIdentifier($newNode->getRepository(), $newNode->getUser()))); } else { $repoId = $this->computeIdentifier($oldNode->getRepository(), $oldNode->getUser()); if ($oldNode->getPath() == $newNode->getPath()) { // CONTENT CHANGE clearstatcache(); $stat = stat($newNode->getUrl()); $this->logDebug("Content changed", "current stat size is : " . $stat["size"]); $this->logDebug('UPDATE CONTENT', $newNode->getUrl()); dibi::query("UPDATE [ajxp_index] SET ", array("bytesize" => $stat["size"], "mtime" => $stat["mtime"], "md5" => md5_file($newNode->getUrl())), "WHERE [node_path] = %s AND [repository_identifier] = %s", SystemTextEncoding::toUTF8($oldNode->getPath()), $repoId); try { $rowCount = dibi::getAffectedRows(); if ($rowCount === 0) { $this->logError(__FUNCTION__, "There was an update event on a non-indexed node (" . $newNode->getPath() . "), creating index entry!"); $this->updateNodesIndex(null, $newNode, false); } } catch (Exception $e) { } } else { // PATH CHANGE ONLY $newNode->loadNodeInfo(); if ($newNode->isLeaf()) { $this->logDebug('UPDATE LEAF PATH', $newNode->getUrl()); dibi::query("UPDATE [ajxp_index] SET ", array("node_path" => SystemTextEncoding::toUTF8($newNode->getPath())), "WHERE [node_path] = %s AND [repository_identifier] = %s", SystemTextEncoding::toUTF8($oldNode->getPath()), $repoId); try { $rowCount = dibi::getAffectedRows(); if ($rowCount === 0) { $this->logError(__FUNCTION__, "There was an update event on a non-indexed node (" . $newNode->getPath() . "), creating index entry!"); $this->updateNodesIndex(null, $newNode, false); } } catch (Exception $e) { } } else { $this->logDebug('UPDATE FOLDER PATH', $newNode->getUrl()); dibi::query("UPDATE [ajxp_index] SET [node_path]=REPLACE( REPLACE(CONCAT('\$\$\$',[node_path]), CONCAT('\$\$\$', %s), CONCAT('\$\$\$', %s)) , '\$\$\$', '') ", $oldNode->getPath(), $newNode->getPath(), "WHERE [node_path] LIKE %like~ AND [repository_identifier] = %s", SystemTextEncoding::toUTF8($oldNode->getPath()), $repoId); try { $rowCount = dibi::getAffectedRows(); if ($rowCount === 0) { $this->logError(__FUNCTION__, "There was an update event on a non-indexed folder (" . $newNode->getPath() . "), relaunching a recursive indexation!"); AJXP_Controller::findActionAndApply("index", array("file" => $newNode->getPath()), array()); } } catch (Exception $e) { } } } } } } catch (Exception $e) { AJXP_Logger::error("[meta.syncable]", "Exception", $e->getTraceAsString()); AJXP_Logger::error("[meta.syncable]", "Indexation", $e->getMessage()); } }
/** * Find all callbacks registered for a given hook and apply them * @static * @param string $hookName * @param array $args * @param bool $forceNonDefer * @return void */ public static function applyHook($hookName, $args, $forceNonDefer = false) { if (isset(self::$hooksCache[$hookName])) { $hooks = self::$hooksCache[$hookName]; foreach ($hooks as $hook) { if (isset($hook["applyCondition"]) && $hook["applyCondition"] != "") { $apply = false; eval($hook["applyCondition"]); if (!$apply) { continue; } } $defer = $hook["defer"]; if ($defer && $forceNonDefer) { $defer = false; } self::applyCallback($hook, $fake1, $fake2, $fake3, $args, $defer); } return; } $xPath = self::initXPath(true); $callbacks = $xPath->query("hooks/serverCallback[@hookName='{$hookName}']"); if (!$callbacks->length) { return; } self::$hooksCache[$hookName] = array(); /** * @var $callback DOMElement */ foreach ($callbacks as $callback) { $defer = $callback->getAttribute("defer") === "true"; $applyCondition = $callback->getAttribute("applyCondition"); $plugId = $callback->getAttribute("pluginId"); $methodName = $callback->getAttribute("methodName"); $dontBreakOnExceptionAtt = $callback->getAttribute("dontBreakOnException"); $dontBreakOnException = !empty($dontBreakOnExceptionAtt) && $dontBreakOnExceptionAtt == "true"; $hookCallback = array("defer" => $defer, "applyCondition" => $applyCondition, "pluginId" => $plugId, "methodName" => $methodName); self::$hooksCache[$hookName][] = $hookCallback; if (!empty($applyCondition)) { $apply = false; eval($applyCondition); if (!$apply) { continue; } } if ($defer && $forceNonDefer) { $defer = false; } if ($dontBreakOnException) { try { self::applyCallback($hookCallback, $fake1, $fake2, $fake3, $args, $defer); } catch (Exception $e) { AJXP_Logger::error("[Hook {$hookName}]", "[Callback " . $plugId . "." . $methodName . "]", $e->getMessage()); } } else { self::applyCallback($hookCallback, $fake1, $fake2, $fake3, $args, $defer); } } }