Commit 552c8bfec765b90a137eef651a2e90f88b7d886e

Authored by Paul Barrett
1 parent c7f71f63

committing missing unit tests file

tests/ktcmis/myf5429.tmp 0 → 100644
  1 +this is some text
0 2 \ No newline at end of file
... ...
tests/ktcmis/myf7FFE.tmp 0 → 100644
  1 +this is some text
0 2 \ No newline at end of file
... ...
tests/ktcmis/myf8F68.tmp 0 → 100644
  1 +this is some text
0 2 \ No newline at end of file
... ...
tests/ktcmis/testCmisApi.php 0 → 100644
  1 +<?php
  2 +require_once (KT_DIR . '/tests/test.php');
  3 +require_once (KT_DIR . '/ktcmis/ktcmis.inc.php');
  4 +
  5 +// username and password for authentication
  6 +// must be set correctly for all of the tests to pass in all circumstances
  7 +define (KT_TEST_USER, 'admin');
  8 +define (KT_TEST_PASS, 'admin');
  9 +
  10 +/**
  11 + * These are the unit tests for the main KTCMIS class
  12 + *
  13 + * NOTE All functions which require electronic signature checking need to send
  14 + * the username and password and reason arguments, else the tests WILL fail IF
  15 + * API Electronic Signatures are enabled.
  16 + * Tests will PASS when API Signatures NOT enabled whether or not
  17 + * username/password are sent.
  18 + */
  19 +class CMISTestCase extends KTUnitTestCase {
  20 +
  21 + /**
  22 + * @var object $ktcmis The main ktapi object
  23 + */
  24 + var $ktcmis;
  25 +
  26 + /**
  27 + * @var object $session The KT session object
  28 + */
  29 + var $session;
  30 +
  31 + /**
  32 + * @var object $root The KT folder object
  33 + */
  34 + var $root;
  35 +
  36 + private $folders;
  37 + private $subfolders;
  38 + private $docs;
  39 +
  40 + /**
  41 + * This method sets up the KT session
  42 + *
  43 + */
  44 + public function setUp() {
  45 + $this->ktapi = new KTAPI();
  46 + $this->session = $this->ktapi->start_session(KT_TEST_USER, KT_TEST_PASS);
  47 + $this->ktcmis = new KTCMIS($this->ktapi);
  48 + $this->root = $this->ktapi->get_root_folder();
  49 + $this->folders = array();
  50 + $this->docs = array();
  51 + }
  52 +
  53 + /**
  54 + * This method ends the KT session
  55 + */
  56 + public function tearDown() {
  57 + $this->session->logout();
  58 + }
  59 +
  60 + // Repository service functions
  61 + function testRepositoryServices()
  62 + {
  63 + // TEST 1
  64 + // test get repositories
  65 + $response = $this->ktcmis->getRepositories();
  66 +
  67 + $this->assertEqual($response['status_code'], 0);
  68 + $this->assertNotNull($response['results'][0]);
  69 +
  70 + // we only expect one repository, though there may be more
  71 + $repository = $response['results'][0];
  72 +
  73 + // check for null
  74 + $this->assertNotNull($repository['repositoryId']);
  75 + $this->assertNotNull($repository['repositoryName']);
  76 + $this->assertNotNull($repository['repositoryURI']);
  77 +
  78 + // check for empty string
  79 + $this->assertNotEqual(trim($repository['repositoryId']), '');
  80 + $this->assertNotEqual(trim($repository['repositoryName']), '');
  81 + $this->assertNotEqual(trim($repository['repositoryURI']), '');
  82 +
  83 + // test printout
  84 + $this->printTable($repository, 'Available Repositories (getRepositories())');
  85 +
  86 + /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  87 +
  88 + $repositoryId = $repository['repositoryId'];
  89 +
  90 + // TEST 2
  91 + // test getting info for specified repository
  92 +
  93 + // get info
  94 + $response = $this->ktcmis->getRepositoryInfo($repositoryId);
  95 +
  96 + $this->assertEqual($response['status_code'], 0);
  97 + $this->assertNotNull($response['results']);
  98 +
  99 + $repositoryInfo = $response['results'];
  100 +
  101 + // returned ID MUST match sent ID
  102 + $this->assertEqual($repositoryId, $repositoryInfo['repositoryId']);
  103 +
  104 + // check for null
  105 + $this->assertNotNull($repositoryInfo['repositoryName']);
  106 +
  107 + // check for empty string
  108 + $this->assertNotEqual(trim($repositoryInfo['repositoryName']), '');
  109 +
  110 + $capabilities = $repositoryInfo['capabilities'];
  111 + $this->assertNotNull($capabilities);
  112 +// echo '<pre>'.print_r($repositoryInfo, true).'</pre>';
  113 +
  114 + // test printout
  115 + $this->printTable($repositoryInfo, 'Repository Information for ' . $repositoryInfo['repositoryName'] . ' Repository (getRepositoryInfo())');
  116 +
  117 + /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  118 +
  119 + // TEST 3
  120 + // test get object types supported by specified repository
  121 +
  122 + $response = $this->ktcmis->getTypes($repositoryId);
  123 +
  124 + $this->assertEqual($response['status_code'], 0);
  125 + $this->assertNotNull($response['results']);
  126 +
  127 + $supportedObjects = $response['results'];
  128 +// echo '<pre>'.print_r($supportedObjects, true).'</pre>';
  129 +
  130 + // we're expecting support for Documents and Folders
  131 + // TODO change test to not care about alphabetical or order alphabetically first,
  132 + // just in case at some point we manage to return the objects in another order :)
  133 + // TODO this test is pretty arbitrary, needs work to properly test results,
  134 + // for now just testing that something was returned
  135 + $this->assertEqual($supportedObjects[0]['typeId'], 'Document');
  136 + $this->assertEqual($supportedObjects[1]['typeId'], 'Folder');
  137 +
  138 + // test printout
  139 + $this->printTable($supportedObjects, 'CMIS Objects Supported by the ' . $repository['repositoryName'] . ' Repository (getTypes())', 'Object Type');
  140 +
  141 + /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  142 +
  143 + // TEST 4
  144 + // test getting type definition for specified types
  145 + // types to test
  146 + $types = array('Document', 'Folder');
  147 +
  148 + // now get info
  149 + foreach ($types as $typeId)
  150 + {
  151 + $response = $this->ktcmis->getTypeDefinition($repositoryId, $typeId);
  152 +
  153 + $this->assertEqual($response['status_code'], 0);
  154 + $this->assertNotNull($response['results']);
  155 +
  156 + $typeDefinition = $response['results'];
  157 +
  158 + // we're expecting support for Documents and Folders
  159 + // TODO change test to not care about alphabetical or order alphabetically first,
  160 + // just in case at some point we manage to return the objects in another order :)
  161 + // TODO this test is pretty arbitrary, needs work to properly test results,
  162 + // for now just testing that something was returned which matches the requested type
  163 + $this->assertEqual($typeDefinition['typeId'], $typeId);
  164 +
  165 + // test printout
  166 + $this->printTable($typeDefinition, 'CMIS Type Definition for ' . $typeDefinition['typeId'] . ' Objects (getTypeDefinition())');
  167 +
  168 + // TODO test properties as well
  169 + }
  170 +
  171 + // test printout
  172 + echo '<div>&nbsp;</div>';
  173 + }
  174 +
  175 + // Navigation service functions
  176 + function testNavigationServices()
  177 + {
  178 + // set up the folder/doc tree structure with which we will be testing
  179 + $this->createFolderDocStructure();
  180 +
  181 + // TEST 1
  182 + // test getting descendants
  183 + $response = $this->ktcmis->getRepositories();
  184 +
  185 + $this->assertEqual($response['status_code'], 0);
  186 + $this->assertNotNull($response['results'][0]);
  187 +
  188 + // we only expect one repository
  189 + $repository = $response['results'][0];
  190 + $repositoryId = $repository['repositoryId'];
  191 +
  192 + // test descendant functionality on first of created folders, should have depth 2;
  193 + $folderid = 'F' . $this->folders[1];
  194 +// $folderid = 'F1';
  195 +
  196 + $depth = 2;
  197 + $result = $this->ktcmis->getDescendants($repositoryId, $folderid, false, false, $depth);
  198 +// echo '<pre>'.print_r($result, true).'</pre>';
  199 +// var_dump($result);
  200 + $this->assertEqual($response['status_code'], 0);
  201 + $this->assertNotNull($response['results'][0]);
  202 +
  203 + $descendants = $result['results'];
  204 + $this->assertNotNull($descendants);
  205 +
  206 + // check depth
  207 + $dug = $this->array_depth($descendants);
  208 +// echo "DUG TO $dug (aiming for $depth)<BR>";
  209 +// $this->assertEqual($depth, $dug);
  210 +
  211 + // test printout
  212 + $this->printTree($descendants, 'Descendants for Folder ' . $folderid . ' (getDescendants())', $dug);
  213 +
  214 + /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  215 +
  216 + // TEST 2
  217 + // test getting direct children, using the second set of folders, should have a folder and a document as children
  218 + $folderid_2 = 'F' . $this->folders[0];
  219 +
  220 + $result = $this->ktcmis->getChildren($repositoryId, $folderid_2, false, false);
  221 + $this->assertNotNull($result['results']);
  222 +
  223 + $children = $result['results'];
  224 +
  225 + // total child count should be 2, as there is a single folder and a single document
  226 +//echo '<pre>'.print_r($children, true).'</pre>';
  227 +
  228 + // test printout
  229 + $this->printTree($children, 'Children for Folder ' . $folderid_2 . ' (getChildren())');
  230 +
  231 + /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  232 +
  233 + // TEST 3
  234 + // test getting folder parent, using first created folder, parent should be root folder
  235 +
  236 +// echo "OUTPUT FROM FIRST TEST<BR>";
  237 + $ancestry = $this->ktcmis->getFolderParent($repositoryId, $folderid, false, false, false);
  238 + $this->assertNotNull($ancestry['results']);
  239 +// echo "OUTPUT FROM FIRST TEST<BR>";
  240 +// echo '<pre>'.print_r($ancestry, true).'</pre>';
  241 +
  242 + // test printout
  243 + $this->printTree($ancestry['results'], 'Parent for Folder ' . $folderid . ' (getFolderParent())');
  244 +
  245 + // test with one of the subfolders...
  246 + $subfolder_id = 'F' . $this->subfolders[0];
  247 +
  248 +// echo "OUTPUT FROM SECOND TEST<BR>";
  249 + // TODO since here we are testing more than one level up, add check for depth as with testGetDescendants
  250 + $ancestry = $this->ktcmis->getFolderParent($repositoryId, $subfolder_id, false, false, true);
  251 + $this->assertNotNull($ancestry['results']);
  252 +// echo "OUTPUT FROM SECOND TEST<BR>";
  253 +// echo '<pre>'.print_r($ancestry, true).'</pre>';
  254 +
  255 + // NOTE can only send depth here because we know it :)
  256 + // test printout
  257 + $this->printTree($ancestry['results'], 'Parent hierarchy (Return To Root) for Folder ' . $subfolder_id . ' (getFolderParent())', 2);
  258 +
  259 + /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
  260 +
  261 + // TEST 4
  262 + // test getting object parent(s) with a document
  263 +
  264 + $objectId = 'D' . $this->docs[0]->get_documentid();
  265 + $ancestry = $this->ktcmis->getObjectParents($repositoryId, $objectId, false, false);
  266 + $this->assertNotNull($ancestry);
  267 +// echo '<pre>'.print_r($ancestry, true).'</pre>';
  268 +
  269 + // test printout
  270 + $this->printTree($ancestry['results'], 'Parent for (Document) Object ' . $objectId . ' (getObjectParents())');
  271 +
  272 + // TEST
  273 + // test getting object parent(s) with a folder
  274 +
  275 + $objectId = 'F' . $this->subfolders[0];
  276 + $ancestry = $this->ktcmis->getObjectParents($repositoryId, $objectId, false, false);
  277 + $this->assertNotNull($ancestry);
  278 +// echo '<pre>'.print_r($ancestry, true).'</pre>';
  279 +
  280 + // test printout
  281 + $this->printTree($ancestry['results'], 'Parent for (Folder) Object ' . $objectId . ' (getObjectParents())');
  282 +
  283 + // tear down the folder/doc tree structure with which we were testing
  284 + $this->cleanupFolderDocStructure();
  285 +
  286 + // test printout
  287 + echo '<div>&nbsp;</div>';
  288 + }
  289 +
  290 + // Object Services
  291 +
  292 + function testObjectServices()
  293 + {
  294 + // set up the folder/doc tree structure with which we will be testing
  295 + $this->createFolderDocStructure();
  296 +
  297 + // TEST 1
  298 + // test getting properties for a specific object
  299 +
  300 + $response = $this->ktcmis->getRepositories();
  301 +
  302 + $this->assertEqual($response['status_code'], 0);
  303 + $this->assertNotNull($response['results'][0]);
  304 +
  305 + // we only expect one repository
  306 + $repository = $response['results'][0];
  307 + $repositoryId = $repository['repositoryId'];
  308 +
  309 + $objectId = 'F'.$this->folders[0];
  310 +
  311 + $properties = $this->ktcmis->getProperties($repositoryId, $objectId, false, false);
  312 + $this->assertNotNull($properties['results']);
  313 +// echo '<pre>'.print_r($properties['results'], true).'</pre>';
  314 +//
  315 + // test printout
  316 + $this->printTable($properties['results'][0], 'Properties for Folder Object ' . $objectId . ' (getProperties())');
  317 +
  318 + $objectId = 'D'.$this->docs[0]->get_documentid();
  319 +
  320 + $properties = $this->ktcmis->getProperties($repositoryId, $objectId, false, false);
  321 + $this->assertNotNull($properties['results']);
  322 +
  323 + // test printout
  324 + $this->printTable($properties['results'][0], 'Properties for Folder Object ' . $objectId . ' (getProperties())');
  325 +
  326 + // tear down the folder/doc tree structure with which we were testing
  327 + $this->cleanupFolderDocStructure();
  328 +
  329 + // test printout
  330 + echo '<div>&nbsp;</div>';
  331 + }
  332 +
  333 + /**
  334 + * Helper function to create a document
  335 + */
  336 + function createDocument($title, $filename, $folder = null)
  337 + {
  338 + if(is_null($folder)){
  339 + $folder = $this->root;
  340 + }
  341 +
  342 + // Create a new document
  343 + $randomFile = $this->createRandomFile();
  344 + $this->assertTrue(is_file($randomFile));
  345 +
  346 + $document = $folder->add_document($title, $filename, 'Default', $randomFile, KT_TEST_USER, KT_TEST_PASS, 'Testing API');
  347 + $this->assertNotError($document);
  348 +
  349 + @unlink($randomFile);
  350 + if(PEAR::isError($document)) return false;
  351 +
  352 + return $document;
  353 + }
  354 +
  355 + /**
  356 + * Helper function to delete docs
  357 + */
  358 + function deleteDocument($document)
  359 + {
  360 + $document->delete('Testing API');
  361 + $document->expunge();
  362 + }
  363 +
  364 + function createRandomFile($content = 'this is some text', $uploadDir = null)
  365 + {
  366 + if(is_null($uploadDir)){
  367 + $uploadDir = dirname(__FILE__);
  368 + }
  369 + $temp = tempnam($uploadDir, 'myfile');
  370 + $fp = fopen($temp, 'wt');
  371 + fwrite($fp, $content);
  372 + fclose($fp);
  373 + return $temp;
  374 + }
  375 +
  376 + function createFolderDocStructure()
  377 + {
  378 + // Create a folder
  379 + $result1 = $this->ktapi->create_folder(1, 'New test api folder', KT_TEST_USER, KT_TEST_PASS, 'Testing API');
  380 +
  381 + $folder_id = $result1['results']['id'];
  382 + $this->folders[] = $folder_id;
  383 +
  384 + // Create a sub folder
  385 + $result2 = $this->ktapi->create_folder($folder_id, 'New test api sub-folder', KT_TEST_USER, KT_TEST_PASS, 'Testing API');
  386 + $folder_id2 = $result2['results']['id'];
  387 + $this->subfolders[] = $folder_id2;
  388 +
  389 + // Add a document to the subfolder
  390 + global $default;
  391 + $dir = $default->uploadDirectory;
  392 + $tempfilename = $this->createRandomFile('some text', $dir);
  393 + $document1 = $this->ktapi->add_document($folder_id2, 'New API test subdoc', 'testsubdoc1.txt', 'Default',
  394 + $tempfilename, KT_TEST_USER, KT_TEST_PASS, 'Testing API');
  395 + @unlink($tempfilename);
  396 +
  397 + // Create a second set of folders
  398 + $result1 = $this->ktapi->create_folder(1, 'New test api folder the second', KT_TEST_USER, KT_TEST_PASS, 'Testing API');
  399 + $folder_id = $result1['results']['id'];
  400 + $this->folders[] = $folder_id;
  401 +
  402 + // Add a single document to the root folder of the second set
  403 + $tempfilename = $this->createRandomFile('some text', $dir);
  404 + $document2 = $this->ktapi->add_document($folder_id, 'New API test subdoc', 'testsubdoc3.txt', 'Default',
  405 + $tempfilename, KT_TEST_USER, KT_TEST_PASS, 'Testing API');
  406 + @unlink($tempfilename);
  407 +
  408 + // Create a sub folder
  409 + $result2 = $this->ktapi->create_folder($folder_id, 'New test api sub-folder for the second', KT_TEST_USER, KT_TEST_PASS, 'Testing API');
  410 + $folder_id2 = $result2['results']['id'];
  411 + $this->subfolders[] = $folder_id2;
  412 +
  413 + // Add a couple of documents to the second subfolder
  414 + $tempfilename = $this->createRandomFile('some text', $dir);
  415 + $document3 = $this->ktapi->add_document($folder_id2, 'New API test subdoc', 'testsubdoc2.txt', 'Default',
  416 + $tempfilename, KT_TEST_USER, KT_TEST_PASS, 'Testing API');
  417 + @unlink($randomFile);
  418 + $randomFile = $this->createRandomFile();
  419 + $document4 = $this->ktapi->add_document($folder_id2, 'New API test subdoc', 'testsubdoc4.txt', 'Default',
  420 + $tempfilename, KT_TEST_USER, KT_TEST_PASS, 'Testing API');
  421 + @unlink($tempfilename);
  422 +
  423 + // add root level docs
  424 +
  425 + $tempfilename = $this->createRandomFile('some text', $dir);
  426 + $document5 = $this->root->add_document('title_1.txt', 'name_1.txt', 'Default', $randomFile, KT_TEST_USER, KT_TEST_PASS, 'Testing API');
  427 + @unlink($tempfilename);
  428 +
  429 + $this->docs[] =& $document5;
  430 +
  431 + // create the document object
  432 + $randomFile = $this->createRandomFile();
  433 + $document6 = $this->root->add_document('title_2.txt', 'name_2.txt', 'Default', $randomFile, KT_TEST_USER, KT_TEST_PASS, 'Testing API');
  434 +
  435 + @unlink($randomFile);
  436 +
  437 + $this->docs[] =& $document6;
  438 + }
  439 +
  440 + function cleanupFolderDocStructure()
  441 + {
  442 + // clean up root level docs
  443 + foreach($this->docs as $doc)
  444 + {
  445 + $doc->delete('Testing');
  446 + $doc->expunge();
  447 + }
  448 +
  449 + // Clean up root level folders (sub-folders and contained docs should be removed automatically)
  450 + foreach ($this->folders as $folder_id)
  451 + {
  452 + $this->ktapi->delete_folder($folder_id, 'Testing API', KT_TEST_USER, KT_TEST_PASS);
  453 + }
  454 + }
  455 +
  456 + function array_depth($array)
  457 + {
  458 +// echo '<pre>'.print_r($array, true).'</pre>';
  459 + if (!(is_array($array))) return 0;
  460 +
  461 + $dug = 0;
  462 +
  463 + $array_str = print_r($array, true);
  464 + $lines = explode("\n", $array_str);
  465 +
  466 + $matched = false;
  467 + foreach ($lines as $line) {
  468 + if (preg_match('/\[0\] => Array/', $line))
  469 + {
  470 + // going down one level
  471 + ++$dug;
  472 + $matched = true;
  473 + }
  474 + else if (preg_match('/\[[^0]\] => Array/', $line))
  475 + {
  476 + // coming up one level
  477 + --$dug;
  478 + $matched = false;
  479 + }
  480 + else if ($matched && (preg_match('/\[item_type\] => D/', $line)))
  481 + {
  482 + --$dug;
  483 + $matched = false;
  484 + }
  485 + }
  486 +
  487 + // oops, glitch if single level only :)
  488 + if ($dug < 1)
  489 + return 1;
  490 +
  491 + return ++$dug;
  492 + }
  493 +
  494 + function printTable($results, $header, $subheader = '', $depth = 1)
  495 + {
  496 + // turn off for testing :)
  497 +// return null;
  498 + ?><div>&nbsp;</div>
  499 + <table border="2"><tr><td colspan="2"><div style="padding: 8px; background-color: green; color: white;"><?php
  500 + echo $header;
  501 + ?></div></td></tr><?php
  502 + foreach($results as $key => $value)
  503 + {
  504 + if ($value == '') continue;
  505 + if (is_array($value))
  506 + {
  507 + if ($subheader != '')
  508 + {
  509 + ?><tr><td colspan="2"><div style="padding: 8px; background-color: lightblue; color: black;"><?php
  510 + echo $subheader;
  511 + ?></div></td></tr><?php
  512 + }
  513 +
  514 + foreach($value as $subkey => $subvalue)
  515 + {
  516 + if ($subvalue == '') continue;
  517 + $this->printRow($subkey, $subvalue);
  518 + }
  519 + }
  520 + else
  521 + {
  522 + $this->printRow($key, $value);
  523 + }
  524 + }
  525 + ?></table><?php
  526 + }
  527 +
  528 + function printRow($key, $value, $indent = 0)
  529 + {
  530 + echo '<tr>';
  531 + if ($indent)
  532 + {
  533 + for ($i = 1; $i <= $indent; ++$i)
  534 + {
  535 + echo '<td>&nbsp;</td>';
  536 + }
  537 + }
  538 + echo ' <td style="padding-left:15px;padding-right:15px;">' . $key . '</td>
  539 + <td style="padding-left:15px;padding-right:15px;">' . $value . '</td>
  540 + </tr>';
  541 + }
  542 +
  543 + function printTree($results, $header, $depth = 1)
  544 + {
  545 + ?><div>&nbsp;</div>
  546 + <table border="2"><tr><td colspan="<?php echo 1 + $depth; ?>"><div style="padding: 8px; background-color: green; color: white;"><?php
  547 + echo $header;
  548 + ?></div></td></tr><?php
  549 +
  550 + // after header we want to print the first level, indent for second level, indent twice for 3rd, etc...
  551 +
  552 + foreach($results as $key => $value)
  553 + {
  554 + ?><tr><td colspan="<?php echo 1 + $depth; ?>"><div style="padding: 8px; background-color: lightblue; color: black;"><?php
  555 + echo $value['properties']['name'];
  556 + ?></div></td></tr><?php
  557 + // properties first
  558 + foreach ($value['properties'] as $propkey => $propval)
  559 + {
  560 + if ($propval == '') continue;
  561 +
  562 + $this->printRow($propkey, $propval);
  563 + }
  564 +
  565 + // now any children
  566 + if ($value['child'])
  567 + {
  568 + foreach ($value['child'] as $childkey => $childval)
  569 + {
  570 + $this->printChild($childval);
  571 + }
  572 + }
  573 +
  574 +// if ($value == '') continue;
  575 +// if (is_array($value))
  576 +// {
  577 +// if ($subheader != '')
  578 +// {
  579 +/*
  580 +// ?><tr><td colspan="2"><div style="padding: 8px; background-color: lightblue; color: black;"><?php
  581 +// echo $subheader;
  582 +// ?></div></td></tr><?php
  583 + *
  584 + */
  585 +// }
  586 +//
  587 +// foreach($value as $subkey => $subvalue)
  588 +// {
  589 +// if ($subvalue == '') continue;
  590 +// $this->printRow($subkey, $subvalue);
  591 +// }
  592 +// }
  593 +// else
  594 +// {
  595 +// $this->printRow($key, $value);
  596 +// }
  597 + }
  598 + ?></table><?php
  599 + }
  600 +
  601 + function printChild($child, $indent = 1)
  602 + {
  603 + ?><tr><?php
  604 + if ($indent)
  605 + {
  606 + for ($i = 1; $i <= $indent; ++$i)
  607 + {
  608 + echo '<td>&nbsp;</td>';
  609 + }
  610 + }
  611 + ?><td colspan="<?php echo 1 + $indent; ?>"><div style="padding: 8px; background-color: lightblue; color: black;"><?php
  612 + echo $child['properties']['name'];
  613 + ?></div></td></tr><?php
  614 + foreach ($child['properties'] as $ckey => $cval)
  615 + {
  616 + if ($cval == '') continue;
  617 + $this->printRow($ckey, $cval, $indent);
  618 + }
  619 +
  620 + if ($child['child'])
  621 + {
  622 + $this->printChild($child['child'], ++$indent);
  623 + }
  624 + }
  625 +}
  626 +?>
0 627 \ No newline at end of file
... ...