Overview

Namespaces

  • PipelinerSales
    • ApiClient
      • Http
      • Query
      • Repository
        • Rest

Classes

  • Criteria
  • Filter
  • Sort
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * This file is part of the Pipeliner API client library for PHP
  4:  *
  5:  * Copyright 2014 Pipelinersales, Inc. All Rights Reserved.
  6:  * For the full license information, see the attached LICENSE file.
  7:  */
  8: 
  9: namespace PipelinerSales\ApiClient\Query;
 10: 
 11: use PipelinerSales\ApiClient\Defaults;
 12: 
 13: /**
 14:  * Represents the query parameters for loading entities.
 15:  *
 16:  * For details, see the {@link
 17:  * http://workspace.pipelinersales.com/community/api/data/Querying_rest.html
 18:  * API documentation on querying}.
 19:  *
 20:  * @method static Criteria limit($limit) Limits how many entities to load. Use the NO_LIMIT constant to disable limits.
 21:  * @method static Criteria offset($offset)
 22:  * @method static Criteria sort($sort) Set sorting of the result, either by using a raw string (see API documentation) or a Sort object
 23:  * @method static Criteria filter($filter) Only return entities which conform to the specified filter - either a raw string (see API documentation) or a Filter object
 24:  * @method static Criteria after($after) Only load entities modified after the date, specified as either a string or a DateTime object
 25:  * @method static Criteria loadonly($loadonly) Only load the specified fields, specified as either an array or a string separated with |
 26:  */
 27: class Criteria
 28: {
 29: 
 30:     private static $properties = array(
 31:         'limit' => 'setLimit',
 32:         'offset' => 'setOffset',
 33:         'sort' => 'setSort',
 34:         'filter' => 'setFilter',
 35:         'after' => 'setAfter',
 36:         'loadonly' => 'setLoadOnly'
 37:     );
 38:     private $limit = null;
 39:     private $offset = null;
 40:     private $sort = null;
 41:     private $filter = null;
 42:     private $after = null;
 43:     private $loadonly = null;
 44:     private $dateTimeFormat;
 45:     private $defaultLimit;
 46: 
 47:     /**
 48:      * Disable the limit on how many entities to load. Please use with caution.
 49:      */
 50:     const NO_LIMIT = -1;
 51: 
 52:     /**
 53:      * Creates a new set of criteria.
 54:      * @param mixed $criteria initial criteria to use, see {@see set}
 55:      * @param string $dateTimeFormat format to use for converting DateTime objects
 56:      */
 57:     public function __construct($criteria = array(), $dateTimeFormat = Defaults::DATE_FORMAT, $defaultLimit = Defaults::DEFAULT_LIMIT)
 58:     {
 59:         $this->dateTimeFormat = $dateTimeFormat;
 60:         $this->defaultLimit = $defaultLimit;
 61:         $this->set($criteria);
 62:     }
 63: 
 64:     /**
 65:      * Returns the resulting url-encoded query string.
 66:      * @return string
 67:      */
 68:     public function toUrlQuery()
 69:     {
 70:         $queryData = array();
 71:         foreach (self::$properties as $p => $setter) {
 72:             if ($this->$p !== null) {
 73:                 $queryData[$p] = $this->$p;
 74:             }
 75:         }
 76:         return http_build_query($queryData);
 77:     }
 78: 
 79:     /**
 80:      * Returns the currently set limit. Null will be returned if the limit is not set.
 81:      * @return integer|null
 82:      */
 83:     public function getLimit()
 84:     {
 85:         return $this->limit;
 86:     }
 87: 
 88:     /**
 89:      * Returns the currently set limit, or the default limit if none is set.
 90:      * @return integer
 91:      */
 92:     public function getEffectiveLimit()
 93:     {
 94:         if ($this->limit === null) {
 95:             return $this->defaultLimit;
 96:         }
 97:         return $this->limit;
 98:     }
 99: 
100:     /**
101:      * @param integer $limit
102:      * @return Criteria
103:      */
104:     private function setLimit($limit)
105:     {
106:         $this->limit = $limit;
107:         return $this;
108:     }
109: 
110:     /**
111:      * Returns the currently set offset. Null will be returned if no offset is set.
112:      * @return integer|null
113:      */
114:     public function getOffset()
115:     {
116:         return $this->offset;
117:     }
118: 
119:     /**
120:      * Returns the currently set offset, or the default offset 0 if no offset is set.
121:      * @return integer
122:      */
123:     public function getEffectiveOffset()
124:     {
125:         if ($this->offset === null) {
126:             return 0;
127:         }
128:         return $this->getOffset();
129:     }
130: 
131:     /**
132:      * @param integer $offset
133:      * @return Criteria
134:      */
135:     private function setOffset($offset)
136:     {
137:         $this->offset = $offset;
138:         return $this;
139:     }
140: 
141:     /**
142:      * @return string|null
143:      */
144:     public function getSort()
145:     {
146:         return $this->sort;
147:     }
148: 
149:     /**
150:      * @param string|Sort
151:      * @return Criteria
152:      */
153:     public function setSort($sort)
154:     {
155:         if ($sort instanceof Sort) {
156:             $this->sort = $sort->getString();
157:         } else {
158:             $this->sort = $sort;
159:         }
160:         return $this;
161:     }
162: 
163:     /**
164:      * Returns the currently set filter string.
165:      * @return string|null
166:      */
167:     public function getFilter()
168:     {
169:         return $this->filter;
170:     }
171: 
172:     /**
173:      * @param Filter|string
174:      * @return Criteria
175:      */
176:     private function setFilter($filter)
177:     {
178:         if ($filter instanceof Filter) {
179:             $this->filter = $filter->getString();
180:         } else {
181:             $this->filter = $filter;
182:         }
183:         return $this;
184:     }
185: 
186:     /**
187:      * @return string|null
188:      */
189:     public function getAfter()
190:     {
191:         return $this->after;
192:     }
193: 
194:     /**
195:      * @param string|\DateTime $after
196:      * @return Criteria
197:      */
198:     private function setAfter($after)
199:     {
200:         if (is_string($after)) {
201:             $this->after = $after;
202:         } elseif ($after instanceof \DateTime) {
203:             $afterCopy = clone $after;
204:             $afterCopy->setTimezone(new \DateTimeZone('UTC'));
205:             $this->after = $afterCopy->format($this->dateTimeFormat);
206:         }
207:         return $this;
208:     }
209: 
210:     /**
211:      * @return string|null
212:      */
213:     public function getLoadOnly()
214:     {
215:         return $this->loadonly;
216:     }
217: 
218:     /**
219:      * @param string|array
220:      * @return Criteria
221:      */
222:     private function setLoadOnly($loadonly)
223:     {
224:         if (is_string($loadonly)) {
225:             $this->loadonly = $loadonly;
226:         } elseif (is_array($loadonly)) {
227:             $this->loadonly = implode('|', $loadonly);
228:         }
229:         return $this;
230:     }
231: 
232:     /**
233:      * Sets multiple parameters at once.
234:      *
235:      * @param mixed $criteria Can be one of the following:
236:      * <ul>
237:      * <li>Another Criteria object - copies that object's criteria into this one.
238:      * Competely replaces the current object's values, unsetting those which have not been
239:      * set in $criteria</li>
240:      * <li>An array - sets the parameters present in the array. Parameters not present
241:      * in the array will <b>not</b> be unset. If you wish to unset certain parameters,
242:      * set them to null in the array.</li>
243:      * <li>A string - the resulting query string (without a leading question mark),
244:      * will be parsed back into the individual parameters and processed like an array.</li>
245:      * </ul>
246:      */
247:     public function set($criteria)
248:     {
249:         if ($criteria instanceof Criteria) {
250:             //this is much faster than using the same method that's used for arrays (see below)
251:             $this->limit = $criteria->limit;
252:             $this->offset = $criteria->offset;
253:             $this->sort = $criteria->sort;
254:             $this->filter = $criteria->filter;
255:             $this->after = $criteria->after;
256:             $this->loadonly = $criteria->loadonly;
257:         } elseif (is_string($criteria)) {
258:             //parse the string into an array and then parse the array
259:             $criteria = $this->parseHttpQuery($criteria);
260:         }
261: 
262:         if (is_array($criteria)) {
263:             foreach (self::$properties as $p => $setter) {
264:                 if (isset($criteria[$p])) {
265:                     $this->$setter($criteria[$p]);
266:                 }
267:             }
268:         }
269:     }
270: 
271:     /**
272:      * Parses a http query into a key-value array, similar to PHP's parse_str function.
273:      * @param string $query query string (without a leading question mark)
274:      * @return array
275:      */
276:     private function parseHttpQuery($query)
277:     {
278:         /* can't use parse_str, because the minimum supported PHP version
279:          * is 5.3, which still has the magic_quotes_gpc option that affects its
280:          * result, so some users could hypothetically have that enabled */
281:         if (empty($query)) {
282:             return array();
283:         }
284: 
285:         $result = array();
286:         $parts = explode('&', $query);
287:         foreach ($parts as $p) {
288:             $keyval = explode('=', $p);
289:             $result[urldecode($keyval[0])] = urldecode($keyval[1]);
290:         }
291:         return $result;
292:     }
293: 
294:     public static function __callStatic($name, $arguments)
295:     {
296:         if (isset(self::$properties[$name])) {
297:             return new Criteria(array( $name => $arguments[0] ));
298:         }
299:         throw new \BadMethodCallException('Call to a non-existent static method \'' . $name . '\'');
300:     }
301: 
302:     public function __call($name, $arguments)
303:     {
304:         if (isset(self::$properties[$name])) {
305:             $setter = self::$properties[$name];
306:             $this->$setter($arguments[0]);
307:             return $this;
308:         }
309:         throw new \BadMethodCallException('Call to a non-existent method \'' . $name . '\'');
310:     }
311: }
312: 
API documentation generated by ApiGen