/** * Generates the unique slug * * @param SluggableAdapter $ea * @param object $object * @param string $preferedSlug * @param array $config[$slugField] * @return string - unique slug */ private function makeUniqueSlug(SluggableAdapter $ea, $object, $preferedSlug, $recursing = false, $config = array()) { $om = $ea->getObjectManager(); $meta = $om->getClassMetadata(get_class($object)); if (count($config) == 0) { $config = $this->getConfiguration($om, $meta->name); } // search for similar slug $result = $ea->getSimilarSlugs($object, $meta, $config, $preferedSlug); // add similar persisted slugs into account $result += $this->getSimilarPersistedSlugs($config['useObjectClass'], $preferedSlug, $config['slug']); // leave only right slugs if (!$recursing) { $this->filterSimilarSlugs($result, $config, $preferedSlug); } if ($result) { $generatedSlug = $preferedSlug; $sameSlugs = array(); foreach ((array) $result as $list) { $sameSlugs[] = $list[$config['slug']]; } $i = pow(10, $this->exponent); do { $generatedSlug = $preferedSlug . $config['separator'] . $i++; } while (in_array($generatedSlug, $sameSlugs)); $mapping = $meta->getFieldMapping($config['slug']); if (isset($mapping['length']) && strlen($generatedSlug) > $mapping['length']) { $generatedSlug = substr($generatedSlug, 0, $mapping['length'] - (strlen($i) + strlen($config['separator']))); $this->exponent = strlen($i) - 1; $generatedSlug = $this->makeUniqueSlug($ea, $object, $generatedSlug, true, $config); } $preferedSlug = $generatedSlug; } return $preferedSlug; }
/** * Generates the unique slug * * @param SluggableAdapter $ea * @param object $object * @param string $preferedSlug * @param boolean $recursing * @param array $config[$slugField] * @return string - unique slug */ private function makeUniqueSlug(SluggableAdapter $ea, $object, $preferedSlug, $recursing = false, $config = array()) { $om = $ea->getObjectManager(); $meta = $om->getClassMetadata(get_class($object)); $similarPersisted = array(); // extract unique base $base = false; if ($config['unique'] && isset($config['unique_base'])) { $base = $meta->getReflectionProperty($config['unique_base'])->getValue($object); } // collect similar persisted slugs during this flush if (isset($this->persisted[$class = $ea->getRootObjectClass($meta)])) { foreach ($this->persisted[$class] as $obj) { if ($base !== false && $meta->getReflectionProperty($config['unique_base'])->getValue($obj) !== $base) { continue; // if unique_base field is not the same, do not take slug as similar } $slug = $meta->getReflectionProperty($config['slug'])->getValue($obj); if (preg_match("@^{$preferedSlug}.*@smi", $slug)) { $similarPersisted[] = array($config['slug'] => $slug); } } } // load similar slugs $result = array_merge((array) $ea->getSimilarSlugs($object, $meta, $config, $preferedSlug), $similarPersisted); // leave only right slugs if (!$recursing) { // filter similar slugs foreach ($result as $key => $similar) { if (!preg_match("@{$preferedSlug}(\$|{$config['separator']}[\\d]+\$)@smi", $similar[$config['slug']])) { unset($result[$key]); } } } if ($result) { $generatedSlug = $preferedSlug; $sameSlugs = array(); foreach ((array) $result as $list) { $sameSlugs[] = $list[$config['slug']]; } $i = pow(10, $this->exponent); do { $generatedSlug = $preferedSlug . $config['separator'] . $i++; } while (in_array($generatedSlug, $sameSlugs)); $mapping = $meta->getFieldMapping($config['slug']); if (isset($mapping['length']) && strlen($generatedSlug) > $mapping['length']) { $generatedSlug = substr($generatedSlug, 0, $mapping['length'] - (strlen($i) + strlen($config['separator']))); $this->exponent = strlen($i) - 1; if (substr($generatedSlug, -strlen($config['separator'])) == $config['separator']) { $generatedSlug = substr($generatedSlug, 0, strlen($generatedSlug) - strlen($config['separator'])); } $generatedSlug = $this->makeUniqueSlug($ea, $object, $generatedSlug, true, $config); } $preferedSlug = $generatedSlug; } return $preferedSlug; }