D7net Mini Sh3LL v1
Current File : /var/www/html/hpsc/../informatica/layouts/../modules/mod_custom/../../templates/system/../../matlab/../old_inst/../components/../libraries/f0f/table/relations.php |
<?php
/**
* @package FrameworkOnFramework
* @subpackage table
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
// Protect from unauthorized access
defined('F0F_INCLUDED') or die;
class F0FTableRelations
{
/**
* Holds all known relation definitions
*
* @var array
*/
protected $relations = array(
'child' => array(),
'parent' => array(),
'children' => array(),
'multiple' => array(),
);
/**
* Holds the default relations' keys
*
* @var array
*/
protected $defaultRelation = array(
'child' => null,
'parent' => null,
'children' => null,
'multiple' => null,
);
/**
* The table these relations are attached to
*
* @var F0FTable
*/
protected $table = null;
/**
* The name of the component used by our attached table
*
* @var string
*/
protected $componentName = 'joomla';
/**
* The type (table name without prefix and component name) of our attached table
*
* @var string
*/
protected $tableType = '';
/**
* Create a relations object based on the provided F0FTable instance
*
* @param F0FTable $table The table instance used to initialise the relations
*/
public function __construct(F0FTable $table)
{
// Store the table
$this->table = $table;
// Get the table's type from its name
$tableName = $table->getTableName();
$tableName = str_replace('#__', '', $tableName);
$type = explode("_", $tableName);
if (count($type) == 1)
{
$this->tableType = array_pop($type);
}
else
{
$this->componentName = array_shift($type);
$this->tableType = array_pop($type);
}
$this->tableType = F0FInflector::singularize($this->tableType);
$tableKey = $table->getKeyName();
unset($type);
// Scan all table keys and look for foo_bar_id fields. These fields are used to populate parent relations.
foreach ($table->getKnownFields() as $field)
{
// Skip the table key name
if ($field == $tableKey)
{
continue;
}
if (substr($field, -3) != '_id')
{
continue;
}
$parts = explode('_', $field);
// If the component type of the field is not set assume 'joomla'
if (count($parts) == 2)
{
array_unshift($parts, 'joomla');
}
// Sanity check
if (count($parts) != 3)
{
continue;
}
// Make sure we skip any references back to ourselves (should be redundant, due to key field check above)
if ($parts[1] == $this->tableType)
{
continue;
}
// Default item name: the name of the table, singular
$itemName = F0FInflector::singularize($parts[1]);
// Prefix the item name with the component name if we refer to a different component
if ($parts[0] != $this->componentName)
{
$itemName = $parts[0] . '_' . $itemName;
}
// Figure out the table class
$tableClass = ucfirst($parts[0]) . 'Table' . ucfirst($parts[1]);
$default = empty($this->relations['parent']);
$this->addParentRelation($itemName, $tableClass, $field, $field, $default);
}
// Get the relations from the configuration provider
$key = $table->getConfigProviderKey() . '.relations';
$configRelations = $table->getConfigProvider()->get($key, array());
if (!empty($configRelations))
{
foreach ($configRelations as $relation)
{
if (empty($relation['type']))
{
continue;
}
if (isset($relation['pivotTable']))
{
$this->addMultipleRelation($relation['itemName'], $relation['tableClass'],
$relation['localKey'], $relation['ourPivotKey'], $relation['theirPivotKey'],
$relation['remoteKey'], $relation['pivotTable'], $relation['default']);
}
else
{
$method = 'add' . ucfirst($relation['type']). 'Relation';
if (!method_exists($this, $method))
{
continue;
}
$this->$method($relation['itemName'], $relation['tableClass'],
$relation['localKey'], $relation['remoteKey'], $relation['default']);
}
}
}
}
/**
* Add a 1:1 forward (child) relation. This adds relations for the getChild() method.
*
* In other words: does a table HAVE ONE child
*
* Parent and child relations works the same way. We have them separated as it makes more sense for us humans to
* read code like $item->getParent() and $item->getChild() than $item->getRelatedObject('someRandomKeyName')
*
* @param string $itemName is how it will be known locally to the getRelatedItem method (singular)
* @param string $tableClass if skipped it is defined automatically as ComponentnameTableItemname
* @param string $localKey is the column containing our side of the FK relation, default: our primary key
* @param string $remoteKey is the remote table's FK column, default: componentname_itemname_id
* @param boolean $default add as the default child relation?
*
* @return void
*/
public function addChildRelation($itemName, $tableClass = null, $localKey = null, $remoteKey = null, $default = true)
{
$itemName = $this->normaliseItemName($itemName, false);
if (empty($localKey))
{
$localKey = $this->table->getKeyName();
}
$this->addBespokeSimpleRelation('child', $itemName, $tableClass, $localKey, $remoteKey, $default);
}
/**
* Defining an inverse 1:1 (parent) relation. You must specify at least the $tableClass or the $localKey.
* This adds relations for the getParent() method.
*
* In other words: does a table BELONG TO ONE parent
*
* Parent and child relations works the same way. We have them separated as it makes more sense for us humans to
* read code like $item->getParent() and $item->getChild() than $item->getRelatedObject('someRandomKeyName')
*
* @param string $itemName is how it will be known locally to the getRelatedItem method (singular)
* @param string $tableClass if skipped it is defined automatically as ComponentnameTableItemname
* @param string $localKey is the column containing our side of the FK relation, default: componentname_itemname_id
* @param string $remoteKey is the remote table's FK column, default: componentname_itemname_id
* @param boolean $default Is this the default parent relationship?
*
* @return void
*/
public function addParentRelation($itemName, $tableClass = null, $localKey = null, $remoteKey = null, $default = true)
{
$itemName = $this->normaliseItemName($itemName, false);
$this->addBespokeSimpleRelation('parent', $itemName, $tableClass, $localKey, $remoteKey, $default);
}
/**
* Defining a forward 1:∞ (children) relation. This adds relations to the getChildren() method.
*
* In other words: does a table HAVE MANY children?
*
* The children relation works very much the same as the parent and child relation. The difference is that the
* parent and child relations return a single table object, whereas the children relation returns an iterator to
* many objects.
*
* @param string $itemName is how it will be known locally to the getRelatedItems method (plural)
* @param string $tableClass if skipped it is defined automatically as ComponentnameTableItemname
* @param string $localKey is the column containing our side of the FK relation, default: our primary key
* @param string $remoteKey is the remote table's FK column, default: componentname_itemname_id
* @param boolean $default is this the default children relationship?
*
* @return void
*/
public function addChildrenRelation($itemName, $tableClass = null, $localKey = null, $remoteKey = null, $default = true)
{
$itemName = $this->normaliseItemName($itemName, true);
if (empty($localKey))
{
$localKey = $this->table->getKeyName();
}
$this->addBespokeSimpleRelation('children', $itemName, $tableClass, $localKey, $remoteKey, $default);
}
/**
* Defining a ∞:∞ (multiple) relation. This adds relations to the getMultiple() method.
*
* In other words: is a table RELATED TO MANY other records?
*
* @param string $itemName is how it will be known locally to the getRelatedItems method (plural)
* @param string $tableClass if skipped it is defined automatically as ComponentnameTableItemname
* @param string $localKey is the column containing our side of the FK relation, default: our primary key field name
* @param string $ourPivotKey is the column containing our side of the FK relation in the pivot table, default: $localKey
* @param string $theirPivotKey is the column containing the other table's side of the FK relation in the pivot table, default $remoteKey
* @param string $remoteKey is the remote table's FK column, default: componentname_itemname_id
* @param string $glueTable is the name of the glue (pivot) table, default: #__componentname_thisclassname_itemname with plural items (e.g. #__foobar_users_roles)
* @param boolean $default is this the default multiple relation?
*/
public function addMultipleRelation($itemName, $tableClass = null, $localKey = null, $ourPivotKey = null, $theirPivotKey = null, $remoteKey = null, $glueTable = null, $default = true)
{
$itemName = $this->normaliseItemName($itemName, true);
if (empty($localKey))
{
$localKey = $this->table->getKeyName();
}
$this->addBespokePivotRelation('multiple', $itemName, $tableClass, $localKey, $remoteKey, $ourPivotKey, $theirPivotKey, $glueTable, $default);
}
/**
* Removes a previously defined relation by name. You can optionally specify the relation type.
*
* @param string $itemName The name of the relation to remove
* @param string $type [optional] The relation type (child, parent, children, ...)
*
* @return void
*/
public function removeRelation($itemName, $type = null)
{
$types = array_keys($this->relations);
if (in_array($type, $types))
{
$types = array($type);
}
foreach ($types as $type)
{
foreach ($this->relations[$type] as $key => $relations)
{
if ($itemName == $key)
{
unset ($this->relations[$type][$itemName]);
// If it's the default one, remove it from the default array, too
if($this->defaultRelation[$type] == $itemName)
{
$this->defaultRelation[$type] = null;
}
return;
}
}
}
}
/**
* Removes all existing relations
*
* @param string $type The type or relations to remove, omit to remove all relation types
*
* @return void
*/
public function clearRelations($type = null)
{
$types = array_keys($this->relations);
if (in_array($type, $types))
{
$types = array($type);
}
foreach ($types as $type)
{
$this->relations[$type] = array();
// Remove the relation from the default stack, too
$this->defaultRelation[$type] = null;
}
}
/**
* Does the named relation exist? You can optionally specify the type.
*
* @param string $itemName The name of the relation to check
* @param string $type [optional] The relation type (child, parent, children, ...)
*
* @return boolean
*/
public function hasRelation($itemName, $type = null)
{
$types = array_keys($this->relations);
if (in_array($type, $types))
{
$types = array($type);
}
foreach ($types as $type)
{
foreach ($this->relations[$type] as $key => $relations)
{
if ($itemName == $key)
{
return true;
}
}
}
return false;
}
/**
* Get the definition of a relation
*
* @param string $itemName The name of the relation to check
* @param string $type [optional] The relation type (child, parent, children, ...)
*
* @return array
*
* @throws RuntimeException When the relation is not found
*/
public function getRelation($itemName, $type)
{
$types = array_keys($this->relations);
if (in_array($type, $types))
{
$types = array($type);
}
foreach ($types as $type)
{
foreach ($this->relations[$type] as $key => $relations)
{
if ($itemName == $key)
{
$temp = $relations;
$temp['type'] = $type;
return $temp;
}
}
}
throw new RuntimeException("Relation $itemName not found in table {$this->tableType}", 500);
}
/**
* Gets the item referenced by a named relation. You can optionally specify the type. Only single item relation
* types will be searched.
*
* @param string $itemName The name of the relation to use
* @param string $type [optional] The relation type (child, parent)
*
* @return F0FTable
*
* @throws RuntimeException If the named relation doesn't exist or isn't supposed to return single items
*/
public function getRelatedItem($itemName, $type = null)
{
if (empty($type))
{
$relation = $this->getRelation($itemName, $type);
$type = $relation['type'];
}
switch ($type)
{
case 'parent':
return $this->getParent($itemName);
break;
case 'child':
return $this->getChild($itemName);
break;
default:
throw new RuntimeException("Invalid relation type $type for returning a single related item", 500);
break;
}
}
/**
* Gets the iterator for the items referenced by a named relation. You can optionally specify the type. Only
* multiple item relation types will be searched.
*
* @param string $itemName The name of the relation to use
* @param string $type [optional] The relation type (children, multiple)
*
* @return F0FDatabaseIterator
*
* @throws RuntimeException If the named relation doesn't exist or isn't supposed to return single items
*/
public function getRelatedItems($itemName, $type = null)
{
if (empty($type))
{
$relation = $this->getRelation($itemName, $type);
$type = $relation['type'];
}
switch ($type)
{
case 'children':
return $this->getChildren($itemName);
break;
case 'multiple':
return $this->getMultiple($itemName);
break;
case 'siblings':
return $this->getSiblings($itemName);
break;
default:
throw new RuntimeException("Invalid relation type $type for returning a collection of related items", 500);
break;
}
}
/**
* Gets a parent item
*
* @param string $itemName [optional] The name of the relation to use, skip to use the default parent relation
*
* @return F0FTable
*
* @throws RuntimeException When the relation is not found
*/
public function getParent($itemName = null)
{
if (empty($itemName))
{
$itemName = $this->defaultRelation['parent'];
}
if (empty($itemName))
{
throw new RuntimeException(sprintf('Default parent relation for %s not found', $this->table->getTableName()), 500);
}
if (!isset($this->relations['parent'][$itemName]))
{
throw new RuntimeException(sprintf('Parent relation %s for %s not found', $itemName, $this->table->getTableName()), 500);
}
return $this->getTableFromRelation($this->relations['parent'][$itemName]);
}
/**
* Gets a child item
*
* @param string $itemName [optional] The name of the relation to use, skip to use the default child relation
*
* @return F0FTable
*
* @throws RuntimeException When the relation is not found
*/
public function getChild($itemName = null)
{
if (empty($itemName))
{
$itemName = $this->defaultRelation['child'];
}
if (empty($itemName))
{
throw new RuntimeException(sprintf('Default child relation for %s not found', $this->table->getTableName()), 500);
}
if (!isset($this->relations['child'][$itemName]))
{
throw new RuntimeException(sprintf('Child relation %s for %s not found', $itemName, $this->table->getTableName()), 500);
}
return $this->getTableFromRelation($this->relations['child'][$itemName]);
}
/**
* Gets an iterator for the children items
*
* @param string $itemName [optional] The name of the relation to use, skip to use the default children relation
*
* @return F0FDatabaseIterator
*
* @throws RuntimeException When the relation is not found
*/
public function getChildren($itemName = null)
{
if (empty($itemName))
{
$itemName = $this->defaultRelation['children'];
}
if (empty($itemName))
{
throw new RuntimeException(sprintf('Default children relation for %s not found', $this->table->getTableName()), 500);
}
if (!isset($this->relations['children'][$itemName]))
{
throw new RuntimeException(sprintf('Children relation %s for %s not found', $itemName, $this->table->getTableName()), 500);
}
return $this->getIteratorFromRelation($this->relations['children'][$itemName]);
}
/**
* Gets an iterator for the sibling items. This relation is inferred from the parent relation. It returns all
* elements on the same table which have the same parent.
*
* @param string $itemName [optional] The name of the relation to use, skip to use the default children relation
*
* @return F0FDatabaseIterator
*
* @throws RuntimeException When the relation is not found
*/
public function getSiblings($itemName = null)
{
if (empty($itemName))
{
$itemName = $this->defaultRelation['parent'];
}
if (empty($itemName))
{
throw new RuntimeException(sprintf('Default siblings relation for %s not found', $this->table->getTableName()), 500);
}
if (!isset($this->relations['parent'][$itemName]))
{
throw new RuntimeException(sprintf('Sibling relation %s for %s not found', $itemName, $this->table->getTableName()), 500);
}
// Get my table class
$tableName = $this->table->getTableName();
$tableName = str_replace('#__', '', $tableName);
$tableNameParts = explode('_', $tableName, 2);
$tableClass = ucfirst($tableNameParts[0]) . 'Table' . ucfirst(F0FInflector::singularize($tableNameParts[1]));
$parentRelation = $this->relations['parent'][$itemName];
$relation = array(
'tableClass' => $tableClass,
'localKey' => $parentRelation['localKey'],
'remoteKey' => $parentRelation['localKey'],
);
return $this->getIteratorFromRelation($relation);
}
/**
* Gets an iterator for the multiple items
*
* @param string $itemName [optional] The name of the relation to use, skip to use the default multiple relation
*
* @return F0FDatabaseIterator
*
* @throws RuntimeException When the relation is not found
*/
public function getMultiple($itemName = null)
{
if (empty($itemName))
{
$itemName = $this->defaultRelation['multiple'];
}
if (empty($itemName))
{
throw new RuntimeException(sprintf('Default multiple relation for %s not found', $this->table->getTableName()), 500);
}
if (!isset($this->relations['multiple'][$itemName]))
{
throw new RuntimeException(sprintf('Multiple relation %s for %s not found', $itemName, $this->table->getTableName()), 500);
}
return $this->getIteratorFromRelation($this->relations['multiple'][$itemName]);
}
/**
* Returns a F0FTable object based on a given relation
*
* @param array $relation Indexed array holding relation definition.
* tableClass => name of the related table class
* localKey => name of the local key
* remoteKey => name of the remote key
*
* @return F0FTable
*
* @throws RuntimeException
* @throws InvalidArgumentException
*/
protected function getTableFromRelation($relation)
{
// Sanity checks
if(
!isset($relation['tableClass']) || !isset($relation['remoteKey']) || !isset($relation['localKey']) ||
!$relation['tableClass'] || !$relation['remoteKey'] || !$relation['localKey']
)
{
throw new InvalidArgumentException('Missing array index for the '.__METHOD__.' method. Please check method signature', 500);
}
// Get a table object from the table class name
$tableClass = $relation['tableClass'];
$tableClassParts = F0FInflector::explode($tableClass);
if(count($tableClassParts) < 3)
{
throw new InvalidArgumentException('Invalid table class named. It should be something like FooTableBar');
}
$table = F0FTable::getInstance($tableClassParts[2], ucfirst($tableClassParts[0]) . ucfirst($tableClassParts[1]));
// Get the table name
$tableName = $table->getTableName();
// Get the remote and local key names
$remoteKey = $relation['remoteKey'];
$localKey = $relation['localKey'];
// Get the local key's value
$value = $this->table->$localKey;
// If there's no value for the primary key, let's stop here
if(!$value)
{
throw new RuntimeException('Missing value for the primary key of the table '.$this->table->getTableName(), 500);
}
// This is required to prevent one relation from killing the db cursor used in a different relation...
$oldDb = $this->table->getDbo();
$oldDb->disconnect(); // YES, WE DO NEED TO DISCONNECT BEFORE WE CLONE THE DB OBJECT. ARGH!
$db = clone $oldDb;
$query = $db->getQuery(true)
->select('*')
->from($db->qn($tableName))
->where($db->qn($remoteKey) . ' = ' . $db->q($value));
$db->setQuery($query, 0, 1);
$data = $db->loadObject();
if (!is_object($data))
{
throw new RuntimeException(sprintf('Cannot load item from relation against table %s column %s', $tableName, $remoteKey), 500);
}
$table->bind($data);
return $table;
}
/**
* Returns a F0FDatabaseIterator based on a given relation
*
* @param array $relation Indexed array holding relation definition.
* tableClass => name of the related table class
* localKey => name of the local key
* remoteKey => name of the remote key
* pivotTable => name of the pivot table (optional)
* theirPivotKey => name of the remote key in the pivot table (mandatory if pivotTable is set)
* ourPivotKey => name of our key in the pivot table (mandatory if pivotTable is set)
*
* @return F0FDatabaseIterator
*
* @throws RuntimeException
* @throws InvalidArgumentException
*/
protected function getIteratorFromRelation($relation)
{
// Sanity checks
if(
!isset($relation['tableClass']) || !isset($relation['remoteKey']) || !isset($relation['localKey']) ||
!$relation['tableClass'] || !$relation['remoteKey'] || !$relation['localKey']
)
{
throw new InvalidArgumentException('Missing array index for the '.__METHOD__.' method. Please check method signature', 500);
}
if(array_key_exists('pivotTable', $relation))
{
if(
!isset($relation['theirPivotKey']) || !isset($relation['ourPivotKey']) ||
!$relation['pivotTable'] || !$relation['theirPivotKey'] || !$relation['ourPivotKey']
)
{
throw new InvalidArgumentException('Missing array index for the '.__METHOD__.' method. Please check method signature', 500);
}
}
// Get a table object from the table class name
$tableClass = $relation['tableClass'];
$tableClassParts = F0FInflector::explode($tableClass);
if(count($tableClassParts) < 3)
{
throw new InvalidArgumentException('Invalid table class named. It should be something like FooTableBar');
}
$table = F0FTable::getInstance($tableClassParts[2], ucfirst($tableClassParts[0]) . ucfirst($tableClassParts[1]));
// Get the table name
$tableName = $table->getTableName();
// Get the remote and local key names
$remoteKey = $relation['remoteKey'];
$localKey = $relation['localKey'];
// Get the local key's value
$value = $this->table->$localKey;
// If there's no value for the primary key, let's stop here
if(!$value)
{
throw new RuntimeException('Missing value for the primary key of the table '.$this->table->getTableName(), 500);
}
// This is required to prevent one relation from killing the db cursor used in a different relation...
$oldDb = $this->table->getDbo();
$oldDb->disconnect(); // YES, WE DO NEED TO DISCONNECT BEFORE WE CLONE THE DB OBJECT. ARGH!
$db = clone $oldDb;
// Begin the query
$query = $db->getQuery(true)
->select('*')
->from($db->qn($tableName));
// Do we have a pivot table?
$hasPivot = array_key_exists('pivotTable', $relation);
// If we don't have pivot it's a straightforward query
if (!$hasPivot)
{
$query->where($db->qn($remoteKey) . ' = ' . $db->q($value));
}
// If we have a pivot table we have to do a subquery
else
{
$subQuery = $db->getQuery(true)
->select($db->qn($relation['theirPivotKey']))
->from($db->qn($relation['pivotTable']))
->where($db->qn($relation['ourPivotKey']) . ' = ' . $db->q($value));
$query->where($db->qn($remoteKey) . ' IN (' . $subQuery . ')');
}
$db->setQuery($query);
$cursor = $db->execute();
$iterator = F0FDatabaseIterator::getIterator($db->name, $cursor, null, $tableClass);
return $iterator;
}
/**
* Add any bespoke relation which doesn't involve a pivot table.
*
* @param string $relationType The type of the relationship (parent, child, children)
* @param string $itemName is how it will be known locally to the getRelatedItems method
* @param string $tableClass if skipped it is defined automatically as ComponentnameTableItemname
* @param string $localKey is the column containing our side of the FK relation, default: componentname_itemname_id
* @param string $remoteKey is the remote table's FK column, default: componentname_itemname_id
* @param boolean $default is this the default children relationship?
*
* @return void
*/
protected function addBespokeSimpleRelation($relationType, $itemName, $tableClass, $localKey, $remoteKey, $default)
{
$ourPivotKey = null;
$theirPivotKey = null;
$pivotTable = null;
$this->normaliseParameters(false, $itemName, $tableClass, $localKey, $remoteKey, $ourPivotKey, $theirPivotKey, $pivotTable);
$this->relations[$relationType][$itemName] = array(
'tableClass' => $tableClass,
'localKey' => $localKey,
'remoteKey' => $remoteKey,
);
if ($default)
{
$this->defaultRelation[$relationType] = $itemName;
}
}
/**
* Add any bespoke relation which involves a pivot table.
*
* @param string $relationType The type of the relationship (multiple)
* @param string $itemName is how it will be known locally to the getRelatedItems method
* @param string $tableClass if skipped it is defined automatically as ComponentnameTableItemname
* @param string $localKey is the column containing our side of the FK relation, default: componentname_itemname_id
* @param string $remoteKey is the remote table's FK column, default: componentname_itemname_id
* @param string $ourPivotKey is the column containing our side of the FK relation in the pivot table, default: $localKey
* @param string $theirPivotKey is the column containing the other table's side of the FK relation in the pivot table, default $remoteKey
* @param string $pivotTable is the name of the glue (pivot) table, default: #__componentname_thisclassname_itemname with plural items (e.g. #__foobar_users_roles)
* @param boolean $default is this the default children relationship?
*
* @return void
*/
protected function addBespokePivotRelation($relationType, $itemName, $tableClass, $localKey, $remoteKey, $ourPivotKey, $theirPivotKey, $pivotTable, $default)
{
$this->normaliseParameters(true, $itemName, $tableClass, $localKey, $remoteKey, $ourPivotKey, $theirPivotKey, $pivotTable);
$this->relations[$relationType][$itemName] = array(
'tableClass' => $tableClass,
'localKey' => $localKey,
'remoteKey' => $remoteKey,
'ourPivotKey' => $ourPivotKey,
'theirPivotKey' => $theirPivotKey,
'pivotTable' => $pivotTable,
);
if ($default)
{
$this->defaultRelation[$relationType] = $itemName;
}
}
/**
* Normalise the parameters of a relation, guessing missing values
*
* @param boolean $pivot Is this a many to many relation involving a pivot table?
* @param string $itemName is how it will be known locally to the getRelatedItems method (plural)
* @param string $tableClass if skipped it is defined automatically as ComponentnameTableItemname
* @param string $localKey is the column containing our side of the FK relation, default: componentname_itemname_id
* @param string $remoteKey is the remote table's FK column, default: componentname_itemname_id
* @param string $ourPivotKey is the column containing our side of the FK relation in the pivot table, default: $localKey
* @param string $theirPivotKey is the column containing the other table's side of the FK relation in the pivot table, default $remoteKey
* @param string $pivotTable is the name of the glue (pivot) table, default: #__componentname_thisclassname_itemname with plural items (e.g. #__foobar_users_roles)
*
* @return void
*/
protected function normaliseParameters($pivot = false, &$itemName, &$tableClass, &$localKey, &$remoteKey, &$ourPivotKey, &$theirPivotKey, &$pivotTable)
{
// Get a default table class if none is provided
if (empty($tableClass))
{
$tableClassParts = explode('_', $itemName, 3);
if (count($tableClassParts) == 1)
{
array_unshift($tableClassParts, $this->componentName);
}
if ($tableClassParts[0] == 'joomla')
{
$tableClassParts[0] = 'J';
}
$tableClass = ucfirst($tableClassParts[0]) . 'Table' . ucfirst(F0FInflector::singularize($tableClassParts[1]));
}
// Make sure we have both a local and remote key
if (empty($localKey) && empty($remoteKey))
{
// WARNING! If we have a pivot table, this behavior is wrong!
// Infact if we have `parts` and `groups` the local key should be foobar_part_id and the remote one foobar_group_id.
// However, this isn't a real issue because:
// 1. we have no way to detect the local key of a multiple relation
// 2. this scenario never happens, since, in this class, if we're adding a multiple relation we always supply the local key
$tableClassParts = F0FInflector::explode($tableClass);
$localKey = $tableClassParts[0] . '_' . $tableClassParts[2] . '_id';
$remoteKey = $localKey;
}
elseif (empty($localKey) && !empty($remoteKey))
{
$localKey = $remoteKey;
}
elseif (!empty($localKey) && empty($remoteKey))
{
if($pivot)
{
$tableClassParts = F0FInflector::explode($tableClass);
$remoteKey = $tableClassParts[0] . '_' . $tableClassParts[2] . '_id';
}
else
{
$remoteKey = $localKey;
}
}
// If we don't have a pivot table nullify the relevant variables and return
if (!$pivot)
{
$ourPivotKey = null;
$theirPivotKey = null;
$pivotTable = null;
return;
}
if (empty($ourPivotKey))
{
$ourPivotKey = $localKey;
}
if (empty($theirPivotKey))
{
$theirPivotKey = $remoteKey;
}
if (empty($pivotTable))
{
$pivotTable = '#__' . strtolower($this->componentName) . '_' .
strtolower(F0FInflector::pluralize($this->tableType)) . '_';
$itemNameParts = explode('_', $itemName);
$lastPart = array_pop($itemNameParts);
$pivotTable .= strtolower($lastPart);
}
}
/**
* Normalises the format of a relation name
*
* @param string $itemName The raw relation name
* @param boolean $pluralise Should I pluralise the name? If not, I will singularise it
*
* @return string The normalised relation key name
*/
protected function normaliseItemName($itemName, $pluralise = false)
{
// Explode the item name
$itemNameParts = explode('_', $itemName);
// If we have multiple parts the first part is considered to be the component name
if (count($itemNameParts) > 1)
{
$prefix = array_shift($itemNameParts);
}
else
{
$prefix = null;
}
// If we still have multiple parts we need to pluralise/singularise the last part and join everything in
// CamelCase format
if (count($itemNameParts) > 1)
{
$name = array_pop($itemNameParts);
$name = $pluralise ? F0FInflector::pluralize($name) : F0FInflector::singularize($name);
$itemNameParts[] = $name;
$itemName = F0FInflector::implode($itemNameParts);
}
// Otherwise we singularise/pluralise the remaining part
else
{
$name = array_pop($itemNameParts);
$itemName = $pluralise ? F0FInflector::pluralize($name) : F0FInflector::singularize($name);
}
if (!empty($prefix))
{
$itemName = $prefix . '_' . $itemName;
}
return $itemName;
}
}
AnonSec - 2021 | Recode By D7net