Overview

Namespaces

  • Crunchmail
    • Collections
    • Entities
    • Exception
    • PHPUnit
    • Resources

Classes

  • Crunchmail\Client
  • Crunchmail\Collections\GenericCollection
  • Crunchmail\Entities\AttachmentEntity
  • Crunchmail\Entities\ContactEntity
  • Crunchmail\Entities\ContactListEntity
  • Crunchmail\Entities\ContactQueueEntity
  • Crunchmail\Entities\DomainEntity
  • Crunchmail\Entities\GenericEntity
  • Crunchmail\Entities\MessageEntity
  • Crunchmail\Entities\RecipientEntity
  • Crunchmail\PHPUnit\IsEntityConstraint
  • Crunchmail\PHPUnit\IsGenericCollectionConstraint
  • Crunchmail\PHPUnit\IsGenericEntityConstraint
  • Crunchmail\PHPUnit\IsGenericResourceConstraint
  • Crunchmail\PHPUnit\IsResourceConstraint
  • Crunchmail\PHPUnit\TestCase
  • Crunchmail\Resources\DomainsResource
  • Crunchmail\Resources\GenericResource
  • Crunchmail\Resources\PreviewSendResource

Exceptions

  • Crunchmail\Exception\ApiException
  • Overview
  • Namespace
  • Class
  1: <?php
  2: /**
  3:  * Generic entity
  4:  *
  5:  * @author    Yannick Huerre <dev@sheoak.fr>
  6:  * @copyright 2015 (c) Oasiswork
  7:  * @license   https://opensource.org/licenses/MIT MIT
  8:  */
  9: namespace Crunchmail\Entities;
 10: 
 11: use Crunchmail\Client;
 12: use Crunchmail\Resources\GenericResource;
 13: 
 14: /**
 15:  * Generic entity class
 16:  */
 17: class GenericEntity
 18: {
 19:     /**
 20:      * Caller resource
 21:      *
 22:      * @var object
 23:      */
 24:     protected $_resource;
 25: 
 26:     /**
 27:      * Entity body
 28:      *
 29:      * @var stdClass
 30:      */
 31:     protected $_body;
 32: 
 33:     protected static $exposeLinks = [];
 34: 
 35:     /**
 36:      * Links remapping
 37:      *
 38:      * @var array
 39:      */
 40:     protected static $links = [
 41:         'recipients'   => 'mails'
 42:     ];
 43: 
 44:     /**
 45:      * Resource mapping
 46:      *
 47:      * @var array
 48:      */
 49:     protected static $resources = [];
 50: 
 51:     /**
 52:      * Some links could lead to confusion, because they would not return
 53:      * a proper resource: let's blacklist them
 54:      *
 55:      * Untested resources are also here
 56:      *
 57:      * @var array
 58:      */
 59:     private static $blacklistLinks = [
 60:         'preview.html',
 61:         'preview.txt'
 62:     ];
 63: 
 64:     /**
 65:      * Create a new entity
 66:      *
 67:      * @param GenericResource $resource caller resource
 68:      * @param stdClass $data entity data
 69:      *
 70:      * @return Crunchmail\Entity\GenericEntity
 71:      */
 72:     public function __construct(GenericResource $resource, $data)
 73:     {
 74:         $this->_resource = $resource;
 75:         $this->_body     = $data;
 76:     }
 77: 
 78:     /**
 79:      * Generic conversion to string
 80:      *
 81:      * @return string
 82:      */
 83:     public function __toString()
 84:     {
 85:         return isset($this->_body->url) ? $this->url : '';
 86:     }
 87: 
 88:     /**
 89:      * Return Entity body
 90:      *
 91:      * @return stdClass
 92:      */
 93:     public function getBody()
 94:     {
 95:         if (empty((array) $this->_body))
 96:         {
 97:             return null;
 98:         }
 99: 
100:         $copy = clone $this->_body;
101:         unset($copy->_links);
102: 
103:         foreach (static::$exposeLinks as $key)
104:         {
105:             $copy->$key = $this->getLink($key);
106:         }
107:         return $copy;
108:     }
109: 
110:     /**
111:      * Catch get, post, put… methods
112:      *
113:      * @param string $name method name
114:      * @param array $args arguments
115:      *
116:      * @return Crunchmail\Entity\GenericEntity
117:      *
118:      * @method mixed get()    get() get entity (refresh)
119:      * @method mixed delete() delete() delete entity
120:      * @method mixed post()   post(array $values, string $format='json')   post values
121:      * @method mixed put()    put(array $values, string $format='json')    put values
122:      * @method mixed patch()  patch(array $values, string $format='json')  patch values
123:      */
124:     public function __call($method, $args)
125:     {
126:         if (!isset($this->_body->url))
127:         {
128:             throw new \RuntimeException('Entity has no url');
129:         }
130: 
131:         // allow use of rest actions, if a link is actually an action
132:         // and not a classic rest resource.
133:         // ex: $queue->consume() instead of $queue->consume->post()
134:         if (isset($this->_body->_links) &&
135:             array_key_exists($method, (array) $this->_body->_links))
136:         {
137:             return call_user_func_array([$this->$method, 'post'], $args);
138:         }
139: 
140:         return $this->_resource->callRequest($method, $args, $this->url);
141:     }
142: 
143:     /**
144:      * Access entity or resources with object properties
145:      *
146:      * Note that this technic could lead to conflict if a resource and a body
147:      * field have the same name
148:      *
149:      * Ex:
150:      * echo $message->title
151:      * $arr = $message->recipients->current();
152:      *
153:      * @param string $name resource name
154:      *
155:      * @return mixed resource
156:      */
157:     public function __get($name)
158:     {
159:         // forbidden resource ie. : $entity->forbidden->post();
160:         if (in_array($name, self::$blacklistLinks))
161:         {
162:             throw new \RuntimeException('Direct access to ' . $name . ' is
163:                 prohibited');
164:         }
165: 
166:         $body = $this->getBody();
167: 
168:         if (is_null($body))
169:         {
170:             throw new \RuntimeException('Entity body is empty');
171:         }
172: 
173:         // shortcut to body fields, when no resource was found
174:         // ex: echo $entity->fielname;
175:         if (property_exists($body, $name))
176:         {
177:             return $body->$name;
178:         }
179: 
180:         // a subresource was found, create and return it
181:         // assign url to the subresource url (may need mapping)
182:         if ($url = $this->getLink($name))
183:         {
184:             $resourceName = $this->getResourceName($name);
185:             // save it to $this->$name, no need to create a new one each time
186:             $this->$name = $this->_resource->client->createResource(
187:                 $resourceName,
188:                 $url
189:             );
190:             return $this->$name;
191:         }
192: 
193:         throw new \RuntimeException('Entity has no resource "' . $name . '"');
194:     }
195: 
196:     /**
197:      * Check if the resource name is registered has belonging to a special
198:      * resource class, ie. 'ContactList'
199:      *
200:      * @param string $name resource name
201:      * @return string
202:      */
203:     private function getResourceName($name)
204:     {
205:         return isset(static::$resources[$name]) ? static::$resources[$name] : $name;
206:     }
207: 
208:     /**
209:      * Allow use of isset on _body fields
210:      *
211:      * @param string $key key to check
212:      *
213:      * @return boolean
214:      */
215:     public function __isset($key)
216:     {
217:         return isset($this->_body->$key);
218:     }
219: 
220:     /**
221:      * Allow use of isset on _body fields
222:      *
223:      * @param string $key key to check
224:      *
225:      * @return boolean
226:      */
227:     public function __unset($key)
228:     {
229:         throw new \RuntimeException('unset() is disabled');
230:     }
231: 
232:     /**
233:      * Get the content of the links attribute, mapping the name first
234:      *
235:      * @param string $name name of the field
236:      *
237:      * @return string
238:      */
239:     public function getLink($name)
240:     {
241:         // access to collections
242:         $map = isset(self::$links[$name]) ? self::$links[$name] : $name;
243: 
244:         return isset($this->_body->_links->$map) ?
245:             $this->_body->_links->$map->href : null;
246:     }
247: }
248: 
API documentation generated by ApiGen