diff options
| author | Tristan Zur <tzur@web.web.ccwn.org> | 2014-03-27 22:27:47 +0100 |
|---|---|---|
| committer | Tristan Zur <tzur@web.web.ccwn.org> | 2014-03-27 22:27:47 +0100 |
| commit | b62676ca5d3d6f6ba3f019ea3f99722e165a98d8 (patch) | |
| tree | 86722cb80f07d4569f90088eeaea2fc2f6e2ef94 /js/dojo/dojox/data/demos/stores | |
Diffstat (limited to 'js/dojo/dojox/data/demos/stores')
| -rw-r--r-- | js/dojo/dojox/data/demos/stores/LazyLoadJSIStore.js | 143 | ||||
| -rw-r--r-- | js/dojo/dojox/data/demos/stores/filestore_dojotree.php | 179 | ||||
| -rw-r--r-- | js/dojo/dojox/data/demos/stores/filestore_dojoxdata.php | 179 | ||||
| -rw-r--r-- | js/dojo/dojox/data/demos/stores/filestore_funcs.php | 366 |
4 files changed, 867 insertions, 0 deletions
diff --git a/js/dojo/dojox/data/demos/stores/LazyLoadJSIStore.js b/js/dojo/dojox/data/demos/stores/LazyLoadJSIStore.js new file mode 100644 index 0000000..7a867a4 --- /dev/null +++ b/js/dojo/dojox/data/demos/stores/LazyLoadJSIStore.js @@ -0,0 +1,143 @@ +//>>built +// wrapped by build app +define("dojox/data/demos/stores/LazyLoadJSIStore", ["dijit","dojo","dojox","dojo/require!dojo/data/ItemFileReadStore"], function(dijit,dojo,dojox){ +dojo.provide("dojox.data.demos.stores.LazyLoadJSIStore"); +dojo.require("dojo.data.ItemFileReadStore"); + +dojo.declare("dojox.data.demos.stores.LazyLoadJSIStore", dojo.data.ItemFileReadStore, { + constructor: function(/* object */ keywordParameters){ + // LazyLoadJSIStore extends ItemFileReadStore to implement an + // example of lazy-loading/faulting in items on-demand. + // Note this is certianly not a perfect implementation, it is + // an example. + }, + + isItemLoaded: function(/*object*/ item) { + // summary: + // Overload of the isItemLoaded function to look for items of type 'stub', which indicate + // the data hasn't been loaded in yet. + // + // item: + // The item to examine. + + //For this store, if it has the value of stub for its type attribute, + //then the item basn't been fully loaded yet. It's just a placeholder. + if(this.getValue(item, "type") === "stub"){ + return false; + } + return true; + }, + + loadItem: function(keywordArgs){ + // summary: + // Overload of the loadItem function to fault in items. This assumes the data for an item is laid out + // in a RESTful sort of pattern name0/name1/data.json and so on and uses that to load the data. + // It will also detect stub items in the newly loaded item and insert the stubs into the ItemFileReadStore + // list so they can also be loaded in on-demand. + // + // item: + // The item to examine. + + var item = keywordArgs.item; + this._assertIsItem(item); + + //Build the path to the data.json for this item + //The path consists of where its parent was loaded from + //plus the item name. + var itemName = this.getValue(item, "name"); + var parent = this.getValue(item, "parent"); + var dataUrl = ""; + if (parent){ + dataUrl += (parent + "/"); + } + + //For this store, all child input data is loaded from a url that ends with data.json + dataUrl += itemName + "/data.json"; + + //Need a reference to the store to call back to its structures. + var self = this; + + // Callback for handling a successful load. + var gotData = function(data){ + //Now we need to modify the existing item a bit to take it out of stub state + //Since we extend the store and have knowledge of the internal + //structure, this can be done here. Now, is we extended + //a write store, we could call the write APIs to do this too + //But for a simple demo the diretc modification in the store function + //is sufficient. + + //Clear off the stub indicators. + delete item.type; + delete item.parent; + + //Set up the loaded values in the format ItemFileReadStore uses for attributes. + for (var i in data) { + if (dojo.isArray(data[i])) { + item[i] = data[i]; + }else{ + item[i] = [data[i]]; + } + } + + //Reset the item in the reference. + self._arrayOfAllItems[item[self._itemNumPropName]] = item; + + //Scan the new values in the item for extra stub items we need to + //add to the items array of the store so they can be lazy-loaded later... + var attributes = self.getAttributes(item); + for(i in attributes){ + var values = item[attributes[i]]; + for (var j = 0; j < values.length; j++) { + var value = values[j]; + + if(typeof value === "object"){ + if(value["stub"] ){ + //We have a stub reference here, we need to create the stub item + var stub = { + type: ["stub"], + name: [value["stub"]], // + parent: [itemName] //The child stub item is parented by this item name... + }; + if (parent) { + //Add in any parents to your parent so URL construstruction is accurate. + stub.parent[0] = parent + "/" + stub.parent[0]; + } + //Finalize the addition of the new stub item into the ItemFileReadStore list. + self._arrayOfAllItems.push(stub); + stub[self._storeRefPropName] = self; + stub[self._itemNumPropName] = (self._arrayOfAllItems.length - 1); //Last one pushed in should be the item + values[j] = stub; //Set the stub item back in its place and replace the stub notation. + } + } + } + } + + //Done processing! Call the onItem, if any. + if(keywordArgs.onItem){ + var scope = keywordArgs.scope ? keywordArgs.scope : dojo.global; + keywordArgs.onItem.call(scope, item); + } + }; + + //Callback for any errors that occur during load. + var gotError = function(error){ + //Call the onComplete, if any + if(keywordArgs.onError){ + var scope = keywordArgs.scope ? keywordArgs.scope : dojo.global; + keywordArgs.onError.call(scope, error); + } + }; + + //Fire the get and pass the proper callbacks to the deferred. + var xhrArgs = { + url: dataUrl, + handleAs: "json-comment-optional" + }; + var d = dojo.xhrGet(xhrArgs); + d.addCallback(gotData); + d.addErrback(gotError); + } +}); + + +}); diff --git a/js/dojo/dojox/data/demos/stores/filestore_dojotree.php b/js/dojo/dojox/data/demos/stores/filestore_dojotree.php new file mode 100644 index 0000000..5e19385 --- /dev/null +++ b/js/dojo/dojox/data/demos/stores/filestore_dojotree.php @@ -0,0 +1,179 @@ +<?php + //Define the root directory to use for this service. + //All file lookups are relative to this path. + $rootDir = "../../../.."; + + require_once("filestore_funcs.php"); + + //Extract the query, if any. + $query = false; + if (array_key_exists("query", $_GET)) { + $query = $_GET['query']; + $query = str_replace("\\\"", "\"", $query); + $query = json_decode($query, true); + } + //Extract relevant query options. + $queryOptions = json_decode("{}"); + $deep = false; + $ignoreCase = false; + if (array_key_exists("queryOptions", $_GET)) { + $queryOptions = $_GET['queryOptions']; + $queryOptions = str_replace("\\\"", "\"", $queryOptions); + $queryOptions = json_decode($queryOptions); + if (property_exists($queryOptions, "deep")) { + $deep = $queryOptions->deep; + } + if (property_exists($queryOptions, "ignoreCase")) { + $ignoreCase = $queryOptions->ignoreCase; + } + } + + //Extract non-dojo.data spec config options. + $expand = false; + $dirsOnly = false; + $showHiddenFiles = false; + $options = array(); + if (array_key_exists("options", $_GET)) { + $options = $_GET['options']; + $options = str_replace("\\\"", "\"", $options); + $options = json_decode($options); + if (array_search("expand", $options) > -1) { + $expand = true; + } + if (array_search("dirsOnly", $options) > -1) { + $dirsOnly = true; + } + if (array_search("showHiddenFiles", $options) > -1) { + $showHiddenFiles = true; + } + } + + + //See if a specific file was requested, or if it is just a query for files. + $path = false; + if (array_key_exists("path", $_GET)) { + $path = $_GET['path']; + } + + if (!is_string($path)) { + + $files = array(); + + //Handle query for files. Must try to generate patterns over the query + //attributes. + $patterns = array(); + if (is_array($query)) { + //Generate a series of RegExp patterns as necessary. + $keys = array_keys($query); + $total = count($keys); + if ($total > 0) { + for ($i = 0; $i < $total; $i++) { + $key = $keys[$i]; + $pattern = $query[$key]; + if (is_string($pattern)) { + $patterns[$key] = patternToRegExp($pattern); + } + } + $files = matchFiles($query, $patterns, $ignoreCase, ".", $rootDir, $deep, $dirsOnly, $expand, $showHiddenFiles); + } else { + $files = getAllFiles(".",$rootDir,$deep,$dirsOnly,$expand,$showHiddenFiles); + } + }else{ + $files = getAllFiles(".",$rootDir,$deep,$dirsOnly,$expand,$showHiddenFiles); + } + + $total = count($files); + + //Handle the sorting and paging. + $sortSpec = false; + if (array_key_exists("sort", $_GET)) { + $sortSpec = $_GET['sort']; + $sortSpec = str_replace("\\\"", "\"", $sortSpec); + $sortSpec = json_decode($sortSpec); + } + + if ($sortSpec != null) { + $comparator = createComparator($sortSpec); + usort($files,array($comparator, "compare")); + } + + //Page, if necessary. + if (array_key_exists("start", $_GET)) { + $start = $_GET['start']; + if (!is_numeric($start)) { + $start = 0; + } + $files = array_slice($files, $start); + } + if (array_key_exists("count", $_GET)) { + $count = $_GET['count']; + if (!is_numeric($count)) { + $count = $total; + } + $files = array_slice($files, 0, $count); + } + + $result = new stdClass(); + $result->total = $total; + $result->items = $files; + header("Content-Type", "text/json"); + print("/* ".json_encode($result)." */"); + } else { + //Query of a specific file (useful for fetchByIdentity and loadItem) + + //Make sure the path isn't trying to walk out of the rooted directory + //As defined by $rootDir in the top of the php script. + $rootPath = realPath($rootDir); + $fullPath = realPath($rootPath."/".$path); + + if ($fullPath !== false) { + if (strpos($fullPath,$rootPath) === 0) { + //Root the path into the tree cleaner. + if (strlen($fullPath) == strlen($rootPath)) { + $path = "."; + } else { + //Fix the path to relative of root and put back into UNIX style (even if windows). + $path = substr($fullPath,(strlen($rootPath) + 1),strlen($fullPath)); + $path = str_replace("\\", "/", $path); + } + + if (file_exists($fullPath)) { + $arr = explode("/", $path); + $size = count($arr); + + if ($size > 0) { + $fName = $arr[$size - 1]; + if ($size == 1) { + print("Setting path to: ."); + $path = "."; + } else { + $path = $arr[0]; + } + for ($i = 1; $i < ($size - 1); $i++) { + $path = $path."/".$arr[$i]; + } + $file = generateFileObj($fName, $path, $rootDir, $expand,$showHiddenFiles); + header("Content-Type", "text/json"); + print("/* ".json_encode($file)." */"); + } else { + header("HTTP/1.0 404 Not Found"); + header("Status: 404 Not Found"); + print("<b>Cannot access file: [".htmlentities($path)."]<b>"); + } + } else { + header("HTTP/1.0 404 Not Found"); + header("Status: 404 Not Found"); + print("<b>Cannot access file: [".htmlentities($path)."]<b>"); + } + } else { + header("HTTP/1.0 403 Forbidden"); + header("Status: 403 Forbidden"); + print("<b>Cannot access file: [".htmlentities($path)."]. It is outside of the root of the file service.<b>"); + } + } else { + header("HTTP/1.0 404 Not Found"); + header("Status: 404 Not Found"); + print("<b>Cannot access file: [".htmlentities($path)."]<b>"); + } + } +?> diff --git a/js/dojo/dojox/data/demos/stores/filestore_dojoxdata.php b/js/dojo/dojox/data/demos/stores/filestore_dojoxdata.php new file mode 100644 index 0000000..0360049 --- /dev/null +++ b/js/dojo/dojox/data/demos/stores/filestore_dojoxdata.php @@ -0,0 +1,179 @@ +<?php + //Define the root directory to use for this service. + //All file lookups are relative to this path. + $rootDir = "../.."; + + require_once("filestore_funcs.php"); + + //Extract the query, if any. + $query = false; + if (array_key_exists("query", $_GET)) { + $query = $_GET['query']; + $query = str_replace("\\\"", "\"", $query); + $query = json_decode($query, true); + } + //Extract relevant query options. + $queryOptions = json_decode("{}"); + $deep = false; + $ignoreCase = false; + if (array_key_exists("queryOptions", $_GET)) { + $queryOptions = $_GET['queryOptions']; + $queryOptions = str_replace("\\\"", "\"", $queryOptions); + $queryOptions = json_decode($queryOptions); + if (property_exists($queryOptions, "deep")) { + $deep = $queryOptions->deep; + } + if (property_exists($queryOptions, "ignoreCase")) { + $ignoreCase = $queryOptions->ignoreCase; + } + } + + //Extract non-dojo.data spec config options. + $expand = false; + $dirsOnly = false; + $showHiddenFiles = false; + $options = array(); + if (array_key_exists("options", $_GET)) { + $options = $_GET['options']; + $options = str_replace("\\\"", "\"", $options); + $options = json_decode($options); + if (array_search("expand", $options) > -1) { + $expand = true; + } + if (array_search("dirsOnly", $options) > -1) { + $dirsOnly = true; + } + if (array_search("showHiddenFiles", $options) > -1) { + $showHiddenFiles = true; + } + } + + + //See if a specific file was requested, or if it is just a query for files. + $path = false; + if (array_key_exists("path", $_GET)) { + $path = $_GET['path']; + } + + if (!is_string($path)) { + + $files = array(); + + //Handle query for files. Must try to generate patterns over the query + //attributes. + $patterns = array(); + if (is_array($query)) { + //Generate a series of RegExp patterns as necessary. + $keys = array_keys($query); + $total = count($keys); + if ($total > 0) { + for ($i = 0; $i < $total; $i++) { + $key = $keys[$i]; + $pattern = $query[$key]; + if (is_string($pattern)) { + $patterns[$key] = patternToRegExp($pattern); + } + } + $files = matchFiles($query, $patterns, $ignoreCase, ".", $rootDir, $deep, $dirsOnly, $expand, $showHiddenFiles); + } else { + $files = getAllFiles(".",$rootDir,$deep,$dirsOnly,$expand,$showHiddenFiles); + } + }else{ + $files = getAllFiles(".",$rootDir,$deep,$dirsOnly,$expand,$showHiddenFiles); + } + + $total = count($files); + + //Handle the sorting and paging. + $sortSpec = false; + if (array_key_exists("sort", $_GET)) { + $sortSpec = $_GET['sort']; + $sortSpec = str_replace("\\\"", "\"", $sortSpec); + $sortSpec = json_decode($sortSpec); + } + + if ($sortSpec != null) { + $comparator = createComparator($sortSpec); + usort($files,array($comparator, "compare")); + } + + //Page, if necessary. + if (array_key_exists("start", $_GET)) { + $start = $_GET['start']; + if (!is_numeric($start)) { + $start = 0; + } + $files = array_slice($files, $start); + } + if (array_key_exists("count", $_GET)) { + $count = $_GET['count']; + if (!is_numeric($count)) { + $count = $total; + } + $files = array_slice($files, 0, $count); + } + + $result; + $result->total = $total; + $result->items = $files; + header("Content-Type", "text/json"); + print("/* ".json_encode($result)." */"); + } else { + //Query of a specific file (useful for fetchByIdentity and loadItem) + + //Make sure the path isn't trying to walk out of the rooted directory + //As defined by $rootDir in the top of the php script. + $rootPath = realPath($rootDir); + $fullPath = realPath($rootPath."/".$path); + + if ($fullPath !== false) { + if (strpos($fullPath,$rootPath) === 0) { + //Root the path into the tree cleaner. + if (strlen($fullPath) == strlen($rootPath)) { + $path = "."; + } else { + //Fix the path to relative of root and put back into UNIX style (even if windows). + $path = substr($fullPath,(strlen($rootPath) + 1),strlen($fullPath)); + $path = str_replace("\\", "/", $path); + } + + if (file_exists($fullPath)) { + $arr = split("/", $path); + $size = count($arr); + + if ($size > 0) { + $fName = $arr[$size - 1]; + if ($size == 1) { + print("Setting path to: ."); + $path = "."; + } else { + $path = $arr[0]; + } + for ($i = 1; $i < ($size - 1); $i++) { + $path = $path."/".$arr[$i]; + } + $file = generateFileObj($fName, $path, $rootDir, $expand,$showHiddenFiles); + header("Content-Type", "text/json"); + print("/* ".json_encode($file)." */"); + } else { + header("HTTP/1.0 404 Not Found"); + header("Status: 404 Not Found"); + print("<b>Cannot access file: [".htmlentities($path)."]<b>"); + } + } else { + header("HTTP/1.0 404 Not Found"); + header("Status: 404 Not Found"); + print("<b>Cannot access file: [".htmlentities($path)."]<b>"); + } + } else { + header("HTTP/1.0 403 Forbidden"); + header("Status: 403 Forbidden"); + print("<b>Cannot access file: [".htmlentities($path)."]. It is outside of the root of the file service.<b>"); + } + } else { + header("HTTP/1.0 404 Not Found"); + header("Status: 404 Not Found"); + print("<b>Cannot access file: [".htmlentities($path)."]<b>"); + } + } +?> diff --git a/js/dojo/dojox/data/demos/stores/filestore_funcs.php b/js/dojo/dojox/data/demos/stores/filestore_funcs.php new file mode 100644 index 0000000..ff61139 --- /dev/null +++ b/js/dojo/dojox/data/demos/stores/filestore_funcs.php @@ -0,0 +1,366 @@ +<?php + /** + * Helper function to convert a simple pattern to a regular expression for matching. + * + * Returns a regular expression object that conforms to the defined conversion rules. + * For example: + * ca* -> /^ca.*$/ + * *ca* -> /^.*ca.*$/ + * *c\*a* -> /^.*c\*a.*$/ + * *c\*a?* -> /^.*c\*a..*$/ + * and so on. + * + * @param pattern: string + * A simple matching pattern to convert that follows basic rules: + * * Means match anything, so ca* means match anything starting with ca + * ? Means match single character. So, b?b will match to bob and bab, and so on. + * \ is an escape character. So for example, \* means do not treat * as a match, but literal character *. + * To use a \ as a character in the string, it must be escaped. So in the pattern it should be + * represented by \\ to be treated as an ordinary \ character instead of an escape. + */ + function patternToRegExp(/*String*/$pattern){ + $rxp = "^"; + $c = ""; + $len = strlen($pattern); + for ($i = 0; $i < $len; $i++) { + $c = $pattern[$i]; + switch ($c) { + case '\\': + $rxp = $rxp.$c; + $i++; + $rxp = $rxp.$pattern[$i]; + break; + case '*': + $rxp = $rxp.".*"; break; + case '?': + $rxp = $rxp."."; break; + case '$': + case '^': + case '/': + case '+': + case '.': + case '|': + case '(': + case ')': + case '{': + case '}': + case '[': + case ']': + $rxp = $rxp."\\"; //fallthrough + default: + $rxp = $rxp.$c; + } + } + return "(".$rxp."$)"; + } + + /** + * Function to load all file info from a particular directory. + * + * @param $dir The dir to seach from, relative to $rootDir. + * @param $rootDir The directory where the file service is rooted, used as separate var to allow easier checking and prevention of ../ing out of the tree. + * @param $recurse Whether or not to deep scan the dir and return all subfiles, or just return the toplevel files. + * @param $dirsOnly boolean to enote to only return directory names, not filenames. + * @param $expand boolean to indicate whether or not to inflate all children files along a path/file, or leave them as stubs. + * @param $showHiddenFiles boolean to indicate to return hidden files as part of the list. + */ + function getAllfiles($dir, $rootDir, $recurse, $dirsOnly, $expand, $showHiddenFiles) { + // summary: + // A function to obtain all the files in a particular directory (file or dir) + $files = array(); + $dirHandle = opendir($rootDir."/".$dir); + if ($dirHandle) { + while($file = readdir($dirHandle)) { + if ($file) { + if ($file != ".." && $file != ".") { + $path = $dir."/".$file; + $fileObj = generateFileObj($file, $dir, $rootDir,$expand,$showHiddenFiles); + if (is_dir($rootDir."/".$path)) { + if ($recurse) { + if ($showHiddenFiles || $fileObj["name"][0] != '.') { + $subfiles = getAllfiles($path,$rootDir,$recurse,$dirsOnly,$expand,$showHiddenFiles); + $length = count($subfiles); + for ($i = 0; $i < $length; $i++) { + $files[] = $subfiles[$i]; + } + } + } + } + if (!$dirsOnly || $fileObj["directory"]) { + if ($showHiddenFiles || $fileObj["name"][0] !== '.') { + $files[] = $fileObj; + } + } + } + } + } + } + closedir($dirHandle); + return $files; + } + + /** + * Function to generate an associative map of data about a specific file. + * @param $file The name of the file this object represents. + * @param $dir The sub-path that contains the file defined by $file + * @param $rootDir The directory from which to append dir and name to get the full path to the file. + * @param $expand boolean to denote that if the file is a directory, expand all children in the children attribute + * to a a full object + * @param $showHiddenFiles boolean to denote if hidden files should be shown in-view or not. + * + * @return Associative Map. The details about the file: + * $file["name"] - Returns the shortname of the file. + * $file["parentDir"] - Returns the relative path from the service root for the parent directory containing file $file["name"] + * $file["path"] - The relative path to the file. + * $file["directory"] - Boolean indicator if the file represents a directory. + * $file["size"] - The size of the file, in bytes. + * $file["modified] - The modified date of the file in milliseconds since Jan 1st, 1970. + * $file["children"] - Children files of a directory. Empty if a standard file. + */ + function generateFileObj($file, $dir, $rootDir, $expand, $showHiddenFiles) { + // summary: + // Function to generate an object representation of a disk file. + $path = $file; + if ($dir != "." && $dir != "./") { + $path = $dir."/".$file; + } + + $fullPath = $rootDir."/".$path; + + $atts = stat($fullPath); + + $rootPath = realPath($rootDir); + $resolvedDir = realPath($rootDir."/".$dir); + $resolvedFullPath = realPath($fullPath); + + //Try to normalize down the paths so it does a consistent return. + if (strcmp($rootPath, $resolvedDir) === 0) { + $dir = "."; + } else { + $dir = substr($resolvedDir, (strlen($rootPath) + 1), strlen($resolvedDir)); + $dir = "./".str_replace("\\","/",$dir); + } + if (strcmp($rootPath, $resolvedFullPath) === 0) { + $path = "."; + } else { + $path = substr($resolvedFullPath, (strlen($rootPath) + 1), strlen($resolvedFullPath)); + $path = "./".str_replace("\\","/",$path); + } + + $fObj = array(); + $fObj["name"] = $file; + $fObj["parentDir"] = $dir; + $fObj["path"] = $path; + $fObj["directory"] = is_dir($fullPath); + $fObj["size"] = filesize($fullPath); + $fObj["modified"] = $atts[9]; + + if (is_dir($fullPath)) { + $children = array(); + $dirHandle = opendir($fullPath); + while($cFile = readdir($dirHandle)) { + if ($cFile) { + if ($cFile != ".." && $cFile != ".") { + if ($showHiddenFiles || $cFile[0] != '.') { + if (!$expand) { + $children[] = $cFile; + }else{ + $children[] = generateFileObj($cFile, $path, $rootDir, $expand, $showHiddenFiles); + } + } + } + } + } + closedir($dirHandle); + $fObj["children"] = $children; + } + return $fObj; + } + + /** + * A field comparator class, whose role it is to define which fields on an associaive map to compare on + * and provide the comparison function to do so. + */ + class FieldComparator { + var $field; + var $descending = false; + + /** + * Constructor. + * @param $f The field of the item to compare. + * @param $d Parameter denoting whether it should be ascending or descending. Default is ascending. + */ + function FieldComparator($f, $d) { + $this->field = $f; + $this->descending = $d; + } + + /** + * Function to compare file objects A and B on the field defined by $this->field. + * @param $fileA The first file to compare. + * @param #fileB The second file to compare. + */ + function compare($fileA,$fileB){ + $f = $this->field; + $a = $fileA[$f]; + $b = $fileB[$f]; + + $ret = 0; + if (is_string($a) && is_string($b)) { + $ret = strcmp($a,$b); + } else if($a > $b || $a === null){ + $ret = 1; + }else if($a < $b || $b === null){ + $ret = -1; + } + + if (property_exists($this, "descending") && $this->descending == true) { + $ret = $ret * -1; + } + + if ($ret > 0) { + $ret = 1; + } else if ($ret < 0) { + $ret = -1; + } + return $ret; //int, {-1,0,1} + } + } + + /** + * A compound comparator class, whose role it is to sequentially call a set of comparators on two objects and + * return the combined result of the comparison. + */ + class CompoundComparator { + //Comparator chain. + var $comparators = array(); + + /** + * Function to compare two objects $a and $b, using the chain of comparators. + * @param $a The first object to compare. + * @param $b The second object to compare. + * @returns -1, 0, 1. -1 if a < b, 1 if a > b, and 0 if a = b. + */ + function compare($a, $b) { + $ret = 0; + $size = count($this->comparators); + for ($i = 0; $i < $size; $i++) { + $comp = $this->comparators[$i]; + $ret = $comp->compare($a, $b); + if ($ret != 0) { + break; + } + } + return $ret; + } + + /** + * Function to add a comparator to the chain. + * @param $comp The comparator to add. + */ + function addComparator($comp){ + $this->comparators[] = $comp; + } + } + + /** + * A function to create a Comparator class with chained comparators based off the sort specification passed into the store. + * @param $sortSpec The Sort specification, which is an array of sort objects containing ( attribute: "someStr": descending: true|fase} + * @returns The constructed comparator. + */ + function createComparator($sortSpec) { + //Function to construct the class that handles chained comparisons. + $comparator = new CompoundComparator(); + $size = count($sortSpec); + for ($i = 0; $i < $size; $i++) { + $sort = $sortSpec[$i]; + $desc = false; + if(property_exists($sort, "descending")){ + $desc = $sort->descending; + } + $fileComp = new FieldComparator($sort->attribute,$desc); + $comparator->addComparator($fileComp); + } + return $comparator; + } + + /** + * Function to match a set of queries against a directory and possibly all subfiles. + * @param query The Query send in to process and test against. + * @param patterns The set of regexp patterns generated off the query. + * @param dir the directory to search in. + * @param recurse Whether or not to recurse into subdirs and test files there too. + * + * @return Array. Returns an array of all matches of the query. + */ + function matchFiles($query, $patterns, $ignoreCase, $dir, $rootDir, $recurse, $dirsOnly, $expand, $showHiddenFiles) { + $files = array(); + $fullDir = $rootDir."/".$dir; + + if ($fullDir != null && is_dir($fullDir)) { + + $dirHandle = opendir($fullDir); + while ($file = readdir($dirHandle)) { + if ($file != "." && $file != "..") { + $item = generateFileObj($file, $dir, $rootDir, $expand,$showHiddenFiles); + $keys = array_keys($patterns); + $total = count($keys); + for ($i = 0; $i < $total; $i++) { + $key = $keys[$i]; + $pattern = $query[$key]; + $matched = containsValue($item,$key,$query[$key],$patterns[$key], $ignoreCase); + if (!$matched) { + break; + } + } + if ($matched) { + if (!$dirsOnly || $item["directory"]) { + if ($showHiddenFiles || $item["name"][0] != '.') { + $files[] = $item; + } + } + } + + if (is_dir($rootDir."/".$item["path"]) && $recurse) { + if ($showHiddenFiles || $item["name"][0] != '.') { + $files = array_merge($files, matchFiles($query, $patterns, $ignoreCase, $item["path"], $rootDir, $recurse, $dirsOnly, $expand, $showHiddenFiles)); + } + } + } + } + closedir($dirHandle); + } + return $files; + } + + /** + * Function to handle comparing the value of an attribute on a file item. + * @param item The item to examine. + * @param attr The attribute of the tem to examine. + * @parma value The value to compare it to. + * @param rExp A regular Expression pattern object generated off 'value' if any. + * + * @returns boolean denoting if the value was matched or not. + */ + function containsValue($item, $attr, $value, $rExp, $ignoreCase) { + $matched = false; + $possibleValue = $item[$attr]; + if ($possibleValue === null && $value === null) { + $matched = true; + } else { + if ($rExp != null && is_string($possibleValue)) { + if ($ignoreCase) { + $matched = eregi($rExp, $possibleValue); + } else { + $matched = ereg($rExp, $possibleValue); + } + + } else { + if ($value != null && $possibleValue != null) { + $matched = ($value == $possibleValue); + } + } + } + return $matched; + } +// No closing PHP tag on purpose. Do not want it to print whitepace and thus not allow setting headers later. |
