summaryrefslogtreecommitdiff
path: root/js/dojo/dojox/data/demos/stores
diff options
context:
space:
mode:
authorTristan Zur <tzur@web.web.ccwn.org>2014-03-27 22:27:47 +0100
committerTristan Zur <tzur@web.web.ccwn.org>2014-03-27 22:27:47 +0100
commitb62676ca5d3d6f6ba3f019ea3f99722e165a98d8 (patch)
tree86722cb80f07d4569f90088eeaea2fc2f6e2ef94 /js/dojo/dojox/data/demos/stores
Initial commit of intern.ccwn.org contentsHEADmaster
Diffstat (limited to 'js/dojo/dojox/data/demos/stores')
-rw-r--r--js/dojo/dojox/data/demos/stores/LazyLoadJSIStore.js143
-rw-r--r--js/dojo/dojox/data/demos/stores/filestore_dojotree.php179
-rw-r--r--js/dojo/dojox/data/demos/stores/filestore_dojoxdata.php179
-rw-r--r--js/dojo/dojox/data/demos/stores/filestore_funcs.php366
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.