add($feature); } } /** * @param string $className Full-qualified class name * * @return bool */ public function has($className) { $this->ensureClassNameParameter($className, __METHOD__); foreach ($this->features as $feature) { if (get_class($feature) === $className) { return true; } } return false; } /** * @param string $className Full-qualified class name * * @throws FeatureNotFoundException * * @return DataTableFeatureInterface */ public function get($className) { $this->ensureClassNameParameter($className, __METHOD__); foreach ($this->features as $feature) { if (get_class($feature) === $className) { return $feature; } } throw new FeatureNotFoundException(sprintf('Feature class "%s" not found.', $className)); } /** * @return array|DataTableFeatureInterface[] */ public function all() { return $this->features; } /** * Adds a new feature * * @param DataTableFeatureInterface $feature * * @throws FeatureExistsException If feature with same type already exists * * @return void */ public function add(DataTableFeatureInterface $feature) { if ($this->has(get_class($feature))) { throw new FeatureExistsException(sprintf('Feature class "%s" already exists', get_class($feature))); } $this->features[] = $feature; } /** * Sets a feature; If feature with same type exists, it will be overwritten. * * @param DataTableFeatureInterface $feature * * @return void */ public function set(DataTableFeatureInterface $feature) { $this->remove(get_class($feature)); $this->features[] = $feature; } /** * @param string|object $className Full-qualified class name * * @return bool */ public function remove($className) { $this->ensureClassNameParameter($className, __METHOD__); foreach ($this->features as $index => $feature) { if (get_class($feature) === $className) { unset($this->features[$index]); return true; } } return false; } /** * @return void */ public function removeAll() { $this->features = []; } /** * @return ArrayIterator|Traversable */ public function getIterator() { return new ArrayIterator($this->features); } /** * Deep copy object * * @return void */ public function __clone() { foreach ($this->features as $index => $column) { $this->features[$index] = clone $column; } } /** * @param mixed $className * @param string $callerName * * @throws InvalidArgumentException * * @return void */ protected function ensureClassNameParameter($className, $callerName) { if (!is_string($className)) { throw new InvalidArgumentException(sprintf( 'Parameter "className" in method "%s" has to be a class name.', $callerName )); } if (!class_exists($className, true)) { throw new InvalidArgumentException(sprintf( '"%s" is not a valid class.', $className )); } } }