| /** | |
| * Matomo - free/libre analytics platform | |
| * | |
| * @link https://matomo.org | |
| * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later | |
| */ | |
| declare(strict_types=1); | |
| namespace Piwik\Plugins\CoreHome\EntityDuplicator; | |
| class EntityDuplicatorHelper | |
| { | |
| /** | |
| * Update the provided name with a number suffix. It will either add a suffix or increment the number in the suffix. | |
| * This can be used to simplify ensuring that the name of a copied item is unique. This doesn't handle querying the | |
| * database for duplicates, so that will need to be handled case-by-case. | |
| * | |
| * @param string $name The name that needs to be updated with a number suffix. If no suffix exists, one will be | |
| * added. If one already exists, the number in the suffix will be incremented. | |
| * @param int $maxLength Optional number indicates the maximum allowed length. If adding the suffix exceeds the max, | |
| * the string will be truncated just enough to allow the suffix. Default is -1 allowing infinite length. | |
| * @return string Name with the updated number suffix | |
| * @throws \Exception If the maximum length is too small to accommodate a suffix like " (1)". | |
| */ | |
| public static function incrementNameWithNumericalSuffix(string $name, int $maxLength = -1): string | |
| { | |
| $modifiedName = $name; | |
| // First check if the name already has a number suffix | |
| $matches = []; | |
| $number = 1; | |
| if (preg_match('/ \(\d+\)$/', $name, $matches)) { | |
| // Increment the number in the name suffix | |
| $number = intval(str_replace(['(', ')'], '', $matches[0])); | |
| ++$number; | |
| $modifiedName = str_replace($matches[0], '', $name); | |
| } | |
| // Make sure that the maximum length isn't too small and won't result in the suffix replacing the whole name | |
| $newNumberLength = strlen((string) $number); | |
| if ($maxLength !== -1 && $maxLength <= $newNumberLength + 3) { | |
| throw new \Exception('The maximum name length cannot be less than the length of the suffix.'); | |
| } | |
| // Make sure that we don't exceed the max length the name fields | |
| if ($maxLength !== -1 && strlen($modifiedName . " ($number)") > $maxLength) { | |
| $modifiedName = substr($modifiedName, 0, ($maxLength - 3) - strlen((string) $number)); | |
| } | |
| $modifiedName .= " ($number)"; | |
| return $modifiedName; | |
| } | |
| /** | |
| * Takes a list of existing names and updates the provided name with a numerical suffix until it's unique. It also | |
| * truncates the name to make sure that it doesn't exceed the maximum length. | |
| * | |
| * @param string $name The name that needs to be updated with a number suffix. If no suffix exists, one will be | |
| * added. If one already exists, the number in the suffix will be incremented. | |
| * @param string[] $names List of existing names to compare against in order to provide a unique name. | |
| * @param int $maxLength Optional number indicates the maximum allowed length. If adding the suffix exceeds the max, | |
| * the string will be truncated just enough to allow the suffix. Default is -1 allowing infinite length. | |
| * @return string | |
| * @throws \Exception If the maximum length is too small". | |
| */ | |
| public static function getUniqueNameComparedToList(string $name, array $names, int $maxLength = -1) | |
| { | |
| // Make sure that the name is at least one character long | |
| if ($maxLength !== -1 && $maxLength < 1) { | |
| throw new \Exception('The maximum name length cannot be less than 1 character.'); | |
| } | |
| $newName = $name; | |
| // Make sure that the string is no more than the max length | |
| if ($maxLength !== -1 && strlen($newName) > $maxLength) { | |
| $newName = substr($newName, 0, $maxLength); | |
| } | |
| // Logically, the name should at most need to be adjusted once per listed name. | |
| for ($i = 0; $i < count($names); $i++) { | |
| if (!in_array($newName, $names)) { | |
| break; | |
| } | |
| $newName = self::incrementNameWithNumericalSuffix($newName, $maxLength); | |
| } | |
| return $newName; | |
| } | |
| } | |