Overview

Packages

  • Pinoco
    • PAL

Classes

  • Pinoco
  • Pinoco_Delegate
  • Pinoco_DynamicVars
  • Pinoco_HttpRequestVars
  • Pinoco_List
  • Pinoco_MIMEType
  • Pinoco_NativeRenderer
  • Pinoco_NothingVars
  • Pinoco_NullRenderer
  • Pinoco_OptionalParam
  • Pinoco_Pagination
  • Pinoco_PDOStatementWrapper
  • Pinoco_PDOWrapper
  • Pinoco_Renderer
  • Pinoco_Router
  • Pinoco_TALRenderer
  • Pinoco_TestEnvironment
  • Pinoco_Validator
  • Pinoco_ValidatorContext
  • Pinoco_Vars

Interfaces

  • Pinoco_ArrayConvertible

Functions

  • __pinoco_autoload_impl
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Pinoco: makes existing static web site dynamic transparently.
  4:  * Copyright 2010-2012, Hisateru Tanaka <tanakahisateru@gmail.com>
  5:  *
  6:  * Licensed under The MIT License
  7:  * Redistributions of files must retain the above copyright notice.
  8:  *
  9:  * PHP Version 5
 10:  *
 11:  * @author     Hisateru Tanaka <tanakahisateru@gmail.com>
 12:  * @copyright  Copyright 2010-2012, Hisateru Tanaka <tanakahisateru@gmail.com>
 13:  * @license    MIT License (http://www.opensource.org/licenses/mit-license.php)
 14:  * @package    Pinoco
 15:  */
 16: 
 17: /**
 18:  * Variable model
 19:  *
 20:  * @package Pinoco
 21:  */
 22: class Pinoco_Vars implements IteratorAggregate, ArrayAccess, Countable, Pinoco_ArrayConvertible
 23: {
 24:     private $_vars;
 25:     private $_default_val;
 26:     private $_loose;
 27: 
 28:     /**
 29:      * Constructor to make an empty instance.
 30:      */
 31:     public function __construct()
 32:     {
 33:         $this->_vars = array();
 34:         $this->_default_val = null;
 35:         $this->_loose = false;
 36:     }
 37: 
 38:     /**
 39:      * Makes a new object from Array.
 40:      *
 41:      * @param mixed $src
 42:      * @return Pinoco_Vars
 43:      */
 44:     public static function fromArray($src)
 45:     {
 46:         $self = new Pinoco_Vars();
 47:         $self->import($src);
 48:         return $self;
 49:     }
 50: 
 51:     /**
 52:      * Wraps an existing Array.
 53:      *
 54:      * @param array &$srcref
 55:      * @throws InvalidArgumentException
 56:      * @return Pinoco_Vars
 57:      */
 58:     public static function wrap(&$srcref)
 59:     {
 60:         if (!is_array($srcref)) {
 61:             throw new InvalidArgumentException("Non array variable was given.");
 62:         }
 63:         $self = new Pinoco_Vars();
 64:         $self->_vars = &$srcref;
 65:         return $self;
 66:     }
 67: 
 68:     /**
 69:      * Returns a value or default by name.
 70:      *
 71:      * @param string $name
 72:      * @param mixed $default
 73:      * @return mixed
 74:      */
 75:     public function get($name, $default=Pinoco_OptionalParam::UNSPECIFIED)
 76:     {
 77:         if (array_key_exists($name, $this->_vars)) {
 78:             $r = $this->_vars[$name];
 79:             if ($r instanceof Pinoco_ValueProxy) {
 80:                 $r = $r->fetch();
 81:             }
 82:             return $r;
 83:         }
 84:         else {
 85:             return Pinoco_OptionalParam::isSpecifiedBy($default) ? $default : $this->_default_val;
 86:         }
 87:     }
 88: 
 89:     /**
 90:      * Returns a value or default by tree expression.
 91:      *
 92:      * @param string $expression
 93:      * @param mixed $default
 94:      * @return mixed
 95:      */
 96:     public function rget($expression, $default=Pinoco_OptionalParam::UNSPECIFIED)
 97:     {
 98:         $default = Pinoco_OptionalParam::isSpecifiedBy($default) ? $default : $this->_default_val;
 99:         $es = explode('/', $expression);
100:         $v = $this;
101:         while (count($es) > 0) {
102:             $name = trim(array_shift($es));
103:             if ($name === "") {
104:                 continue;
105:             }
106:             if ($v instanceof Pinoco_ArrayConvertible) {
107:                 $v = $v->get($name, $default);
108:             }
109:             elseif (is_object($v)) {
110:                 if (property_exists($v, $name)) {
111:                     $v = $v->$name;
112:                 }
113:                 else {
114:                     return $default;
115:                 }
116:             }
117:             elseif (is_array($v)) {
118:                 if (array_key_exists($name, $v)) {
119:                     $v = $v[$name];
120:                 }
121:                 else {
122:                     return $default;
123:                 }
124:             }
125:             else {
126:                 return $default;
127:             }
128:         }
129:         return $v;
130:     }
131: 
132:     /**
133:      * Checks if this object has certain property or not.
134:      * If "setloose" is set as true then it returns true always.
135:      *
136:      * @param string $name
137:      * @return bool
138:      */
139:     public function has($name)
140:     {
141:         return $this->_loose || array_key_exists($name, $this->_vars);
142:     }
143: 
144:     /**
145:      * Returns all property names in this object.
146:      * Elements of returned list are sorted by its name.
147:      *
148:      * @return Pinoco_List
149:      */
150:     public function keys()
151:     {
152:         return Pinoco_List::fromArray(array_keys($this->_vars))->sorted();
153:     }
154: 
155:     /**
156:      * Returns values of all properties in this object.
157:      * Values are sorted by its key name.
158:      *
159:      * @return Pinoco_List
160:      */
161:     public function values()
162:     {
163:         $tmp = $this->_vars;
164:         ksort($tmp);
165:         return Pinoco_List::fromArray(array_values($tmp));
166:     }
167: 
168:     public function __get($name)
169:     {
170:         return $this->get($name);
171:     }
172: 
173:     /**
174:      * Sets a value to this object as given name.
175:      *
176:      * @param string $name
177:      * @param mixed $value
178:      * @return void
179:      */
180:     public function set($name, $value)
181:     {
182:         $this->_vars[$name] = $value;
183:     }
184: 
185:     /**
186:      * Extends existing instance with any callable object.
187:      * The instance would be passed to the 1st argument of callback, then
188:      * trailing arguments are filled as is, just like Python's OOP.
189:      *
190:      * @param string $name
191:      * @param callback $callable
192:      * @return void
193:      */
194:     public function registerAsMethod($name, $callable)
195:     {
196:         $this->_vars[$name] = new Pinoco_MethodProxy($callable, $this);
197:     }
198: 
199:     /**
200:      * Sets a value to this object as given named dynamic value.
201:      * The callback evaluated every time when fetched.
202:      *
203:      * @param string $name
204:      * @param callback $callable
205:      * @param array $context
206:      * @return void
207:      */
208:     public function registerAsDynamic($name, $callable, $context=array())
209:     {
210:         $this->_vars[$name] = new Pinoco_ValueProxy($callable, $this, false, $context);
211:     }
212: 
213:     /**
214:      * Sets a value to this object as given named lazy value.
215:      * The callback evaluated as one-shot.
216:      *
217:      * @param string $name
218:      * @param callback $callable
219:      * @param array $context
220:      * @return void
221:      */
222:     public function registerAsLazy($name, $callable, $context=array())
223:     {
224:         $this->_vars[$name] = new Pinoco_ValueProxy($callable, $this, true, $context);
225:     }
226: 
227:     /**
228:      * Clear lazy property's internal cache.
229:      * It would be regenerated at the next fetching.
230:      *
231:      * @param string $name
232:      * @return void
233:      */
234:     public function markAsDirty($name)
235:     {
236:         if (array_key_exists($name, $this->_vars) &&
237:             $this->_vars[$name] instanceof Pinoco_ValueProxy
238:         ) {
239:             /* @var $proxy Pinoco_ValueProxy */
240:             $proxy = $this->_vars[$name];
241:             $proxy->dirty();
242:         }
243:     }
244: 
245:     /**
246:      * Sets a default value for non existence property access.
247:      *
248:      * @param mixed $value
249:      * @return void
250:      */
251:     public function setDefault($value)
252:     {
253:         $this->_default_val = $value;
254:     }
255: 
256:     /**
257:      * Makes has() result always true.
258:      *
259:      * @param bool $flag
260:      * @return void
261:      */
262:     public function setLoose($flag)
263:     {
264:         $this->_loose = $flag;
265:     }
266: 
267:     /**
268:      * Removes a property by name.
269:      *
270:      * @param string $name
271:      * @return void
272:      */
273:     public function remove($name)
274:     {
275:         unset($this->_vars[$name]);
276:     }
277: 
278:     public function __set($name, $value)
279:     {
280:         $this->set($name, $value);
281:     }
282: 
283:     public function __isset($name)
284:     {
285:         return $this->has($name);
286:     }
287: 
288:     public function __unset($name)
289:     {
290:         $this->remove($name);
291:     }
292: 
293:     public function __call($name, $arguments)
294:     {
295:         if ($this->has($name)) {
296:             $m = $this->get($name);
297:             if ($m instanceof Pinoco_MethodProxy) {
298:                 return $m->call($arguments);
299:             }
300:             elseif (is_callable($m)) {
301:                 return call_user_func_array($m, $arguments);
302:             }
303:         }
304:         throw new BadMethodCallException("The Vars object has no such method: $name.");
305:     }
306: 
307:     /**
308:      * Returns a number of entries in this object.
309:      *
310:      * @return int
311:      */
312:     public function count()
313:     {
314:         return count($this->_vars);
315:     }
316: 
317:     public function getIterator()
318:     {
319:         return new Pinoco_ArrayConvertiblesIterator($this->_vars);
320:     }
321: 
322:     public function offsetSet($offset, $value)
323:     {
324:         $this->set($offset, $value);
325:     }
326: 
327:     public function offsetExists($offset)
328:     {
329:         return $this->has($offset);
330:     }
331: 
332:     public function offsetUnset($offset)
333:     {
334:         $this->remove($offset);
335:     }
336: 
337:     public function offsetGet($offset)
338:     {
339:         return $this->get($offset);
340:     }
341: 
342:     /**
343:      * Exports properties to Array.
344:      *
345:      * @param array $filter
346:      * @param mixed $default
347:      * @param string $modifier
348:      * @return array
349:      */
350:     public function toArray($filter=null, $default=null, $modifier="%s")
351:     {
352:         $arr = array();
353:         $ks = $filter ? $filter : $this->keys();
354:         foreach ($ks as $k) {
355:             $name = (strpos($modifier, "%") !== false) ? sprintf($modifier, $k) : (
356:                 is_callable($modifier) ? call_user_func($modifier, $k) : ($modifier . $k)
357:             );
358:             $arr[$name] = $this->get($k, $default);
359:         }
360:         return $arr;
361:     }
362: 
363:     /**
364:      * Exports properties to Array recursively.
365:      *
366:      * @param int $depth
367:      * @return array
368:      */
369:     public function toArrayRecurse($depth=null)
370:     {
371:         if ($depth !== null && $depth == 0) { return $this; }
372:         $arr = array();
373:         foreach ($this->keys() as $k) {
374:             $v = $this->get($k);
375:             if ($v instanceof Pinoco_ArrayConvertible) {
376:                 $v = $v->toArrayRecurse($depth !== null ? $depth - 1 : null);
377:             }
378:             $arr[$k] = $v;
379:         }
380:         return $arr;
381:     }
382: 
383:     /**
384:      * Imports properties from an array, object or another Vars.
385:      *
386:      * @param mixed $src
387:      * @param array|boolean $filter
388:      * @param mixed $default
389:      * @param string $modifier
390:      * @throws InvalidArgumentException
391:      * @return void
392:      */
393:     public function import($src, $filter=false, $default=null, $modifier="%s")
394:     {
395:         if (is_array($src)) {
396:             $srcarr = $src;
397:         }
398:         elseif ($src instanceof Traversable) {
399:             $srcarr = array();
400:             foreach ($src as $k=>$v) {
401:                 $srcarr[$k] = $v;
402:             }
403:         }
404:         elseif (is_object($src)) {
405:             $srcarr = get_object_vars($src);
406:         }
407:         else {
408:             throw new InvalidArgumentException("Can't import from scalar variable.");
409:         }
410:         $ks = $filter ? $filter : array_keys($srcarr);
411:         foreach ($ks as $k) {
412:             $name = (strpos($modifier, "%") !== false) ? sprintf($modifier, $k) : (
413:                 is_callable($modifier) ? call_user_func($modifier, $k) : ($modifier . $k)
414:             );
415:             $this->set($name, array_key_exists($k, $srcarr) ? $srcarr[$k] : $default);
416:         }
417:     }
418: 
419:     public function __toString() { return __CLASS__; } // TODO: dump vars name/values
420: }
421: 
422: 
Pinoco 0.8.0 Documentation API documentation generated by ApiGen 2.8.0