Skip to content

Instantly share code, notes, and snippets.

@basherr
Last active June 16, 2021 03:21
Show Gist options
  • Save basherr/338f1ca5e96141f9c0e9934be59f344e to your computer and use it in GitHub Desktop.
Save basherr/338f1ca5e96141f9c0e9934be59f344e to your computer and use it in GitHub Desktop.
<?php
namespace App\Connectors\Zest\ApiModels;
use App\ApiModels\Category as BaseCategory;
/**
* class Category
*
* Convert API response to App\ApiModels\Category
*
* @package App\Connectors\Zest\ApiModels
*/
class Category extends BaseCategory
{
/**
* Fill the class properties using API response
*
* @param \Illuminate\Support\Collection $category
* @return $this
*/
public function hydrate($category)
{
return $this->setCode($category->get('code'))
->setName($category->get('name'))
->setImage($category->get('image'))
->setLink($category->get('link'))
->setDescription($category->get('description'));
}
}
?>
///////////////////////////// BASE CATEGORY API MODEL //////////////////////////////
<?php
namespace App\ApiModels;
/**
* class Category
*
* Represent the Category type for the shopbot
*
* @package App\ApiModels
*/
abstract class Category extends BaseApiModel
{
/**
* @var string
*/
protected $code;
/**
* @var string
*/
protected $name;
/**
* @var string
*/
protected $image;
/**
* @var string
*/
protected $link;
/**
* @var string
*/
protected $description;
/**
* @var float|string
*/
protected $total;
/**
* @var App\ApiModels\ProductsCollection
*/
protected $products;
}
?>
///////////////////////// THE DEFAULT BASE API MODEL FOR ALL ///////////////////////////////////
<?php
namespace App\ApiModels;
use App\Traits\CanAccessProperties;
/**
* class BaseApiModel
*
* The base class for all the models
*
* @package App\ApiModels
*/
abstract class BaseApiModel
{
use CanAccessProperties;
/**
* Create an object from API response
*
* @param mixed $incoming
* @return mixed
*/
public abstract function hydrate($incoming);
}
@brentkelly
Copy link

I think we should have a couple of extra methods in AbstractApiModel:

  • set - lets you set multiple properties in one go
  • copyProperties - receives an instance & a list of property names, and mirrors those properties out of the passed instance
/**
 * Set multiple properties in one go
 *
 * @param array|\Illuminate\Support\Collection $values key value pairs - keys representing properties to set
 * @return $this
 */
public function set($values)
{
    foreach ($values as $key => $value) {
        $this->$key = $value;
    }

    return $this;
}

/**
  * Copy properties - copies a list of properties out of a passed instance into the current model
  *
  * @param object $instance instance to copy properties out of
  * @param array $properties a list of properties to copy over
  * @return $this;
  */
public function copyProperties($instance, $properties)
{
    $values = collect($properties)
        ->mapWithKeys(function($property) use ($instance) {
            return [$property => $instance[$property]];
        });

    return $this->set($values);
}

Your hydrate docs should be updated to return $this so it can be chained.

Now your hydrate can look like this:

    /**
     * Create an object from API response
     *
     * @param mixed $incoming
     * @return $this
     */
    public abstract function hydrate($incoming)
    {
        return $this->copyProperties($incoming, [
            'code',
            'name',
            'image',
            'link',
            'description',
        ]);

        // old way
        // $this->set([
        //     'code' => $category->get('code'),
        //     'name' => $category->get('name'),
        //     'image' => $category->get('image'),
        //     'link' => $category->get('link'),
        //     'description' => $category->get('description'),
        // ]);
    }

This makes the code easier to read & cuts out all the boilerplate

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