ktwebdavserver.inc.php

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,547 行 · 第 1/5 页

PHP
1,547
字号
            $info["props"][] = $this->mkprop("isreadonly", '');
            $info["props"][] = $this->mkprop("contentclass", '');
            $info["props"][] = $this->mkprop("getcontentlanguage", '');
            $info["props"][] = $this->mkprop("lastaccessed", '');
            $info["props"][] = $this->mkprop("isstructureddocument", '');
            $info["props"][] = $this->mkprop("defaultdocument", '');
            $info["props"][] = $this->mkprop("isroot", '');

            return $info;
        }


        /**
         * PROPFIND helper for Document Info
         *
         * @param int  Document ID
         * @param string  path
         * @return array   Doc info array
         */
        function _fileinfoForDocumentID($iDocumentID, $path) {

            global $default;

            $this->ktwebdavLog("Entering _fileinfoForDocumentID. DocumentID is " . print_r($iDocumentID, true), 'info', true);

            if ($iDocumentID == '') return false;

            $oDocument =& Document::get($iDocumentID);

            if (is_null($oDocument) || ($oDocument === false) || PEAR::isError($oDocument)) {
                return false;
            }

            return $this->_fileinfoForDocument($oDocument, $path);

        }

        /**
         * PROPFIND helper for Folder Info
         *
         * @param Folder  Folder Object
         * @param string  $path
         * @return array  Folder info array
         */
        function _fileinfoForFolder($oFolder, $path) {

            global $default;

            $this->ktwebdavLog("Entering _fileinfoForFolder. Folder is " . print_r($oFolder, true), 'info', true);

            // Fix for Mac
            // Modified - 25/10/07 - spaces prevent files displaying in finder
            if($this->dav_client == 'MC'){
                $path = str_replace('%2F', '/', urlencode(utf8_encode($path)));
            }
            $path = str_replace('&', '%26', $path);

            // create result array
            $info = array();
            $info["path"] = $path;
            $fspath = $default->documentRoot . "/" . $this->rootFolder . $path;
            //$fspath = $default->documentRoot . '/' . $oFolder->generateFolderPath($oFolder->getID());

            $info["props"] = array();
            // no special beautified displayname here ...
            $info["props"][] = $this->mkprop("displayname", $oFolder->getName());

            // creation and modification time
            //$info["props"][] = $this->mkprop("creationdate", strtotime($oFolder->getCreatedDateTime()));
            //$info["props"][] = $this->mkprop("getlastmodified", strtotime($oFolder->getVersionCreated()));

            // directory (WebDAV collection)
            $info["props"][] = $this->mkprop("resourcetype", "collection");
            $info["props"][] = $this->mkprop("getcontenttype", "httpd/unix-directory");
            $info["props"][] = $this->mkprop("getcontentlength", 0);

            return $info;
        }

        /**
         * PROPFIND method handler
         *
         * @param  void
         * @return void
         */
        function http_PROPFIND()
        {
            $options = Array();
            $options["path"] = $this->path;

            // search depth from header (default is "infinity)
            if (isset($_SERVER['HTTP_DEPTH'])) {
                $options["depth"] = $_SERVER["HTTP_DEPTH"];
            } else {
                $options["depth"] = "infinity";
            }

            // analyze request payload
            $propinfo = new _parse_propfind("php://input");
            if (!$propinfo->success) {
                $this->http_status("400 Error");
                return;
            }
            $options['props'] = $propinfo->props;

            // call user handler
            if (!$this->PROPFIND($options, $files)) {
                $this->http_status("404 Not Found");
                return;
            }

            // collect namespaces here
            $ns_hash = array();

            // Microsoft Clients need this special namespace for date and time values
            $ns_defs = "xmlns:ns0=\"urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/\"";

            // now we loop over all returned file entries
            foreach($files["files"] as $filekey => $file) {

                // nothing to do if no properties were returned for a file
                if (!isset($file["props"]) || !is_array($file["props"])) {
                    continue;
                }

                // now loop over all returned properties
                foreach($file["props"] as $key => $prop) {
                    // as a convenience feature we do not require that user handlers
                    // restrict returned properties to the requested ones
                    // here we strip all unrequested entries out of the response

                    switch($options['props']) {
                        case "all":
                            // nothing to remove
                            break;

                        case "names":
                            // only the names of all existing properties were requested
                            // so we remove all values
                            unset($files["files"][$filekey]["props"][$key]["val"]);
                        break;

                        default:
                        $found = false;

                        // search property name in requested properties
                        foreach((array)$options["props"] as $reqprop) {
                            if (   $reqprop["name"]  == $prop["name"]
                                    && $reqprop["xmlns"] == $prop["ns"]) {
                                $found = true;
                                break;
                            }
                        }

                        // unset property and continue with next one if not found/requested
                        if (!$found) {
                            $files["files"][$filekey]["props"][$key]='';
                            continue(2);
                        }
                        break;
                    }

                    // namespace handling
                    if (empty($prop["ns"])) continue; // no namespace
                    $ns = $prop["ns"];
                    if ($ns == "DAV:") continue; // default namespace
                    if (isset($ns_hash[$ns])) continue; // already known

                    // register namespace
                    $ns_name = "ns".(count($ns_hash) + 1);
                    $ns_hash[$ns] = $ns_name;
                    $ns_defs .= " xmlns:$ns_name=\"$ns\"";
                }

                // we also need to add empty entries for properties that were requested
                // but for which no values where returned by the user handler
                if (is_array($options['props'])) {
                    foreach($options["props"] as $reqprop) {
                        if($reqprop['name']=='') continue; // skip empty entries

                        $found = false;

                        // check if property exists in result
                        foreach($file["props"] as $prop) {
                            if (   $reqprop["name"]  == $prop["name"]
                                    && $reqprop["xmlns"] == $prop["ns"]) {
                                $found = true;
                                break;
                            }
                        }

                        if (!$found) {
                            if($reqprop["xmlns"]==="DAV:" && $reqprop["name"]==="lockdiscovery") {
                                // lockdiscovery is handled by the base class
                                $files["files"][$filekey]["props"][]
                                    = $this->mkprop("DAV:",
                                            "lockdiscovery" ,
                                            $this->lockdiscovery($files["files"][$filekey]['path']));
                            } else {
                                // add empty value for this property
                                $files["files"][$filekey]["noprops"][] = $this->mkprop($reqprop["xmlns"], $reqprop["name"], '');

                                // register property namespace if not known yet
                                if ($reqprop["xmlns"] != "DAV:" && !isset($ns_hash[$reqprop["xmlns"]])) {
                                    $ns_name = "ns".(count($ns_hash) + 1);
                                    $ns_hash[$reqprop["xmlns"]] = $ns_name;
                                    $ns_defs .= " xmlns:$ns_name=\"$reqprop[xmlns]\"";
                                }
                            }
                        }
                    }
                }
            }

            // now we generate the reply header ...
            $this->http_status("207 Multi-Status");
            header('Content-Type: text/xml; charset="utf-8"');

            // ... and payload
            echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
            echo "<D:multistatus xmlns:D=\"DAV:\">\n";

            foreach($files["files"] as $file) {
                // ignore empty or incomplete entries
                if(!is_array($file) || empty($file) || !isset($file["path"])) continue;
                $path = $file['path'];
                if(!is_string($path) || $path==='') continue;

                echo " <D:response $ns_defs>\n";

                $tempHref = $this->_mergePathes($_SERVER['SCRIPT_NAME'], $path);

                // Ensure collections end in a slash
                if(isset($file['props'])){
                    foreach($file['props'] as $v){
                        if($v['name'] == 'resourcetype'){
                            if($v['val'] == 'collection'){
                                $tempHref = $this->_slashify($tempHref);
                                continue;
                            }
                        }
                    }
                }

                $href = htmlspecialchars($tempHref);

                echo "  <D:href>$href</D:href>\n";

                $this->ktwebdavLog("\nfile is: " . print_r($file, true), 'info', true);

                // report all found properties and their values (if any)
                if (isset($file["props"]) && is_array($file["props"])) {
                    echo "   <D:propstat>\n";
                    echo "    <D:prop>\n";

                    foreach($file["props"] as $key => $prop) {

                        if (!is_array($prop)) continue;
                        if (!isset($prop["name"])) continue;

                        $this->ktwebdavLog("Namespace is " . $prop["ns"], 'info', true);

                        if (!isset($prop["val"]) || $prop["val"] === '' || $prop["val"] === false) {
                            // empty properties (cannot use empty() for check as "0" is a legal value here)
                            if($prop["ns"]=="DAV:") {
                                echo "     <D:$prop[name]/>\n";
                            } else if(!empty($prop["ns"])) {
                                echo "     <".$ns_hash[$prop["ns"]].":$prop[name]/>\n";
                            } else {
                                echo "     <$prop[name] xmlns=\"\"/>";
                            }
                        } else if ($prop["ns"] == "DAV:") {
                            $this->ktwebdavLog("Getting DAV: Properties...", 'info', true);
                            // some WebDAV properties need special treatment
                            switch ($prop["name"]) {
                                case "creationdate":
                                    $this->ktwebdavLog("Getting creationdate...", 'info', true);
                                echo "     <D:creationdate ns0:dt=\"dateTime.tz\">"
                                    . gmdate("Y-m-d\\TH:i:s\\Z",$prop['val'])
                                    . "</D:creationdate>\n";
                                break;
                                case "getlastmodified":
                                    $this->ktwebdavLog("Getting getlastmodified...", 'info', true);
                                echo "     <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">"
                                    . gmdate("D, d M Y H:i:s ", $prop['val'])
                                    . "GMT</D:getlastmodified>\n";
                                break;
                                case "resourcetype":
                                    $this->ktwebdavLog("Getting resourcetype...", 'info', true);
                                echo "     <D:resourcetype><D:$prop[val]/></D:resourcetype>\n";
                                break;
                                case "supportedlock":
                                    $this->ktwebdavLog("Getting supportedlock...", 'info', true);
                                echo "     <D:supportedlock>$prop[val]</D:supportedlock>\n";
                                break;
                                case "lockdiscovery":
                                    $this->ktwebdavLog("Getting lockdiscovery...", 'info', true);
                                echo "     <D:lockdiscovery>\n";
                                echo $prop["val"];
                                echo "     </D:lockdiscovery>\n";
                                break;
                                default:
                                $this->ktwebdavLog("Getting default...", 'info', true);
                                $this->ktwebdavLog("name is: " . $prop['name'], 'info', true);
                                $this->ktwebdavLog("val is: " . $this->_prop_encode(htmlspecialchars($prop['val'])), 'info', true);
                                echo "     <D:" . $prop['name'] .">"
                                    . $this->_prop_encode(htmlspecialchars($prop['val']))
                                    .     "</D:" . $prop['name'] . ">\n";
                                break;
                            }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?