Skip to content

Instantly share code, notes, and snippets.

@basherr
Last active June 1, 2021 00:34
Show Gist options
  • Save basherr/4f5d5fef9213587120a96988162d29bb to your computer and use it in GitHub Desktop.
Save basherr/4f5d5fef9213587120a96988162d29bb to your computer and use it in GitHub Desktop.
/// PRODUCT Data type
<?php
namespace App\DataTypes;
/**
* class Product
*
* Represent the Product type for the shopbot
*
* @package App\DataTypes
*/
class Product extends PropertyAccessor
{
/**
* @var string
*/
protected $sku;
/**
* @var string
*/
protected $title;
/**
* @var string
*/
protected $image;
/**
* @var string
*/
protected $link;
}
/// Default Property Accessor class
namespace App\DataTypes;
/**
* class PropertyAccessor
*
* Retrieve/changes any property of the class dynmically without the need for
* setters & getters
*
* To set `foo` property for a class, just call `setFoo` method on object instance
* where `Foo` first character will be converted to lowercase
*
* @package App\DataTypes
*/
abstract class PropertyAccessor
{
/**
* Set any property for the class dynamically
*
* @param string $name
* @param mixed $value
* @return $this
*/
public function __call(string $name, $value)
{
if (substr($name, 0, 3) === 'set') {
return $this->setProperty($name, $value);
} else if (substr($name, 0, 3) === 'get') {
return $this->getProperty($name);
}
}
/**
* Set any property for the class
*
* @param string $name
* @param mixed $value
* @return $this
* @throws \App\Exception\InvalidSetterException
*/
protected function setProperty(string $name, $value)
{
$property = lcfirst(str_replace('set', '', $name));
if (property_exists($this, $property)) {
$this->$property = array_shift($value);
return $this;
}
throw new \Exception('Invalid Property Setter');
}
/**
* Retrieve any property for the class dynamically
*
* @param string $name
* @return mixed
* @throws \App\Exception\InvalidGetterException
*/
public function getProperty(string $name)
{
$property = lcfirst(str_replace('get', '', $key));
if (property_exists($this, $property)) {
return $this->$property;
}
throw new \Exception('Invalid Property Getter');
}
}
@basherr
Copy link
Author

basherr commented Jun 1, 2021

@brentkelly Why Product should be abstract? How we will instantiate an abstract class Product? What I believe it should implement a contract to hydrate or extend a base abstract class that contains hydrate method as abstract.

@brentkelly
Copy link

Because Zest isn't going to be the only Connector we have long term. It should be App\ApiModels\AbstractProduct which defines 90% of the class, but then there needs to be a connector implementation for Zest which tells it how to hydrate from a API result.

So \App\Connectors\Zest\ApiModels\Product extends App\ApiModels\AbstractProduct & probably has 1 method:

  • hydrate($productData) - this receives a raw API product data & hydrates the properties defined in AbstractProduct.

Then in future when we want to connect to e.g. Shopify, we will have a \App\Connectors\Shopify\Product which will extend AbstractProduct, and its hydrate method will take a Shopify product API result & translate it to hydrate the AbstractProduct properties.

@basherr
Copy link
Author

basherr commented Jun 1, 2021

@brentkelly Perfect, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment