3 * The general simulator personell class
5 * @author Roland Haeder <webmaster@ship-simu.org>
7 * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software
8 * @license GNU GPL 3.0 or any newer version
9 * @link http://www.ship-simu.org
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 class SimulatorPersonell extends BasePersonell {
26 private $personellList = null;
29 private $cacheList = null;
31 // A string for cached conditions
32 private $cacheCond = null;
35 * Protected constructor
39 protected function __construct () {
40 // Call parent constructor
41 parent::__construct(__CLASS__);
43 if (((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) && (defined('DEBUG_CONSTRUCT'))) $this->getDebugInstance()->output(sprintf("[%s:] Konstruktor erreicht.<br />\n",
48 $this->setObjectDescription("Simulationspersonal");
51 $this->createUniqueID();
54 $this->removeSystemArray();
58 * Magic wake-up method called when unserialize() is called. This is
59 * neccessary because in this case a personell does not need to know the
60 * min/max ages range and system classes. This would anyway use more RAM
61 * what is not required.
65 public function __wakeup () {
67 $this->removePersonellList();
68 $this->removeMinMaxAge();
70 $this->removeSystemArray();
74 * Generate a specified amount of personell and return the prepared instance
76 * @param $amountPersonell Number of personell we shall
78 * @return $personellInstance An instance of this object with a
81 public final static function createSimulatorPersonell ($amountPersonell) {
82 // Make sure only integer can pass
83 $amountPersonell = (int) $amountPersonell;
86 $personellInstance = new SimulatorPersonell();
89 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $personellInstance->getDebugInstance()->output(sprintf("[%s:%d] Es werden <strong>%d</strong> Personal bereitgestellt.<br />\n",
95 // Initialize the personell list
96 $personellInstance->createPersonellList();
98 // Create requested amount of personell
99 for ($idx = 0; $idx < $amountPersonell; $idx++) {
100 $personellInstance->addRandomPersonell();
104 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $personellInstance->getDebugInstance()->output(sprintf("[%s:%d] <strong>%d</strong> Personal bereitgestellt.<br />\n",
111 $personellInstance->removeGender();
112 $personellInstance->removeNames();
113 $personellInstance->removeBirthday();
114 $personellInstance->removeSalary();
115 $personellInstance->removeEmployed();
116 $personellInstance->removeMarried();
117 $personellInstance->removeNumberFormaters();
118 //$personellInstance->removeCache();
119 $personellInstance->removeSystemArray();
121 // Instanz zurueckgeben
122 return $personellInstance;
126 * Create a SimulatorPersonell object by loading the specified personell
127 * list from an existing database backend
129 * @param $idNumber The ID number (only right part) of the list
130 * @return $personellInstance An instance of
131 * @throws InvalidIDFormatException If the given id number
132 * $idNumber is invalid
133 * @throws NullPointerException If a null pointer (instance)
135 * @throws NoObjectException If a non-object has been
137 * @throws MissingMethodException If a required method is missing
138 * @throws MissingSimulatorIDException If an ID number was not found
140 public final static function createSimulatorPersonellByID ($idNumber) {
141 // Add the class name if it was not found
142 if (count(explode("@", $idNumber)) < 2) {
143 // Add class name in front of the incomplete ID number
144 $tempID = sprintf("%s@%s", __CLASS__, $idNumber);
146 // Use the direct ID number
150 // Validate the ID number
151 if (!preg_match(sprintf("/%s\@([a-f0-9]){32}/i", __CLASS__), $tempID)) {
153 throw new InvalidIDFormatException(new SimulatorPersonell(), self::EXCEPTION_ID_IS_INVALID_FORMAT);
157 $personellInstance = new SimulatorPersonell(false);
159 // Get database instance
160 $dbInstance = $personellInstance->getDatabaseInstance();
162 // Is this a valid database instance?
163 if (is_null($dbInstance)) {
165 throw new NullPointerException($personellInstance, self::EXCEPTION_IS_NULL_POINTER);
166 } elseif (!is_object($dbInstance)) {
167 // Not an object! ;-(
168 throw new NoObjectException($dbInstance, self::EXCEPTION_IS_NO_OBJECT);
169 } elseif (!method_exists($dbInstance, 'isUniqueIdUsed')) {
170 // Required method not found
171 throw new MissingMethodException(array($dbInstance, 'isUniqueIdUsed'), self::EXCEPTION_MISSING_METHOD);
174 // Is the unique ID already used? Then it must be there!
175 if (!$dbInstance->isUniqueIdUsed($tempID)) {
177 throw new MissingSimulatorIDException(array($personellInstance, $idNumber), self::EXCEPTION_SIMULATOR_ID_INVALID);
180 // Load the personell list and add it to this object
181 $personellInstance->loadPersonellList($tempID);
184 $personellInstance->removeGender();
185 $personellInstance->removeNames();
186 $personellInstance->removeBirthday();
187 $personellInstance->removeSalary();
188 $personellInstance->removeEmployed();
189 $personellInstance->removeMarried();
190 $personellInstance->removeNumberFormaters();
191 //$personellInstance->removeCache();
192 $personellInstance->removeSystemArray();
195 return $personellInstance;
198 // Create personell list
199 public function createPersonellList () {
200 if (is_null($this->personellList)) {
201 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Personell-Liste erstellt.<br />\n",
205 $this->personellList = new FrameworkArrayObject();
207 throw new PersonellListAlreadyCreatedException($this, self::EXCEPTION_DIMENSION_ARRAY_INVALID);
211 // Remove the personell list
212 private function removePersonellList () {
213 if (defined('DEBUG_PERSONELL')) $this->getDebugInstance()->output(sprintf("[%s:%d] Personell-Liste entfernt.<br />\n",
217 unset($this->personellList);
220 // Add new personell object to our list
221 public function addRandomPersonell () {
223 $genders = array('M', 'F');
225 // Create new personell members
226 $personellInstance = new SimulatorPersonell();
228 // Set a randomized gender
229 $personellInstance->setGender($genders[mt_rand(0, 1)]);
231 // Set a randomized birthday (maximum age required, see const MAX_AGE)
232 $personellInstance->createBirthday();
234 // Married? Same values means: married
235 if (mt_rand(0, 5) == mt_rand(0, 5)) $personellInstance->setMarried(true);
238 $personellInstance->removePersonellList();
239 $personellInstance->removeMinMaxAge();
240 $personellInstance->removeCache();
241 $personellInstance->removeSystemArray();
243 // Add new member to the list
244 $this->personellList->append($personellInstance);
248 * Get a specifyable list of our people, null or empty string will be ignored!
250 * @return $cacheList A list of cached personells
252 function getSpecialPersonellList ($isEmployed = null, $isMarried = null, $hasGender = "") {
253 // Serialize the conditions for checking if we can take the cache
254 $serialized = serialize(array($isEmployed, $isMarried, $hasGender));
256 // The same (last) conditions?
257 if (($serialized == $this->cacheCond) && (!is_null($this->cacheCond))) {
258 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Gecachte Liste wird verwendet.<br />\n",
263 // Return cached list
264 return $this->cacheList;
267 // Output debug message
268 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Personalliste wird nach Kriterien durchsucht...<br />\n",
273 // Remember the conditions
274 $this->setCacheCond($serialized);
276 // Create cached list
277 $this->setAllCacheList(new FrameworkArrayObject());
279 // Search all unemployed personells
280 for ($idx = $this->personellList->getIterator(); $idx->valid(); $idx->next()) {
282 $el = $idx->current();
284 // Check currenylt all single conditions (combined conditions are not yet supported)
285 if ((!is_null($isEmployed)) && ($el->isEmployed() == $isEmployed)) {
286 // Add this one (employed status asked)
287 $this->cacheList->append($el);
288 } elseif ((!is_null($isMarried)) && ($el->isMarried() == $isMarried)) {
289 // Add this one (marrital status asked)
290 $this->cacheList->append($el);
291 } elseif ((!empty($hasGender)) && ($el->getGender() == $hasGender)) {
292 // Add this one (specified gender)
293 $this->cacheList->append($el);
297 // Return the completed list
298 return $this->cacheList;
302 * Get amount of unemployed personell
304 * @return $count Amount of unemployed personell
306 public final function getAllUnemployed () {
307 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Es werden alle erwerbslosen Personen gesucht.<br />\n",
312 // Get a temporary list
313 $list = $this->getSpecialPersonellList(false);
315 // Anzahl zurueckliefern
316 return $list->count();
320 * Remove cache things
324 private function removeCache () {
325 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Cache-Attribute entfernt.<br />\n",
331 unset($this->cacheList);
332 unset($this->cacheCond);
336 * Setter for cache list
338 * @param $cacheList The new cache list to set or null for initialization/reset
341 private final function setAllCacheList (FrameworkArrayObject $cacheList = null) {
342 $this->cacheList = $cacheList;
346 * Setter for cache conditions
348 * @param $cacheCond The new cache conditions to set
351 private final function setCacheCond ($cacheCond) {
352 $this->cacheCond = (string) $cacheCond;
360 public function resetCache () {
361 if ((defined('DEBUG_PERSONELL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Cache-Liste zurückgesetzt.<br />\n",
365 $this->setAllCacheList(null);
366 $this->setCacheCond("");
370 * Getter for surname. If no surname is set then default surnames are set
371 * for male and female personells.
373 * @return $surname The personell' surname
375 public final function getSurname () {
376 $surname = parent::getSurname();
377 // Make sure every one has a surname...
378 if (empty($surname)) {
379 if ($this->isMale()) {
383 // Typical female name
384 $surname = "Jennifer";
387 // Set typical family name
388 parent::setFamily("Smith");
394 * Saves only the personell list to the database
398 public function saveObjectToDatabase () {
400 $dbInstance = $this->getDatabaseInstance();
402 // Prepare the limitation object. We just need the personellList array object.
403 $limitInstance = ObjectLimits::createObjectLimits(array("personellList"));
405 // Limitate the saving amount
406 $dbInstance->limitObject($limitInstance);
409 $dbInstance->saveObject($this);
413 * Getter for personell list
415 * @return $personellList The list of all personells
417 public final function getPersonellList () {
418 return $this->personellList;
422 * Loads the mostly pre-cached personell list
424 * @param $idNumber The ID number we shall use for looking up
427 * @throws ContainerItemIsNullException If a container item is null
428 * @throws ContainerItemIsNoArrayException If a container item is
430 * @throws ContainerMaybeDamagedException If the container item
431 * is missing the indexes
432 * 'name' and/or 'value'
433 * @see SerializationContainer A special container class which
434 * helps storing only some attributes
437 public function loadPersonellList ($idNumber) {
438 // Get database instance
439 $dbInstance = $this->getDatabaseInstance();
441 // Get the serialization container within the personell list from
442 // the database layer
443 $containerInstance = $dbInstance->getObjectFromCachedData($idNumber);
445 // Iterate through the whole container
446 for ($idx = $containerInstance->getIterator(); $idx->valid(); $idx->next()) {
447 // Get current item from container
448 $item = $idx->current();
451 if (is_null($item)) {
453 throw new ContainerItemIsNullException($this, self::EXCEPTION_CONTAINER_ITEM_IS_NULL);
454 } elseif (!is_array($item)) {
456 throw new ContainerItemIsNoArrayException($this, self::EXCEPTION_ITEM_IS_NO_ARRAY);
457 } elseif ((!isset($item['name'])) || (!isset($item['value']))) {
459 throw new ContainerMaybeDamagedException($this, self::EXCEPTION_CONTAINER_MAYBE_DAMAGED);
462 // Okay, now we can get the item and generate a valid command for eval().
463 // We need to convert the first letter to lower-case but keep all others intact
464 $eval = sprintf("\$this->%s = \$item['value'];",
465 strtolower(substr($item['name'], 0, 1))
467 substr($item['name'], 1)
471 if ((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",