function advagg_bundler_merge in Advanced CSS/JS Aggregation 6
Same name and namespace in other branches
- 7.2 advagg_bundler/advagg_bundler.advagg.inc \advagg_bundler_merge()
- 7 advagg_bundler/advagg_bundler.module \advagg_bundler_merge()
Merge bundles together if too many where created.
This preserves the order.
Parameters
$groupings: array of requested groups
$max: max number of grouping
1 call to advagg_bundler_merge()
- advagg_bundler_advagg_filenames_alter in advagg_bundler/
advagg_bundler.module - Implement hook_advagg_filenames_alter.
File
- advagg_bundler/
advagg_bundler.module, line 259 - Advanced aggregation bundler module.
Code
function advagg_bundler_merge(&$groupings, $max, $filetype) {
$group_count = count($groupings);
if (!empty($max)) {
// Keep going till array has been merged to the desired size.
while ($group_count > $max) {
// Get array sizes.
// Counts the number of files that are placed into each bundle.
$counts = array();
foreach ($groupings as $key => $values) {
$counts[$key] = count($values);
}
// Create mapping.
// Calculates the file count of potential merges. It only merges with
// neighbors in order to preserve execution order.
$map = array();
$prev_key = '';
foreach ($counts as $key => $val) {
// First run of the foreach loop; populate prev key/values and continue.
// We can't merge with the previous group in this case.
if (empty($prev_key)) {
$prev_key = $key;
$prev_val = $val;
continue;
}
// Array key ($prev_val + $val) is the file count of this new group if
// these 2 groups ($prev_key, $key) where to be merged together.
$map[] = array(
$prev_val + $val => array(
$prev_key,
$key,
),
);
$prev_key = $key;
$prev_val = $val;
}
// Get best merge candidate.
// We are looking for the smallest file count. $min is populated with a
// large number (15 bits) so it won't be selected in this process.
$min = 32767;
foreach ($map as $v) {
foreach ($v as $key => $values) {
$min = min($min, $key);
// If the min value (number of files in the proposed merged bundle) is
// the same as the key, then get the 2 bundle keys that generated this
// new min value.
if ($min == $key) {
list($first, $last) = $values;
}
}
}
// Create the new merged set.
$a = $groupings[$first];
$b = $groupings[$last];
$new_set = array_merge($a, $b);
// Rebuild the array with the new set in the correct place.
$new_groupings = array();
foreach ($groupings as $key => $files) {
if ($key == $first) {
$new_groupings[$first . ' ' . $last] = $new_set;
}
elseif ($key != $last) {
$new_groupings[$key] = $files;
}
}
$groupings = $new_groupings;
$group_count--;
}
}
// Make sure there isn't a group that has all files that don't exist or empty.
$bad_groups = array();
$counts = array();
foreach ($groupings as $key => $group) {
$missing_counter = 0;
$counts[$key] = count($group);
foreach ($group as $i => $file) {
advagg_clearstatcache(TRUE, $file);
if (!file_exists($file) || filesize($file) == 0) {
$missing_counter++;
}
}
// If all files are missing/empty in this group then it is a bad set.
if ($missing_counter == count($group)) {
$bad_groups[$key] = TRUE;
}
}
// Add the bad groups to the smallest grouping in this set.
if (!empty($bad_groups)) {
$merge_candidate_key = '';
$merge_candidate_count = 32767;
$bad_group = array();
foreach ($groupings as $key => $group) {
if (isset($bad_groups[$key])) {
// Merge all bad groups into one.
$bad_group = array_merge($bad_group, $group);
// Delete the bad group from the master set.
unset($groupings[$key]);
continue;
}
// Find the smallest good grouping.
$min = min($merge_candidate_count, count($group));
if ($min < $merge_candidate_count) {
$merge_candidate_key = $key;
$merge_candidate_count = $min;
}
}
// Move the bad files into the smallest good group.
$new_set = $groupings[$merge_candidate_key];
$new_set = array_merge($new_set, $bad_group);
$groupings[$merge_candidate_key] = $new_set;
}
// Prevent CSS selectors exceeding 4095 due to limits with IE9 and below.
if ($filetype == 'css') {
// Check each group to see if it exceeds the selector limit.
do {
$groupings_edited = FALSE;
foreach ($groupings as $key => $group) {
// Restart the selector limit check if the grouping was edited.
if ($groupings_edited) {
break;
}
$group_selector_counter = 0;
$selector_counts = advagg_bundler_get_css_selector_count($group);
for ($i = 0; $i < count($group) && !$groupings_edited; $i++) {
$selector_count = isset($selector_counts[$group[$i]]) ? $selector_counts[$group[$i]] : 0;
if ($group_selector_counter + $selector_count > SELECTOR_SPLIT_VALUE) {
$groupings_edited = TRUE;
// Divide the group.
$first_group = array_splice($group, 0, $i);
$second_group = array_splice($group, 0);
// Rebuild the array with the new set in the correct place.
$new_groupings = array();
foreach ($groupings as $k => $files) {
if ($k == $key) {
$new_groupings[$k . '_1'] = $first_group;
$new_groupings[$k . '_2'] = $second_group;
}
else {
$new_groupings[$k] = $files;
}
}
$groupings = $new_groupings;
}
else {
$group_selector_counter += $selector_count;
}
}
}
} while ($groupings_edited);
}
}