/** * Returns The SQL query join part (shared between getElementList and getElementCount) * @param string $mainTableName The main table name * @param string $join The join string to apply (ex : 'World IJ Region, Region LJ City, World IJ City') * @return array array($request, $joinTableNameList, $joinTableAttachements, $specificJoinConditions, $joinOrder) */ public static function getJoin($mainTableName, $joinCondition) { $joinSelectRequest = ''; // SELECT part of the request $joinFromRequest = ''; // FROM part of the request // Parses join string (ex : 'World IJ Region, Region LJ User') $joinTableNameList = array(); // Element types array (ex : [World, Region, City]) $joinOperators = array(); // Join operators array (ex : [IJ, LJ, RJ]) $joinLeftTypes = array(); // Join left types array (ex : [World, Region, World]]) $joinRightTypes = array(); // Join right types array (ex : [Region, City, City]]) $joinConditions = array(); $joinTableAttachements = array(); // Join table attachements array (ex : [Region => World, City => [Region, World]]) // Sets a join per table/condition match, separeted by comma (ie: 0 => Character IJ User, 1 => Character IJ Type) $joinList = StringTool::split(DatabaseFactory::JOIN_TABLE_SEPARATOR, $joinCondition); $joinOrder = array(); // join order array (ex: ['Region'=>0, 'User'=>-1, 'Zone'=>1]) $joinOrder[$mainTableName] = 0; // join order init foreach ($joinList as &$join) { // Parse join conditions and joined tables $joinSplit = StringTool::split(DatabaseFactory::JOIN_CONDITIONS_SEPARATOR, $join); $joinTables = $joinSplit[0]; $joinCondition = isset($joinSplit[1]) ? $joinSplit[1] : NULL; // Separates left and right parts from spaces (ie: Character IJ Type => array(Character, IJ, Type)) list($leftSyntax, $joinOperator, $rightSyntax) = StringTool::split(DatabaseFactory::JOIN_SYNTAX_SEPARATOR, $joinTables); // Scans left/right part for aliases $leftType = $leftSyntax; $rightType = $rightSyntax; // Gets table names from types $leftTableName = DatabaseFactory::getElementTableName($leftType); $rightTableName = DatabaseFactory::getElementTableName($rightType); if (isset($joinOrder[$leftTableName])) { $joinOrder[$rightTableName] = $joinOrder[$leftTableName] + 1; } elseif (isset($joinOrder[$rightTableName])) { $joinOrder[$leftTableName] = $joinOrder[$rightTableName] - 1; } else { LogTool::getInstance()->logWarning('Join syntax is not in the right order'); } if ($leftTableName != $mainTableName && !in_array($leftTableName, $joinTableNameList)) { $joinTableNameList[] = $leftTableName; } if ($rightTableName != $mainTableName && !in_array($rightTableName, $joinTableNameList)) { $joinTableNameList[] = $rightTableName; } $joinOperators[] = $joinOperator; $joinLeftTypes[] = $leftType; $joinRightTypes[] = $rightType; $joinConditions[] = $joinCondition; $joinTableAttachements[$rightTableName][] = $leftTableName; } // Builds request field list part $usedTableNameList = array($mainTableName); $joinSelectRequest .= $mainTableName . '.*'; foreach ($joinTableNameList as &$joinTableName) { $joinSelectRequest .= ', NULL AS ' . $joinTableName . DatabaseFactory::JOIN_TABLE_FIELD_SEPARATOR . ', ' . $joinTableName . '.*'; } // Builds request "FROM" part $joinFromRequest .= ' FROM ' . $mainTableName; // Builds request join list part $specificJoinConditions = FALSE; $joinOperatorsCount = count($joinOperators); for ($fieldIndex = 0; $fieldIndex < $joinOperatorsCount; $fieldIndex++) { $joinOperator = $joinOperators[$fieldIndex]; $joinLeftType = $joinLeftTypes[$fieldIndex]; $joinRightType = $joinRightTypes[$fieldIndex]; $joinLeftTableName = DatabaseFactory::getElementTableName($joinLeftType); $joinRightTableName = DatabaseFactory::getElementTableName($joinRightType); $joinLeftField = $joinLeftTableName . '_id'; $joinRightField = DatabaseFactory::getParentIdColumnName($joinLeftType); $joinCondition = $joinConditions[$fieldIndex]; if ($joinCondition === NULL) { $joinCondition = $joinRightTableName . '.' . $joinRightField . '=' . $joinLeftTableName . '.' . $joinLeftField; } else { $specificJoinConditions = TRUE; } switch ($joinOperator) { // Inner join case 'IJ': $joinOperatorSql = ' INNER JOIN '; break; // Left join // Left join case 'LJ': $joinOperatorSql = ' LEFT JOIN '; break; default: // Unknown join throw new DatabaseException('Invalid join operator specified : "' . $joinOperator . '"'); } // Right type already used (joining on left type) if (in_array($joinRightTableName, $usedTableNameList)) { $joinFromRequest .= $joinOperatorSql . $joinLeftTableName; } else { $joinFromRequest .= $joinOperatorSql . $joinRightTableName; } $joinFromRequest .= ' ON ' . $joinCondition; // Marks join types as used $usedTableNameList[] = array($joinLeftTableName); $usedTableNameList[] = array($joinRightTableName); } return array($joinSelectRequest, $joinFromRequest, $joinTableNameList, $joinTableAttachements, $specificJoinConditions, $joinOrder); }
/** * Gets parent element from an element * @param Element $element The child element * @param string $parentClass The parent element class * @param string $conditions The conditions string to apply * @param string $orderBy The order string to apply * @return Element The parent element */ public static function getParentElement($element, $parentClass, $conditions = NULL, $orderBy = NULL) { $logInstance = LogTool::getInstance(); $logInstance->logDebug('Gets ' . $element->getElementClass() . ' parent ' . $parentClass . ' element...'); // Gets parent element by type and id $parentIdFieldName = DatabaseFactory::getParentIdColumnName($parentClass); // Split parent class name for search like people_mother, to get mother_people_id field from People table $parentClassNameList = StringTool::split(ElementFactory::TABLE_FIELD_SEPARATOR, $parentClass); $parentClass = end($parentClassNameList); $parentId = $element->{$parentIdFieldName}; // Parent element id is null if ($parentId === NULL) { throw new ElementException('Cannot get ' . $parentClass . ' parent for ' . $element->getElementClass() . ' with id #' . $element->id . ': ' . $parentIdFieldName . ' is NULL'); } return ElementFactory::getElement($parentClass, $parentId, $conditions, $orderBy); }