/**
  * Gets all elements by type from database
  * @param string $elementClass The element type searched
  * @param string $conditions The conditions string to apply (ex : Region.x < 10 AND World.size = 500)
  * @param string $orderBy The order string to apply (ex : 'Region.x, City.name DESC')
  * @param string $join the joined tables
  * @return array The element list
  */
 public static function getElementList($elementClass, $conditions = NULL, $orderBy = NULL, $join = NULL)
 {
     $tableName = DatabaseFactory::getElementTableName($elementClass);
     if ($join !== NULL) {
         list($select, $from, $joinTableNameList, $joinTableAttachements) = DatabaseFactory::getJoin($tableName, $join);
         $request = 'SELECT ' . $select . $from;
     } else {
         $request = 'SELECT * FROM ' . $tableName;
     }
     if ($conditions !== NULL) {
         $request .= ' WHERE ' . $conditions;
     }
     if ($orderBy !== NULL) {
         $request .= ' ORDER BY ' . $orderBy;
     }
     $databaseConnection = $elementClass::getDatabaseConnection();
     // For join requests, needs to fetch results by index (to handle several fields with same name)
     if ($join === NULL) {
         // Execute request on database
         $resultType = MysqlDatabaseConnectionModel::ARRAY_TYPE_ASSOC;
         $resultList = $databaseConnection->selectRequest($request, $resultType, false, false);
     } else {
         // Gets field list with resut to get them for joined tables
         $resultType = MysqlDatabaseConnectionModel::ARRAY_TYPE_NUM;
         list($resultList, $fieldNameList) = $databaseConnection->selectRequest($request, $resultType, TRUE, FALSE);
         // Builds main element field list
         $fieldIndex = 0;
         $fieldNumber = count($fieldNameList);
         $elementFieldNameList = array();
         while ($fieldIndex < $fieldNumber) {
             $fieldName = $fieldNameList[$fieldIndex++];
             if (StringTool::endsWith($fieldName, DatabaseFactory::JOIN_TABLE_FIELD_SEPARATOR)) {
                 break;
             }
             $elementFieldNameList[$tableName][] = $fieldName;
         }
         // Builds joined elements field list
         foreach ($joinTableNameList as &$joinTableName) {
             while ($fieldIndex < $fieldNumber) {
                 $fieldName = $fieldNameList[$fieldIndex++];
                 if (StringTool::endsWith($fieldName, DatabaseFactory::JOIN_TABLE_FIELD_SEPARATOR)) {
                     break;
                 }
                 $elementFieldNameList[$joinTableName][] = $fieldName;
             }
         }
     }
     // Constructs typed elements from results
     $elementList = array();
     $retrievedElementList = array();
     while ($result = MysqlDatabaseConnectionModel::fetch_array($resultList, $resultType)) {
         $rowElementList = array();
         if ($join === NULL) {
             // Sets element
             $element = Element::getElementFromArray($elementClass, $result);
             $element->setId();
             $elementList[$element->id] = $element;
         } else {
             // Additionnal tables requested
             $fieldIndex = 0;
             $fieldValues = array_values($result);
             $rowElementList = array();
             // Sets elements attributes for each table on the row
             foreach ($elementFieldNameList as $elementTableName => $fieldNameList) {
                 $elementAttributeList = array();
                 foreach ($fieldNameList as $fieldName) {
                     $elementAttributeList[$fieldName] = $fieldValues[$fieldIndex++];
                 }
                 // Go next to avoid separator field
                 ++$fieldIndex;
                 // Sets element
                 $element = Element::getElementFromArray(DatabaseFactory::getElementClassName($elementTableName), $elementAttributeList);
                 $element->setId();
                 // Ignores empty LJ elements from "_has_" tables
                 if ($element->id == '-') {
                     continue;
                 }
                 // Adds it to element list if it is the main table
                 if ($tableName == $elementTableName && !ArrayTool::array_key_exists($element->id, $elementList)) {
                     $elementList[$element->id] = $element;
                 }
                 $rowElementList[$elementTableName] = $element;
             }
             // Attaches elements with each other
             foreach ($rowElementList as $rowElementTable => $rowElement) {
                 CacheFactory::addElement($rowElement);
                 // Checks if element has to be attached to another one
                 if (isset($joinTableAttachements[$rowElementTable])) {
                     foreach ($joinTableAttachements[$rowElementTable] as &$joinTableAttachement) {
                         if (isset($rowElementList[$joinTableAttachement])) {
                             if ($rowElementList[$joinTableAttachement]->getElementClass() != $rowElement->getElementClass() || $rowElementList[$joinTableAttachement]->id != $rowElement->id) {
                                 $retrievedElementList[$joinTableAttachement][$rowElementList[$joinTableAttachement]->id][$rowElementTable][$rowElement->id] = $rowElement;
                             }
                         }
                     }
                 }
             }
         }
     }
     MysqlDatabaseConnectionModel::free_result($resultList);
     return array($elementList, $retrievedElementList);
 }