data.generator.class.inc.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <?php
  2. /**
  3. * data generator
  4. * helps the consultants in creating dummy data sets, for various test purposes (validation, usability, scalability)
  5. *
  6. * @package tbd
  7. * @author Romain Quetiez <romainquetiez@yahoo.fr>
  8. * @author Denis Flaven <denisflave@free.fr>
  9. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
  10. * @link www.itop.com
  11. * @since 1.0
  12. * @version 1.1.1.1 $
  13. */
  14. /**
  15. * Data Generator helper class
  16. *
  17. * This class is useful to generate a lot of sample data that look consistent
  18. * for a given organization in order to simulate a real CMDB
  19. */
  20. class cmdbDataGenerator
  21. {
  22. protected $m_sOrganizationKey;
  23. protected $m_sOrganizationCode;
  24. protected $m_sOrganizationName;
  25. protected $m_OrganizationDomains;
  26. /**
  27. * Constructor
  28. */
  29. public function __construct($sOrganizationId = "")
  30. {
  31. global $aCompanies, $aCompaniesCode;
  32. if ($sOrganizationId == '')
  33. {
  34. // No organization provided, pick a random and unused one from our predefined list
  35. $retries = 5*count($aCompanies);
  36. while ( ($retries > 0) && !isset($this->m_sOrganizationCode)) // Stupid algorithm, but I'm too lazy to do something bulletproof tonight
  37. {
  38. $index = rand(0, count($aCompanies) - 1);
  39. if (!$this->OrganizationExists($aCompanies[$index]['code']))
  40. {
  41. $this->m_sOrganizationCode = $aCompanies[$index]['code'];
  42. $this->m_sOrganizationName = $aCompanies[$index]['name'];
  43. $this->m_OrganizationDomains = $aCompanies[$index]['domain'];
  44. }
  45. $retries--;
  46. }
  47. }
  48. else
  49. {
  50. // A code has been provided, let's take the information we need from the organization itself
  51. $this->m_sOrganizationId = $sOrganizationId;
  52. $oOrg = $this->GetOrganization($sOrganizationId);
  53. if ($oOrg == null)
  54. {
  55. echo "Unable to find the organization '$sOrganisationCode' in the database... can not add objects into this organization.<br/>\n";
  56. exit();
  57. }
  58. $this->m_sOrganizationCode = $oOrg->Get('code');
  59. $this->m_sOrganizationName = $oOrg->Get('name');
  60. if (!isset($aCompaniesCode[$this->m_sOrganizationCode]['domain']))
  61. {
  62. // Generate some probable domain names for this organization
  63. $this->m_OrganizationDomains = array(strtolower($this->m_sOrganizationCode).".com", strtolower($this->m_sOrganizationCode).".org", strtolower($this->m_sOrganizationCode)."corp.net",);
  64. }
  65. else
  66. {
  67. // Pick the domain names for this organization from the predefined list
  68. $this->m_OrganizationDomains = $aCompaniesCode[$this->m_sOrganizationCode]['domain'];
  69. }
  70. }
  71. if (!isset($this->m_sOrganizationCode))
  72. {
  73. echo "Unable to find an organization code which is not already used... can not create a new organization. Enhance the list of fake organizations (\$aCompanies in data_sample.inc.php).<br/>\n";
  74. exit();
  75. }
  76. }
  77. /**
  78. * Get the current organization id used by the generator
  79. *
  80. * @return string The organization id
  81. */
  82. public function GetOrganizationId()
  83. {
  84. return $this->m_sOrganizationId;
  85. }
  86. /**
  87. * Get the current organization id used by the generator
  88. *
  89. * @param string The organization id
  90. * @return none
  91. */
  92. public function SetOrganizationId($sId)
  93. {
  94. $this->m_sOrganizationId = $sId;
  95. }
  96. /**
  97. * Get the current organization code used by the generator
  98. *
  99. * @return string The organization code
  100. */
  101. public function GetOrganizationCode()
  102. {
  103. return $this->m_sOrganizationCode;
  104. }
  105. /**
  106. * Get the current organization name used by the generator
  107. *
  108. * @return string The organization name
  109. */
  110. function GetOrganizationName()
  111. {
  112. return $this->m_sOrganizationName;
  113. }
  114. /**
  115. * Get a pseudo random first name taken from a (big) prefedined list
  116. *
  117. * @return string A random first name
  118. */
  119. function GenerateFirstName()
  120. {
  121. global $aFirstNames;
  122. return $aFirstNames[rand(0, count($aFirstNames) - 1)];
  123. }
  124. /**
  125. * Get a pseudo random last name taken from a (big) prefedined list
  126. *
  127. * @return string A random last name
  128. */
  129. function GenerateLastName()
  130. {
  131. global $aNames;
  132. return $aNames[rand(0, count($aNames) - 1)];
  133. }
  134. /**
  135. * Get a pseudo random country name taken from a prefedined list
  136. *
  137. * @return string A random city name
  138. */
  139. function GenerateCountryName()
  140. {
  141. global $aCountries;
  142. return $aCountries[rand(0, count($aCountries) - 1)];
  143. }
  144. /**
  145. * Get a pseudo random city name taken from a (big) prefedined list
  146. *
  147. * @return string A random city name
  148. */
  149. function GenerateCityName()
  150. {
  151. global $aCities;
  152. return $aCities[rand(0, count($aCities) - 1)];
  153. }
  154. /**
  155. * Get a pseudo random email address made of the first name, last name and organization's domain
  156. *
  157. * @return string A random email address
  158. */
  159. function GenerateEmail($sFirstName, $sLastName)
  160. {
  161. if (rand(1, 20) > 18)
  162. {
  163. // some people (let's say 5~10%) have an irregular email address
  164. $sEmail = strtolower($this->CleanForEmail($sLastName))."@".strtolower($this->GenerateDomain());
  165. }
  166. else
  167. {
  168. $sEmail = strtolower($this->CleanForEmail($sFirstName)).".".strtolower($this->CleanForEmail($sLastName))."@".strtolower($this->GenerateDomain());
  169. }
  170. return $sEmail;
  171. }
  172. /**
  173. * Generate (pseudo) random strings that follow a given pattern
  174. *
  175. * The template is made of any number of 'parts' separated by pipes '|'
  176. * Each part is either:
  177. * - domain() => returns a domain name for the current organization
  178. * - enum(aaa,bb,c,dddd) => returns randomly one of aaa,bb,c or dddd with the same
  179. * probability of occurence. If you want to change the probability you can repeat some values
  180. * i.e enum(most probable,most probable,most probable,most probable,most probable,rare)
  181. * - number(xxx-yyy) => a random number between xxx and yyy (bounds included)
  182. * note that if the first number (xxx) begins with a zero, then the result will zero padded
  183. * to the same number of digits as xxx.
  184. * All other 'part' that does not follow one of the above mentioned pattern is returned as is
  185. *
  186. * Example: GenerateString("enum(sw,rtr,gw)|number(00-99)|.|domain()")
  187. * will produce strings like "sw01.netcmdb.com" or "rtr45.itop.org"
  188. *
  189. * @param string $sTemplate The template used for generating the string
  190. * @return string The generated pseudo random the string
  191. */
  192. function GenerateString($sTemplate)
  193. {
  194. $sResult = "";
  195. $aParts = split("\|", $sTemplate);
  196. foreach($aParts as $sPart)
  197. {
  198. if (preg_match("/domain\(\)/", $sPart, $aMatches))
  199. {
  200. $sResult .= strtolower($this->GenerateDomain());
  201. }
  202. elseif (preg_match("/enum\((.+)\)/", $sPart, $aMatches))
  203. {
  204. $sEnumValues = $aMatches[1];
  205. $aEnumValues = split(",", $sEnumValues);
  206. $sResult .= $aEnumValues[rand(0, count($aEnumValues) - 1)];
  207. }
  208. elseif (preg_match("/number\((\d+)-(\d+)\)/", $sPart, $aMatches))
  209. {
  210. $sStartNumber = $aMatches[1];
  211. if ($sStartNumber[0] == '0')
  212. {
  213. // number must be zero padded
  214. $sFormat = "%0".strlen($sStartNumber)."d";
  215. }
  216. else
  217. {
  218. $sFormat = "%d";
  219. }
  220. $sEndNumber = $aMatches[2];
  221. $sResult .= sprintf($sFormat, rand($sStartNumber, $sEndNumber));
  222. }
  223. else
  224. {
  225. $sResult .= $sPart;
  226. }
  227. }
  228. return $sResult;
  229. }
  230. /**
  231. * Generate a foreign key by picking a random element of the given class in a set limited by the given search criteria
  232. *
  233. * Example: GenerateKey("bizLocation", array('org_id', $oGenerator->GetOrganizationId());
  234. * will produce the foreign key of a Location object picked at random in the same organization
  235. *
  236. * @param string $sClass The name of the class to search for
  237. * @param string $aFilterCriteria A hash array of filterCOde => FilterValue (the strict operator '=' is used )
  238. * @return mixed The key to an object of the given class, or null if none are found
  239. */
  240. function GenerateKey($sClass, $aFilterCriteria)
  241. {
  242. $retKey = null;
  243. $oFilter = new CMDBSearchFilter($sClass);
  244. foreach($aFilterCriteria as $sFilterCode => $filterValue)
  245. {
  246. $oFilter->AddCondition($sFilterCode, $filterValue, '=');
  247. }
  248. $oSet = new CMDBObjectSet($oFilter);
  249. if ($oSet->Count() > 0)
  250. {
  251. $max_count = $index = rand(1, $oSet->Count());
  252. do
  253. {
  254. $oObj = $oSet->Fetch();
  255. $index--;
  256. }
  257. while($index > 0);
  258. if (!is_object($oObj))
  259. {
  260. echo "<pre>";
  261. echo "ERROR: non empty set, but invalid object picked! class='$sClass'\n";
  262. echo "Index chosen: $max_count\n";
  263. echo "The set is supposed to contain ".$oSet->Count()." object(s)\n";
  264. echo "Filter criteria:\n";
  265. print_r($aFilterCriteria);
  266. echo "</pre>";
  267. }
  268. else
  269. {
  270. $retKey = $oObj->GetKey();
  271. }
  272. }
  273. return $retKey;
  274. }
  275. ///////////////////////////////////////////////////////////////////////////////
  276. //
  277. // Protected methods
  278. //
  279. ///////////////////////////////////////////////////////////////////////////////
  280. /**
  281. * Generate a (random) domain name consistent with the organization name & code
  282. *
  283. * The values are pulled from a (limited) predefined list. Note that a given
  284. * organization may have several domain names, so the result may be random
  285. *
  286. * @return string A domain name (like netcnmdb.com)
  287. */
  288. protected function GenerateDomain()
  289. {
  290. if (is_array($this->m_OrganizationDomains))
  291. {
  292. $sDomain = $this->m_OrganizationDomains[rand(0, count($this->m_OrganizationDomains)-1)];
  293. }
  294. else
  295. {
  296. $sDomain = $this->m_OrganizationDomains;
  297. }
  298. return $sDomain;
  299. }
  300. /**
  301. * Strips accented characters from a string in order to produce a suitable email address
  302. *
  303. * @param string The text string to clean
  304. * @return string The cleanified text string
  305. */
  306. protected function CleanForEmail($sText)
  307. {
  308. return str_replace(array("'", "é", "è", "ê", "ç", "à", "â", "ñ", "ö", "ä"), array("", "e", "e", "e", "c", "a", "a", "n", "oe", "ae"), $sText);
  309. }
  310. /**
  311. * Check if an organization with the given code already exists in the database
  312. *
  313. * @param string $sCode The code to look for
  314. * @return boolean true if the given organization exists, false otherwise
  315. */
  316. protected function OrganizationExists($sCode)
  317. {
  318. $oFilter = new CMDBSearchFilter('bizOrganization');
  319. $oFilter->AddCondition('code', $sCode, '=');
  320. $oSet = new CMDBObjectSet($oFilter);
  321. return ($oSet->Count() > 0);
  322. }
  323. /**
  324. * Search for an organization with the given code in the database
  325. *
  326. * @param string $Id The organization Id to look for
  327. * @return cmdbOrganization the organization if it exists, null otherwise
  328. */
  329. protected function GetOrganization($sId)
  330. {
  331. $oOrg = null;
  332. $oFilter = new CMDBSearchFilter('bizOrganization');
  333. $oFilter->AddCondition('pkey', $sId, '=');
  334. $oSet = new CMDBObjectSet($oFilter);
  335. if ($oSet->Count() > 0)
  336. {
  337. $oOrg = $oSet->Fetch(); // Let's take the first one found
  338. }
  339. return $oOrg;
  340. }
  341. }
  342. ?>