class PathChecker in Optimizely 8
Same name and namespace in other branches
- 8.0 src/PathChecker.php \Drupal\optimizely\PathChecker
Provides static methods to check path validity, etc.
Hierarchy
- class \Drupal\optimizely\PathChecker uses LookupPath
Expanded class hierarchy of PathChecker
File
- src/
PathChecker.php, line 8
Namespace
Drupal\optimizelyView source
class PathChecker {
use LookupPath;
/**
* Validate the target paths.
*
* @param array $project_paths
* An array of the paths to validate.
*
* @return bool|string
* Boolean of TRUE if the paths are valid or
* a string of the path that failed.
*/
public static function validatePaths(array $project_paths) {
// Validate entered paths to confirm the paths exist on the website.
foreach ($project_paths as $path) {
// Check for sitewide wildcard.
if (strpos($path, '*') === 0) {
// Must be just the wildcard itself with nothing trailing.
if ($path != '*') {
return $path;
}
return count($project_paths) == 1 ? TRUE : $path;
}
elseif (strpos($path, '*') !== FALSE) {
$project_wildpath = substr($path, 0, -2);
if (\Drupal::pathValidator()
->isValid($project_wildpath) == FALSE) {
// Look for entries in url_alias.
$query = \Drupal::database()
->query("SELECT * FROM {url_alias} WHERE\n source LIKE :project_wildpath OR alias LIKE :project_wildpath", [
':project_wildpath' => $project_wildpath . '%',
]);
$results = $query
->fetchCol(0);
$project_wildpath_match = count($results);
// No matches found for wildcard path.
if (!$project_wildpath_match) {
return $path;
}
}
}
elseif (strpos($path, '?') !== FALSE) {
// Look for entries in menu_router.
$project_parmpath = substr($path, 0, strpos($path, '?'));
// Look for entry in url_alias table.
if (self::lookupPathAlias($path) === FALSE && self::lookupSystemPath($path) === FALSE && \Drupal::pathValidator()
->isValid($project_parmpath) == FALSE) {
return $path;
}
}
elseif (\Drupal::pathValidator()
->isValid($path) == FALSE) {
// Look for entry in url_alias table.
if (self::lookupPathAlias($path) === FALSE && self::lookupSystemPath($path) === FALSE) {
return $path;
}
}
}
return TRUE;
}
/**
* Compare target path against the project paths to confirm they're unique.
*
* @param array $target_paths
* The paths entered for a new project entry, OR
* the paths of an existing project entry that has been enabled.
* @param int|null $target_oid
* The oid of the project entry that has been enabled, or NULL.
*
* @return bool|
* $target_path: the path that is a duplicate that must be addressed to
* enable or create the new project entry, or TRUE if unique paths.
*/
public static function uniquePaths(array $target_paths, $target_oid = NULL) {
// Look up alternative paths.
$target_paths = self::collectAlias($target_paths);
// Look for duplicate paths in submitted $target_paths.
$duplicate_target_path = self::duplicateCheck($target_paths);
// Look for duplicate paths within target paths.
if (!$duplicate_target_path) {
// Collect all of the existing project paths that are enabled.
$query = \Drupal::database()
->select('optimizely', 'o', [
'target' => 'slave',
])
->fields('o', [
'oid',
'project_title',
'path',
])
->condition('o.enabled', 1, '=');
// Add target_oid to query when it's an update, $target_oid is defined.
if ($target_oid != NULL) {
$query = $query
->condition('o.oid', $target_oid, '<>');
}
$projects = $query
->execute();
// No other enabled projects.
if ($query
->countQuery()
->execute()
->fetchField() == 0) {
return [
TRUE,
NULL,
];
}
$all_project_paths = [];
// Build array of all the project entry paths.
foreach ($projects as $project) {
// Collect all of the path values and merge into collective array.
$project_paths = unserialize($project->path);
$all_project_paths = array_merge($all_project_paths, $project_paths);
}
// Add any additional aliases to catch all match possiblities.
$all_project_paths = self::collectAlias($all_project_paths);
// Convert array into string for drupal_match_path().
$all_project_paths_string = implode("\n", $all_project_paths);
// Check all of the paths for all of the active project entries
// to make sure the paths are unique.
foreach ($target_paths as $target_path) {
// "*" found in path.
if (strpos($target_path, '*') !== FALSE) {
// Look for wild card match if not sitewide.
if (strpos($target_path, '*') !== 0) {
$target_path = substr($target_path, 0, -2);
// Look for duplicate path due to wild card.
foreach ($all_project_paths as $all_project_path) {
if (strpos($all_project_path, $target_path) === 0 && $all_project_path != $target_path) {
return [
$project->project_title,
$target_path,
];
}
}
}
elseif (strpos($target_path, '*') === 0 && (count($target_paths) > 1 || count($all_project_paths) > 0)) {
return [
$project->project_title,
$target_path,
];
}
// Look for sitewide wild card in target project paths.
if (in_array('*', $all_project_paths)) {
return [
$project->project_title,
$target_path,
];
}
}
elseif (strpos($target_path, '?') !== FALSE) {
$target_path = substr($target_path, 0, strpos($target_path, '?'));
}
// Look for duplicates.
if (\Drupal::service('path.matcher')
->matchPath($target_path, $all_project_paths_string)) {
return [
$project->project_title,
$target_path,
];
}
}
return [
TRUE,
NULL,
];
}
else {
return [
NULL,
$duplicate_target_path,
];
}
}
/**
* Lookup all alternatives to the group of paths - alias, <front>.
*
* @param array $paths
* A set of paths to be reviewed for alternatives.
*
* @return array
* An updated list of paths that include the additional source
* and alias values.
*/
private static function collectAlias(array $paths) {
// Add alternative values - alias, source, <front> to ensure matches
// also check different possibilities.
foreach ($paths as $path_count => $path) {
// Remove parameters.
if (strpos($path, '?') !== FALSE) {
$path = substr($path, 0, strpos($path, '?'));
$paths[$path_count] = $path;
}
if (self::lookupPathAlias($path)) {
$paths[] = self::lookupPathAlias($path);
}
if (self::lookupSystemPath($path)) {
$paths[] = self::lookupSystemPath($path);
}
// Collect all the possible values to match <front>.
if ($path == '<front>') {
$frontpage = \Drupal::config('system.site')
->get('page.front');
if ($frontpage) {
$paths[] = $frontpage;
$paths[] = self::lookupPathAlias($frontpage);
}
}
}
return $paths;
}
/**
* Compare paths to ensure each item resolves to a unique entry.
*
* @param array $paths
* A set of paths to be reviewed for uniqueness.
*
* @return bool|array
* FALSE if no duplicates found, otherwise the duplicate path is returned.
*/
private static function duplicateCheck(array $paths) {
$unreviewed_paths = $paths;
// Check all of the paths.
foreach ($paths as $path) {
// Remove path that's being processed from the front of the list.
array_shift($unreviewed_paths);
// "*" found in path.
if (strpos($path, '*') !== FALSE) {
// Look for wild card match that's not sitewide (position not zero (0))
if (strpos($path, '*') !== 0) {
$path = substr($path, 0, -2);
foreach ($unreviewed_paths as $unreviewed_path) {
if (strpos($unreviewed_path, $path) !== FALSE) {
return $path . '/*';
}
}
}
elseif (strpos($path, '*') === 0 && count($paths) > 1) {
return $path;
}
}
elseif (in_array($path, $unreviewed_paths)) {
return $path;
}
}
return FALSE;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
LookupPath:: |
public static | function | Ensure that $path starts with a forward slash. | |
LookupPath:: |
public static | function | Helper function to lookup a path alias, given a path. | |
LookupPath:: |
public static | function | Helper function to lookup a system path, given a path alias. | |
PathChecker:: |
private static | function | Lookup all alternatives to the group of paths - alias, <front>. | |
PathChecker:: |
private static | function | Compare paths to ensure each item resolves to a unique entry. | |
PathChecker:: |
public static | function | Compare target path against the project paths to confirm they're unique. | |
PathChecker:: |
public static | function | Validate the target paths. |