Here is the structure of my categories in the database
Parent category A (category_id = 1)
Child category B (category_id = 2)
Child category C (category_id = 3)
Child category D (category_id = 4)
Child category E (category_id = 5)
Basically my Joomla extension does not allow you to classify a Page in several categories at the same time. But I managed to get around this by modifying some php files, and adding several category_id values (separated by commas)
My code that works. But it's just too long. I would like to simplify it. I had to create all the scenarios, depending on the position of the numbers.
My code :
// Get all child ids from this category
$categoryModel = ES::model('ClusterCategory');
$childs = $categoryModel->getChildCategories($activeCategory->id, [], SOCIAL_TYPE_PAGE, array('state' => SOCIAL_STATE_PUBLISHED));
$childIds = [];
foreach ($childs as $child) {
$childIds[] = "1,$child->id";
$childIds[] = "2,$child->id";
$childIds[] = "3,$child->id";
$childIds[] = "4,$child->id";
$childIds[] = "5,$child->id";
$childIds[] = "$child->id,1";
$childIds[] = "$child->id,2";
$childIds[] = "$child->id,3";
$childIds[] = "$child->id,4";
$childIds[] = "$child->id,5";
$childIds[] = "1,$child->id,2";
$childIds[] = "2,$child->id,3";
$childIds[] = "3,$child->id,4";
$childIds[] = "4,$child->id,5";
$childIds[] = "5,$child->id,1";
$childIds[] = "2,$child->id,1";
$childIds[] = "3,$child->id,2";
$childIds[] = "4,$child->id,3";
$childIds[] = "5,$child->id,4";
$childIds[] = "1,$child->id,5";
$childIds[] = $child->id;
}
My question : How to insert a variable instead of the number? I tried Regexp, and many other things.
As in an equation with an unknown. $childIds[] = X,$child->id,X;
You could use nested loops do do this.
$categoryModel = ES::model('ClusterCategory');
$childs = $categoryModel->getChildCategories($activeCategory->id, [], SOCIAL_TYPE_PAGE, array('state' => SOCIAL_STATE_PUBLISHED));
$childIds = [];
foreach ($childs as $child) {
for ($i = 1; $i <= 5; $i++) {
$childIds[] = "$i,$child->id";
$childIds[] = "$child->id,$i";
for ($j = 1; $j <= 5; $j++) {
if ($i != $j) {
$childIds[] = "$i,$child->id,$j";
$childIds[] = "$i,$j,$child->id";
for ($k = 1; $k <= 5; $k++) {
if ($i != $k && $j != $k) {
$childIds[] = "$i,$child->id,$j,$k";
$childIds[] = "$i,$j,$child->id,$k";
// Add more combinations as needed
}
}
}
}
}
}
This way, you can easily adjust the range of numbers by changing the loop boundaries, and the code will be more maintainable.
But since nested loops in general are a very bad idea you should consider using a recursive function instead.
function generateCombinations($depth, $maxDepth, $currentCombination, $excludeValues, $childId, &$childIds) {
if ($depth == $maxDepth) {
$childIds[] = implode(',', $currentCombination);
return;
}
for ($i = 1; $i <= 5; $i++) {
if (!in_array($i, $excludeValues)) {
$currentCombination[] = $i;
generateCombinations($depth + 1, $maxDepth, $currentCombination, $excludeValues, $childId, $childIds);
array_pop($currentCombination);
}
}
}
$categoryModel = ES::model('ClusterCategory');
$childs = $categoryModel->getChildCategories($activeCategory->id, [], SOCIAL_TYPE_PAGE, array('state' => SOCIAL_STATE_PUBLISHED));
$childIds = [];
foreach ($childs as $child) {
generateCombinations(0, 2, [$child->id], [], $child->id, $childIds);
generateCombinations(0, 3, [$child->id], [], $child->id, $childIds);
// Add more calls for additional combinations if needed
}
But to be completely honest the right way to solve this is to review your database structure.