Skip to content

Commit

Permalink
update file
Browse files Browse the repository at this point in the history
  • Loading branch information
juancristobalgd1 authored Jan 24, 2024
1 parent a0bc3bd commit 0cacf26
Showing 1 changed file with 43 additions and 61 deletions.
104 changes: 43 additions & 61 deletions src/Fluent.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use ReflectionException;
use InvalidArgumentException;
use Illuminate\Support\Collection;
use RuntimeException;

/**
* Class Fluent
Expand All @@ -22,8 +23,8 @@
*
* The Fluent class provides a fluent interface to facilitate method chaining and flow control
* in your PHP applications. and flow control in your PHP applications. You can use this class to perform a variety
* of operations by chaining methods in a concise and readable way. */

* of operations by chaining methods in a concise and readable way.
*/
class Fluent
{
private $obj;
Expand All @@ -32,19 +33,15 @@ class Fluent
private $isReturn = false;
private $customMethods = [];


/**
* Constructor that accepts a class name or object.
*
* @param mixed $obj The class name or object to work with.
* @throws InvalidArgumentException If the argument is not a valid class name or object.
*/
public function __construct($data)
public function __construct(string|object|array $data)
{
// Validate that $data is a string, an object or an array
if (!is_string($data) && !is_object($data) && !is_array($data)) {
throw new InvalidArgumentException("Invalid argument. Expected class name, object, or array.");
}

$this->createInstance($data);
}

Expand All @@ -54,15 +51,15 @@ public function __construct($data)
* @param mixed $data The argument to be used to create the instance.
* @return void
*/
private function createInstance($data)
private function createInstance(string|object|array $data)
{
if (is_string($data) && class_exists($data)) {
$this->obj = new $data();
} elseif (is_object($data)) {
$this->obj = $data;
} elseif (is_array($data)) {
$this->obj = new Collection($data);
}
$this->obj = match (true) {
is_string($data) && class_exists($data) => new $data(),
is_object($data) => $data,
is_array($data) => new Collection($data),
};

$this->result[get_class($this->obj)] = $this->obj;
}

/**
Expand All @@ -72,14 +69,11 @@ private function createInstance($data)
* @param bool $return Whether to return the created object or $this.
* @return $this|object
*/
public function new($data, bool $return = true): Fluent
public function new(string|object|array $data, bool $return = true): Fluent
{
if (!is_string($data) && !is_object($data) && !is_array($data)) {
throw new InvalidArgumentException("Invalid argument. Expected class name, object, or array.");
}

if ($this->condition && !$this->isReturn) {
$this->createInstance($data);

return $return ? $this->obj : $this;
}
}
Expand All @@ -101,9 +95,9 @@ public function get(string $key = null)
{
if ($key !== null && array_key_exists($key, $this->result)) {
return $this->result[$key];
} else {
return end($this->result);
}

return end($this->result);
}

/**
Expand Down Expand Up @@ -158,7 +152,7 @@ public function getProperty($name)
return $this->obj->$name;
}

throw new Exception("The property '$name' does not exist on the object " . get_class($this->obj));
throw new InvalidArgumentException(sprintf('The property [ %s ] does not exist on the object [ %s ] .', $name, get_class($this->obj)));
}

/**
Expand All @@ -175,7 +169,7 @@ public function setProperty($name, $value)
return $this;
}

throw new Exception("The property '$name' does not exist on the object " . get_class($this->obj));
throw new InvalidArgumentException(sprintf('The property [ %s ] does not exist on the object [ %s ] .', $name, get_class($this->obj)));
}

/**
Expand Down Expand Up @@ -319,7 +313,7 @@ public function reflect($className, ...$constructorArgs)
$reflection = new ReflectionClass($className);
$this->result['reflect'] = $reflection->newInstanceArgs($constructorArgs);
} catch (ReflectionException $e) {
throw new Exception("Error creating instance of $className: " . $e->getMessage());
throw new InvalidArgumentException(sprintf('Error creating instance of %s: [ %s ] .', $className, $e->getMessage()));
}
}

Expand All @@ -341,7 +335,7 @@ public function loop(callable $callback, $iterations)
try {
$this->result['loop'] = $callback($i);
} catch (Exception $e) {
throw new Exception("Error in loop iteration $i: " . $e->getMessage());
throw new InvalidArgumentException(sprintf('Error in loop iteration %s: [ %s ] .', $i, $e->getMessage()));
}
}
}
Expand Down Expand Up @@ -398,8 +392,7 @@ public function write($value = null)
}

/**
* addCustomMethod the Fluent with custom methods.
*
* The Fluent with custom methods.
* @param callable $extension A closure that defines the new method.
*/
public function addCustomMethod($method, $callback)
Expand Down Expand Up @@ -445,35 +438,12 @@ public function __call($name, $arguments): Fluent
if ($this->condition && !$this->isReturn) {
$result = null;

// Check if the method exists in the Collection object
if ($this->obj instanceof Collection) {
if (method_exists($this->obj, $name)) {
$result = call_user_func_array([$this->obj, $name], $arguments);
} else {
throw new InvalidArgumentException("El método '$name' no existe en el contexto Collection.");
}
}

// Check if the method exists in the custom methods
elseif (array_key_exists($name, $this->customMethods)) {
$result = call_user_func_array($this->customMethods[$name], $arguments);
}
$result = match (true) {
$this->obj instanceof Collection, is_callable([$this->obj, $name]) => $this->callMethod($this->obj, $name, $arguments),
array_key_exists($name, $this->customMethods) => call_user_func_array($this->customMethods[$name], $arguments),

// Check if the method exists in the methods of the Class passed as argument
elseif (is_callable([$this->obj, $name])) {
if (method_exists($this->obj, $name)) {
$result = call_user_func_array([$this->obj, $name], $arguments);
} else {
throw new InvalidArgumentException("El método '$name' no existe en el contexto." . get_class($this->obj));
}
}

// Check if the method exists in the Fluent methods
elseif (method_exists($this, $name)) {
$result = call_user_func_array([$this, $name], $arguments);
} else {
throw new InvalidArgumentException("El método '$name' no existe en el contexto Fluent.");
}
default => $this->callMethod($this, $name, $arguments),
};

if ($result !== null) {
$this->result[$name] = $result;
Expand All @@ -483,6 +453,18 @@ public function __call($name, $arguments): Fluent
return $this;
}

/**
* Method to call a method on a service
*/
private function callMethod(Object $obj, string $method, $arguments)
{
if (method_exists($obj, $method)) {
return call_user_func_array([$obj, $method], $arguments);
}
// If the method does not exist, throw an exception
throw new InvalidArgumentException(sprintf('The method [ %s ] does not exist in the Collection context.', $method));
}

/**
* Magic method to get a service by property access.
*
Expand All @@ -494,8 +476,8 @@ public function __get($name)
if (property_exists($this->obj, $name)) {
return $this->obj->$name;
}

throw new Exception("The property '$name' does not exist on the object " . get_class($this->obj));
// If the property does not exist, throw an exception
throw new RuntimeException(sprintf('The property [ %s ] does not exist on the object [ %s ]', $name, get_class($this->obj)));
}

/**
Expand All @@ -509,8 +491,8 @@ public function __set($name, $value)
if (property_exists($this->obj, $name)) {
return $this->obj->$name = $value;
}

throw new Exception("The property '$name' does not exist on the object " . get_class($this->obj));
// If the property does not exist, throw an exception
throw new RuntimeException(sprintf('The property [ %s ] does not exist on the object [ %s ]', $name, get_class($this->obj)));
}

/**
Expand Down

0 comments on commit 0cacf26

Please sign in to comment.