function _drush_features_component_filter in Features 7.2
Same name and namespace in other branches
- 8.4 drush/features.drush8.inc \_drush_features_component_filter()
- 8.3 drush/features.drush8.inc \_drush_features_component_filter()
- 7 features.drush.inc \_drush_features_component_filter()
Filters components by patterns.
Parameters
string[][] $all_components: Format: $[$component][$name] = $title.
string[] $patterns: Format: $[] = $pattern.
bool[] $options: Options to control what is returned, and which components are included. Exported items (defined in at least one enabled are included if $options['exported'] is TRUE(-ish) or not provided. Non-exported items If $options['exported'] is TRUE(-ish) or not provided, "exported" features are Possible array keys: 'exported', 'not exported', 'provided by'.
Return value
array[]|false Format: Contains two sub-arrays: $['components'][$component][$name] = $title $['sources'][$component . ':' . $name] = implode(', ', $providing_modules)
2 calls to _drush_features_component_filter()
- drush_features_components in ./
features.drush.inc - Drush command callback for 'features-components'.
- drush_features_export in ./
features.drush.inc - Drush command callback for 'features-export'.
File
- ./
features.drush.inc, line 373 - Features module drush integration.
Code
function _drush_features_component_filter($all_components, $patterns = array(), $options = array()) {
$options += array(
'exported' => TRUE,
'not exported' => TRUE,
'provided by' => FALSE,
);
$pool = array();
// Maps exported components to feature modules.
$components_map = features_get_component_map();
// First filter on exported state.
foreach ($all_components as $source => $components) {
foreach ($components as $name => $title) {
$exported = !empty($components_map[$source][$name]);
if ($exported) {
if ($options['exported']) {
$pool[$source][$name] = $title;
}
}
else {
if ($options['not exported']) {
$pool[$source][$name] = $title;
}
}
}
}
$state_string = '';
if (!$options['exported']) {
$state_string = 'unexported';
}
elseif (!$options['not exported']) {
$state_string = 'exported';
}
$selected = array();
foreach ($patterns as $pattern) {
// Rewrite * to %. Let users use both as wildcard.
$pattern = strtr($pattern, array(
'*' => '%',
));
$sources = array();
if (strpos($pattern, ':') !== FALSE) {
list($source_pattern, $component_pattern) = explode(':', $pattern, 2);
}
else {
$source_pattern = $pattern;
$component_pattern = '';
}
// If source is empty, use a pattern.
if ($source_pattern == '') {
$source_pattern = '%';
}
if ($component_pattern == '') {
$component_pattern = '%';
}
$preg_source_pattern = strtr(preg_quote($source_pattern, '/'), array(
'%' => '.*',
));
$preg_component_pattern = strtr(preg_quote($component_pattern, '/'), array(
'%' => '.*',
));
// If it isn't a pattern, but a simple string, we don't anchor the pattern,
// this allows for abbreviating. Else, we do, as this seems more natural for
// patterns.
if (strpos($source_pattern, '%') !== FALSE) {
$preg_source_pattern = '^' . $preg_source_pattern . '$';
}
if (strpos($component_pattern, '%') !== FALSE) {
$preg_component_pattern = '^' . $preg_component_pattern . '$';
}
$matches = array();
// Find the sources.
$all_sources = array_keys($pool);
$matches = preg_grep('/' . $preg_source_pattern . '/', $all_sources);
if (sizeof($matches) > 0) {
// If we have multiple matches and the source string wasn't a
// pattern, check if one of the matches is equal to the pattern, and
// use that, or error out.
if (sizeof($matches) > 1 and $preg_source_pattern[0] != '^') {
if (in_array($source_pattern, $matches)) {
$matches = array(
$source_pattern,
);
}
else {
return drush_set_error('', dt('Ambiguous source "!source", matches !matches', array(
'!source' => $source_pattern,
'!matches' => join(', ', $matches),
)));
}
}
// Loose the indexes preg_grep preserved.
$sources = array_values($matches);
}
else {
return drush_set_error('', dt('No !state sources match "!source"', array(
'!state' => $state_string,
'!source' => $source_pattern,
)));
}
// Now find the components.
foreach ($sources as $source) {
// Find the components.
$all_components = array_keys($pool[$source]);
// See if there's any matches.
$matches = preg_grep('/' . $preg_component_pattern . '/', $all_components);
if (sizeof($matches) > 0) {
// If we have multiple matches and the components string wasn't a
// pattern, check if one of the matches is equal to the pattern, and
// use that, or error out.
if (sizeof($matches) > 1 and $preg_component_pattern[0] != '^') {
if (in_array($component_pattern, $matches)) {
$matches = array(
$component_pattern,
);
}
else {
return drush_set_error('', dt('Ambiguous component "!component", matches !matches', array(
'!component' => $component_pattern,
'!matches' => join(', ', $matches),
)));
}
}
if (empty($selected[$source])) {
$selected[$source] = array();
}
$selected[$source] += array_intersect_key($pool[$source], array_flip($matches));
}
else {
// No matches. If the source was a pattern, just carry on, else
// error out. Allows for patterns like :*field*.
if ($preg_source_pattern[0] != '^') {
return drush_set_error('', dt('No !state !source components match "!component"', array(
'!state' => $state_string,
'!component' => $component_pattern,
'!source' => $source,
)));
}
}
}
}
// Lastly, provide feature module information on the selected components, if
// requested.
$provided_by = array();
if ($options['provided by'] && $options['exported']) {
foreach ($selected as $source => $components) {
foreach ($components as $name => $title) {
$exported = !empty($components_map[$source][$name]);
if ($exported) {
$provided_by[$source . ':' . $name] = join(', ', $components_map[$source][$name]);
}
}
}
}
return array(
'components' => $selected,
'sources' => $provided_by,
);
}