function CACF_CreateFolderAuditDataAndWriteToCsv(&$db, &$CACFconstants, &$altiumUserNamesByGuid, &$altiumFoldersByGuid, &$altiumFolderUserParmValuesByGuid, &$altiumUserParmNames, &$altiumAclDataByObjectGuid) { /* Retrieve necessary global constants. */ $ofs = $CACFconstants["ofs"]; $constNamingScheme = $CACFconstants["constNamingScheme"]; $constAbsent = $CACFconstants["constAbsent"]; $auditFoldersFileName = $CACFconstants["auditFoldersFileName"]; /** Modify $altiumUserParmNames to add one FOLDER level special parameter string. **/ /* WARNING: Do not move this code block above the audit components operation located above here! */ $altiumUserParmNames[$constNamingScheme] = 1; /* Re-sort all Altium user parameter names stored in the array, by array key. */ $rc = ksort($altiumUserParmNames); if ($rc == FALSE) { my_die("ksort() failed!"); } /** Open audit folders file for writing. **/ $auditFoldersFile = my_fopen($auditFoldersFileName); /** Output column headers. **/ $line = ""; $line = $line . "FOLDERGUID" . $ofs . "DESCRIPTION" . $ofs . "FOLDERTYPE" . $ofs . "FOLDERPATH" . $ofs . "CREATEDBY" . $ofs . "CREATEDAT" . $ofs . "LASTMODIFIEDBY" . $ofs . "LASTMODIFIEDAT"; /* Get a random array slice to know what fields exist. */ $slice = array_slice($altiumAclDataByObjectGuid, 0, 1); //echo "slice is:\n"; //print_r($slice); /* Output an ordered list of all the permission fields that exist. */ foreach ($slice as $key => $value) { foreach ($slice[$key] as $PERMNAME => $value2) { /* Output $PERMNAME. */ $line = $line . $ofs . $PERMNAME; } /* end foreach */ } /* end foreach */ /* Output an ordered list of all the Altium user parameters that exist in our universe as columns in the csv file. */ foreach ($altiumUserParmNames as $PARAMETERNAME => $value) { /* Output $PARAMETERNAME. */ $line = $line . $ofs . $PARAMETERNAME; } /* end foreach */ // echo "altiumAclDataByObjectGuid is:\n"; // print_r($altiumAclDataByObjectGuid); /* Write line to file. Note: explicitly use DOS (CR/LF) \r\n line endings! */ fputs($auditFoldersFile, $line . "\r\n"); /** Create array to temporarily hold all lines that we generate, since we need to sort before writing to file. **/ $auditFoldersLines = array(); /* Setup query SQL commands. */ $queryText = ' SELECT FOLDER.GUID AS FOLDERGUID, FOLDER.HRID, FOLDER.CREATEDBYGUID, FOLDER.LASTMODIFIEDBYGUID, FOLDER.CREATEDAT, FOLDER.LASTMODIFIEDAT, FOLDER.PARENTFOLDERGUID, FOLDER.DESCRIPTION, FT.HRID AS FOLDERTYPE FROM ALU_FOLDER FOLDER LEFT JOIN ALU_FOLDERTYPE FT ON FOLDER.FOLDERTYPEGUID = FT.GUID ; '; echo date('H:i:s') . " Begin query to read in all folder info from Vault database...\n"; /* Execute SQL query. */ $resultHandle = odbc_exec($db, $queryText); /* Loop over all rows returned by SQL query. */ while (odbc_fetch_row($resultHandle)) { /* Extract the fields of interest from this query result. */ $FOLDERGUID = odbc_result($resultHandle, "FOLDERGUID"); $DESCRIPTION = odbc_result($resultHandle, "DESCRIPTION"); $FOLDERTYPE = odbc_result($resultHandle, "FOLDERTYPE"); $CREATEDBYGUID = odbc_result($resultHandle, "CREATEDBYGUID"); $LASTMODIFIEDBYGUID = odbc_result($resultHandle, "LASTMODIFIEDBYGUID"); $CREATEDAT = odbc_result($resultHandle, "CREATEDAT"); $LASTMODIFIEDAT = odbc_result($resultHandle, "LASTMODIFIEDAT"); /* Lookup the usernames of the person to create and last modify this folder. */ $CREATEDBY = CACF_LookupUsername($altiumUserNamesByGuid, $CREATEDBYGUID); $LASTMODIFIEDBY = CACF_LookupUsername($altiumUserNamesByGuid, $LASTMODIFIEDBYGUID); /* Lookup the full path of this folder, based on cached data from having already read in this table once already. */ $FOLDERPATH = CACF_TraceFolderPath($CACFconstants, $altiumFoldersByGuid, $FOLDERGUID); /** Output actual data. **/ $line = ""; $line = $line . "{$FOLDERGUID}" . $ofs . "{$DESCRIPTION}" . $ofs . "{$FOLDERTYPE}" . $ofs . "{$FOLDERPATH}" . $ofs . "{$CREATEDBY}" . $ofs . "{$CREATEDAT}" . $ofs . "{$LASTMODIFIEDBY}" . $ofs . "{$LASTMODIFIEDAT}"; /** Output an ordered list of all the Altium user parameters that exist in our universe as columns in the csv file. If this part has a given parameter, list its value. **/ /* Get all the permission fields that exist for this folder. */ foreach ($altiumAclDataByObjectGuid[$FOLDERGUID] as $PERMNAME => $PERMVALUE) { /* Output $PERMVALUE. */ $line = $line . $ofs . $PERMVALUE; } /* end foreach */ /* Loop over all the defined Altium user parameter names. */ foreach ($altiumUserParmNames as $PARAMETERNAME => $value) { /* Unconditionally print out a field separator. */ $line = $line . $ofs; /* If this component has a stored folder user parameter named $PARAMETERNAME, then output it. */ if (isset($altiumFolderUserParmValuesByGuid[$FOLDERGUID][$PARAMETERNAME])) { $line = $line . $altiumFolderUserParmValuesByGuid[$FOLDERGUID][$PARAMETERNAME]; } else { $line = $line . $constAbsent; } } /* end foreach */ /* Store this line in an in-memory array, so we can sort it all just before writing to disk. */ $auditFoldersLines[$FOLDERPATH] = $line; } /* endwhile */ /* Free memory that was holding query results. */ odbc_free_result($resultHandle); /* Sort all output lines here by folder path (key). */ $rc = ksort($auditFoldersLines); if ($rc == FALSE) { my_die("ksort() failed!"); } /* Loop over all lines in what will be our output file. */ foreach ($auditFoldersLines as $key => $line) { /* Write line to file. Note: explicitly use DOS (CR/LF) \r\n line endings! */ fputs($auditFoldersFile, $line . "\r\n"); } /* endforeach */ /** Clear array that held all lines prior to writing to file. **/ $auditFoldersLines = array(); /** Close the audit output file. **/ fclose($auditFoldersFile); echo date('H:i:s') . " Done writing audit folders file \"{$auditFoldersFileName}.\"\n"; }
function UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib(&$CACFconstants, &$UCTCFconstants, &$altiumFoldersByGuid, $path, $xpath, &$xmlNode, &$cmpLibGroupXpathByPath, &$cmpLibCompByItemHrid) { /* Retrieve necessary global constants. */ $pathSep = $CACFconstants["pathSep"]; // echo "Hello world from UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib().\n"; // echo "\nIn UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib(), xmlNode is:\n"; // print_r($xmlNode); /* Retrieve name of this node. */ $name = $xmlNode->getName(); /* Update xpath with name of this node. */ $xpath = $xpath . "/{$name}"; // echo "In UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib(), xpath is now \"$xpath\".\n"; // echo "In node \"$name\", count is " . $xmlNode->count() . "!\n"; /* Handle the base case where we're given a path of "". */ /* Look up the GUID of the initial path element in database to get starting path. */ if ($path == "") { /* Make sure we have the root path element's GUID field. */ if (!isset($xmlNode->GUID)) { my_die('In UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib(), could not find GUID for root path element!'); } /* Extract GUID field. */ $GUID = (string) $xmlNode->GUID; // echo "GUID is \"$GUID\".\n"; /* Lookup folder path for this starting point. */ $path = CACF_TraceFolderPath($CACFconstants, $altiumFoldersByGuid, $GUID); // echo "In UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib(), base path is \"".$path."\".\n"; /* Store xpath query corresponding to this (database) path. */ $cmpLibGroupXpathByPath[$path] = $xpath; // echo "In UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib(), for group path \"$path\", stored xpath \"$xpath\".\n"; } else { if ($name == "TGroup") { /* Make sure we have the group's HRID field. */ if (!isset($xmlNode->HRID)) { my_die('In UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib(), could not find HRID for TGroup!'); } /* Attempt to extract new path element (TGroup's HRID field). */ $HRID = (string) $xmlNode->HRID; /* Add new element to path. */ $path = $path . $HRID . $pathSep; // echo "In UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib(), path is \"".$path."\".\n"; /* Retrieve the ID of this group. */ $groupId = (string) $xmlNode['id']; /* Add a query to our xpath to disambiguate it from other peer groups. */ $xpath = $xpath . "[@id=\"{$groupId}\"]"; // echo "xpath is \"$xpath\".\n"; /* Store xpath query corresponding to this (database) path. */ $cmpLibGroupXpathByPath[$path] = $xpath; // echo "In UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib(), for group path \"$path\", stored xpath \"$xpath\".\n"; } else { if ($name == "TComponentDefinition") { /* Make sure we have the component's ItemHRID field. */ if (!isset($xmlNode->ItemHRID)) { my_die('In UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib(), could not find ItemHRID for TComponentDefinition!'); } /* Attempt to extract component's ItemHRID field). */ $ItemHRID = (string) $xmlNode->ItemHRID; /* Add a query to our xpath to disambiguate it from other peer components. */ $xpath = $xpath . "[ItemHRID=\"{$ItemHRID}\"]"; // echo "Component xpath is \"$xpath\".\n"; /* Store path and xpath query corresponding to this component (by component ItemHrid). */ $cmpLibCompByItemHrid[$ItemHRID] = array(); $cmpLibCompByItemHrid[$ItemHRID]["path"] = $path; $cmpLibCompByItemHrid[$ItemHRID]["xpath"] = $xpath; // echo "In UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib(), for component ItemHrid \"$ItemHRID\", stored xpath \"$xpath\".\n"; } } } /* end elsif */ /** Recurse into child nodes to find any TGroups or TComponentDefinitions. **/ /* See if this XML node has any children. */ if ($xmlNode->count() > 0) { /* Attempt to loop over all child nodes. */ foreach ($xmlNode->children() as $childNode) { // echo "Recursing from node \"$name\"!\n"; /* Recursively call this function. */ $xmlNode =& $childNode; UCTCF_ExtractGroupsAndComponentsByXpathFromCmpLib($CACFconstants, $UCTCFconstants, $altiumFoldersByGuid, $path, $xpath, $xmlNode, $cmpLibGroupXpathByPath, $cmpLibCompByItemHrid); } /* end foreach */ } /* endif node has children. */ }