532ca3f394f20ba77f27aa9b075775e16bc188da
[shipsimu.git] / application / ship-simu / main / personell / class_SimulatorPersonell.php
1 <?php
2
3 // Die Schiffsbesatzung
4 class SimulatorPersonell extends BasePersonell {
5         // Personell list
6         private $personellList = null;
7
8         // A cache for lists
9         private $cacheList = null;
10
11         // A string for cached conditions
12         private $cacheCond = null;
13
14         /**
15          * Private constructor
16          *
17          * @return      void
18          */
19         private function __construct () {
20                 // Call parent constructor
21                 parent::constructor(__CLASS__);
22
23                 if (((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) && (defined('DEBUG_CONSTRUCT'))) $this->getDebugInstance()->output(sprintf("[%s:] Konstruktor erreicht.<br />\n",
24                         $this->__toString()
25                 ));
26
27                 // Set description
28                 $this->setPartDescr("Simulationspersonal");
29
30                 // Create unique ID
31                 $this->createUniqueID();
32
33                 // Clean-up a little
34                 $this->removeSystemArray();
35         }
36
37         /**
38          * Magic wake-up method called when unserialize() is called. This is
39          * neccessary because in this case a personell does not need to know the
40          * min/max ages range and system classes. This would anyway use more RAM
41          * what is not required.
42          *
43          * @return      void
44          */
45         public function __wakeup () {
46                 // Tidy up a little
47                 $this->removePersonellList();
48                 $this->removeMinMaxAge();
49                 $this->removeCache();
50                 $this->removeSystemArray();
51         }
52
53         /**
54          * Generate a specified amount of personell and return the prepared instance
55          *
56          * @param               $amountPersonell                Number of personell we shall
57          *                                                              generate
58          * @return      $personellInstance              An instance of this object with a
59          *                                                              list of personells
60          */
61         public static function createSimulatorPersonell ($amountPersonell) {
62                 // Make sure only integer can pass
63                 $amountPersonell = (int) $amountPersonell;
64
65                 // Get a new instance
66                 $personellInstance = new SimulatorPersonell();
67
68                 // Debug message
69                 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $personellInstance->getDebugInstance()->output(sprintf("[%s:%d] Es werden <strong>%d</strong> Personal bereitgestellt.<br />\n",
70                         __CLASS__,
71                         __LINE__,
72                         $amountPersonell
73                 ));
74
75                 // Initialize the personell list
76                 $personellInstance->createPersonellList();
77
78                 // Create requested amount of personell
79                 for ($idx = 0; $idx < $amountPersonell; $idx++) {
80                         $personellInstance->addRandomPersonell();
81                 }
82
83                 // Debug message
84                 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $personellInstance->getDebugInstance()->output(sprintf("[%s:%d] <strong>%d</strong> Personal bereitgestellt.<br />\n",
85                         __CLASS__,
86                         __LINE__,
87                         $amountPersonell
88                 ));
89
90                 // Tidy up a little
91                 $personellInstance->removeGender();
92                 $personellInstance->removeNames();
93                 $personellInstance->removeBirthday();
94                 $personellInstance->removeSalary();
95                 $personellInstance->removeEmployed();
96                 $personellInstance->removeMarried();
97                 $personellInstance->removeNumberFormaters();
98                 //$personellInstance->removeCache();
99                 $personellInstance->removeSystemArray();
100
101                 // Instanz zurueckgeben
102                 return $personellInstance;
103         }
104
105         /**
106          * Create a SimulatorPersonell object by loading the specified personell
107          * list from an existing database backend
108          *
109          * @param               $idNumber               The ID number (only right part) of the list
110          * @return      $personellInstance      An instance of
111          * @throws      InvalidIDFormatException                If the given id number
112          *                                                                      $idNumber is invalid
113          * @throws      NullPointerException            If a null pointer (instance)
114          *                                                                      has been returned.
115          * @throws      NoObjectException                       If a non-object has been
116          *                                                                      returned
117          * @throws      MissingMethodException          If a required method is missing
118          * @throws      MissingSimulatorIDException     If an ID number was not found
119          */
120         public final static function createSimulatorPersonellByID ($idNumber) {
121                 // Add the class name if it was not found
122                 if (count(explode("@", $idNumber)) < 2) {
123                         // Add class name in front of the incomplete ID number
124                         $tempID = sprintf("%s@%s", __CLASS__, $idNumber);
125                 } else {
126                         // Use the direct ID number
127                         $tempID = $idNumber;
128                 }
129
130                 // Validate the ID number
131                 if (!preg_match(sprintf("/%s\@([a-f0-9]){32}/i", __CLASS__), $tempID)) {
132                         // Invalid format
133                         throw new InvalidIDFormatException(new SimulatorPersonell(), self::EXCEPTION_ID_IS_INVALID_FORMAT);
134                 }
135
136                 // Get instance
137                 $personellInstance = new SimulatorPersonell(false);
138
139                 // Get database instance
140                 $dbInstance = $personellInstance->getDatabaseInstance();
141
142                 // Is this a valid database instance?
143                 if (is_null($dbInstance)) {
144                         // No class returned
145                         throw new NullPointerException($personellInstance, self::EXCEPTION_IS_NULL_POINTER);
146                 } elseif (!is_object($dbInstance)) {
147                         // Not an object! ;-(
148                         throw new NoObjectException($dbInstance, self::EXCEPTION_IS_NO_OBJECT);
149                 } elseif (!method_exists($dbInstance, 'isUniqueIdUsed')) {
150                         // Required method not found
151                         throw new MissingMethodException(array($dbInstance, 'isUniqueIdUsed'), self::EXCEPTION_MISSING_METHOD);
152                 }
153
154                 // Is the unique ID already used? Then it must be there!
155                 if (!$dbInstance->isUniqueIdUsed($tempID))  {
156                         // Entry not found!
157                         throw new MissingSimulatorIDException(array($personellInstance, $idNumber), self::EXCEPTION_SIMULATOR_ID_INVALID);
158                 }
159
160                 // Load the personell list and add it to this object
161                 $personellInstance->loadPersonellList($tempID);
162
163                 // Clean-up a little
164                 $personellInstance->removeGender();
165                 $personellInstance->removeNames();
166                 $personellInstance->removeBirthday();
167                 $personellInstance->removeSalary();
168                 $personellInstance->removeEmployed();
169                 $personellInstance->removeMarried();
170                 $personellInstance->removeNumberFormaters();
171                 //$personellInstance->removeCache();
172                 $personellInstance->removeSystemArray();
173
174                 // Return instance
175                 return $personellInstance;
176         }
177
178         // Create personell list
179         public function createPersonellList () {
180                 if (is_null($this->personellList)) {
181                         if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Personell-Liste erstellt.<br />\n",
182                                 __CLASS__,
183                                 __LINE__
184                         ));
185                         $this->personellList = new FrameworkArrayObject();
186                 } else {
187                         throw new PersonellListAlreadyCreatedException($this, self::EXCEPTION_DIMENSION_ARRAY_INVALID);
188                 }
189         }
190
191         // Remove the personell list
192         private function removePersonellList () {
193                 if (defined('DEBUG_PERSONELL')) $this->getDebugInstance()->output(sprintf("[%s:%d] Personell-Liste entfernt.<br />\n",
194                         __CLASS__,
195                         __LINE__
196                 ));
197                 unset($this->personellList);
198         }
199
200         // Add new personell object to our list
201         public function addRandomPersonell () {
202                 // Gender list...
203                 $genders = array('M', 'F');
204
205                 // Create new personell members
206                 $personellInstance = new SimulatorPersonell();
207
208                 // Set a randomized gender
209                 $personellInstance->setGender($genders[mt_rand(0, 1)]);
210
211                 // Set a randomized birthday (maximum age required, see const MAX_AGE)
212                 $personellInstance->createBirthday();
213
214                 // Married? Same values means: married
215                 if (mt_rand(0, 5) == mt_rand(0, 5)) $personellInstance->setMarried(true);
216
217                 // Tidy up a little
218                 $personellInstance->removePersonellList();
219                 $personellInstance->removeMinMaxAge();
220                 $personellInstance->removeCache();
221                 $personellInstance->removeSystemArray();
222
223                 // Add new member to the list
224                 $this->personellList->append($personellInstance);
225         }
226
227         /**
228          * Get a specifyable list of our people, null or empty string will be ignored!
229          *
230          * @return      $cacheList      A list of cached personells
231          */
232         function getSpecialPersonellList ($isEmployed = null, $isMarried = null, $hasGender = "") {
233                 // Serialize the conditions for checking if we can take the cache
234                 $serialized = serialize(array($isEmployed, $isMarried, $hasGender));
235
236                 // The same (last) conditions?
237                 if (($serialized == $this->cacheCond) && (!is_null($this->cacheCond))) {
238                         if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Gecachte Liste wird verwendet.<br />\n",
239                                 __CLASS__,
240                                 __LINE__
241                         ));
242
243                         // Return cached list
244                         return $this->cacheList;
245                 }
246
247                 // Output debug message
248                 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Personalliste wird nach Kriterien durchsucht...<br />\n",
249                         __CLASS__,
250                         __LINE__
251                 ));
252
253                 // Remember the conditions
254                 $this->setCacheCond($serialized);
255
256                 // Create cached list
257                 $this->setAllCacheList(new FrameworkArrayObject());
258
259                 // Search all unemployed personells
260                 for ($idx = $this->personellList->getIterator(); $idx->valid(); $idx->next()) {
261                         // Element holen
262                         $el = $idx->current();
263
264                         // Check currenylt all single conditions (combined conditions are not yet supported)
265                         if ((!is_null($isEmployed)) && ($el->isEmployed() == $isEmployed)) {
266                                 // Add this one (employed status asked)
267                                 $this->cacheList->append($el);
268                         } elseif ((!is_null($isMarried)) && ($el->isMarried() == $isMarried)) {
269                                 // Add this one (marrital status asked)
270                                 $this->cacheList->append($el);
271                         } elseif ((!empty($hasGender)) && ($el->getGender() == $hasGender)) {
272                                 // Add this one (specified gender)
273                                 $this->cacheList->append($el);
274                         }
275                 }
276
277                 // Return the completed list
278                 return $this->cacheList;
279         }
280
281         /**
282          * Get amount of unemployed personell
283          *
284          * @return      $count  Amount of unemployed personell
285          */
286         public final function getAllUnemployed () {
287                 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Es werden alle erwerbslosen Personen gesucht.<br />\n",
288                         __CLASS__,
289                         __LINE__
290                 ));
291
292                 // Get a temporary list
293                 $list = $this->getSpecialPersonellList(false);
294
295                 // Anzahl zurueckliefern
296                 return $list->count();
297         }
298
299         /**
300          * Remove cache things
301          *
302          * @return      void
303          */
304         private function removeCache () {
305                 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Cache-Attribute entfernt.<br />\n",
306                         __CLASS__,
307                         __LINE__
308                 ));
309
310                 // Remove cache data
311                 unset($this->cacheList);
312                 unset($this->cacheCond);
313         }
314
315         /**
316          * Setter for cache list
317          *
318          * @param               $cacheList      The new cache list to set or null for initialization/reset
319          * @return      void
320          */
321         private function setAllCacheList (FrameworkArrayObject $cacheList = null) {
322                 $this->cacheList = $cacheList;
323         }
324
325         /**
326          * Setter for cache conditions
327          *
328          * @param               $cacheCond      The new cache conditions to set
329          * @return      void
330          */
331         private function setCacheCond ($cacheCond) {
332                 $this->cacheCond = (string) $cacheCond;
333         }
334
335         /**
336          * Reset cache list
337          *
338          * @return      void
339          */
340         public function resetCache () {
341                 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Cache-Liste zur&uuml;ckgesetzt.<br />\n",
342                         __CLASS__,
343                         __LINE__
344                 ));
345                 $this->setAllCacheList(null);
346                 $this->setCacheCond("");
347         }
348
349         /**
350          * Getter for surname. If no surname is set then default surnames are set
351          * for male and female personells.
352          *
353          * @return      $surname                The personell' surname
354          */
355         public final function getSurname () {
356                 $surname = parent::getSurname();
357                 // Make sure every one has a surname...
358                 if (empty($surname)) {
359                         if ($this->isMale()) {
360                                 // Typical male name
361                                 $surname = "John";
362                         } else {
363                                 // Typical female name
364                                 $surname = "Jennifer";
365                         }
366
367                         // Set typical family name
368                         parent::setFamily("Smith");
369                 }
370                 return $surname;
371         }
372
373         /**
374          * Saves only the personell list to the database
375          *
376          * @return      void
377          */
378         public function saveObjectToDatabase () {
379                 // Get the database
380                 $dbInstance = $this->getDatabaseInstance();
381
382                 // Prepare the limitation object. We just need the personellList array object.
383                 $limitInstance = ObjectLimits::createObjectLimits(array("personellList"));
384
385                 // Limitate the saving amount
386                 $dbInstance->limitObject($limitInstance);
387
388                 // Save this object
389                 $dbInstance->saveObject($this);
390         }
391
392         /**
393          * Getter for personell list
394          *
395          * @return      $personellList          The list of all personells
396          */
397         public final function getPersonellList () {
398                 return $this->personellList;
399         }
400
401         /**
402          * Loads the mostly pre-cached personell list
403          *
404          * @param               $idNumber               The ID number we shall use for looking up
405          *                                              the right data.
406          * @return      void
407          * @throws      ContainerItemIsNullException    If a container item is null
408          * @throws      ContainerItemIsNoArrayException If a container item is
409          *                                                                              not an array
410          * @throws      ContainerMaybeDamagedException  If the container item
411          *                                                                              is missing the indexes
412          *                                                                              'name' and/or 'value'
413          * @see         SerializationContainer  A special container class which
414          *                                                              helps storing only some attributes
415          *                                                              of a class.
416          */
417         public function loadPersonellList ($idNumber) {
418                 // Get database instance
419                 $dbInstance = $this->getDatabaseInstance();
420
421                 // Get the serialization container within the  personell list from
422                 // the database layer
423                 $containerInstance = $dbInstance->getObjectFromCachedData($idNumber);
424
425                 // Iterate through the whole container
426                 for ($idx = $containerInstance->getIterator(); $idx->valid(); $idx->next()) {
427                         // Get current item from container
428                         $item = $idx->current();
429
430                         // Validate it a bit
431                         if (is_null($item)) {
432                                 // Is null
433                                 throw new ContainerItemIsNullException($this, self::EXCEPTION_CONTAINER_ITEM_IS_NULL);
434                         } elseif (!is_array($item)) {
435                                 // Is not an array
436                                 throw new ContainerItemIsNoArrayException($this, self::EXCEPTION_ITEM_IS_NO_ARRAY);
437                         } elseif ((!isset($item['name'])) || (!isset($item['value']))) {
438                                 // Missing elements
439                                 throw new ContainerMaybeDamagedException($this, self::EXCEPTION_CONTAINER_MAYBE_DAMAGED);
440                         }
441
442                         // Okay, now we can get the item and generate a valid command for eval().
443                         // We need to convert the first letter to lower-case but keep all others intact
444                         $eval = sprintf("\$this->%s = \$item['value'];",
445                                 strtolower(substr($item['name'], 0, 1))
446                                 .
447                                 substr($item['name'], 1)
448                         );
449
450                         // Debug message
451                         if ((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
452                                 __CLASS__,
453                                 __LINE__,
454                                 htmlentities($eval)
455                         ));
456
457                         // Run the command
458                         @eval($eval);
459                 }
460         }
461 }
462
463 // [EOF]
464 ?>