Esempio n. 1
0
 /**
  * @param $name
  * @param $value
  */
 public function __set($name, $value)
 {
     if (in_array($name, ['prototype', 'properties'])) {
         return;
     }
     if (!isset($this->_ownProperties[$name]) && !\arc\prototype::isExtensible($this)) {
         return;
     }
     $valueIsSetterOrGetter = $this->_isGetterOrSetter($value);
     $propertyIsSetterOrGetter = isset($this->_ownProperties[$name]) ? $this->_isGetterOrSetter($this->_ownProperties[$name]) : false;
     if (\arc\prototype::isSealed($this) && $valueIsSetterOrGetter != $propertyIsSetterOrGetter) {
         return;
     }
     $changes = [];
     $changes['name'] = $name;
     $changes['object'] = $this;
     if (array_key_exists($name, $this->_ownProperties)) {
         $changes['type'] = 'update';
         $changes['oldValue'] = $this->_ownProperties[$name];
     } else {
         $changes['type'] = 'add';
     }
     $clearcache = false;
     // get current value for $name, to check if it has a getter and/or a setter
     if (array_key_exists($name, $this->_ownProperties)) {
         $current = $this->_ownProperties[$name];
     } else {
         $current = $this->_getPrototypeProperty($name);
     }
     if ($valueIsSetterOrGetter) {
         // reconfigure current property
         $clearcache = true;
         $this->_ownProperties[$name] = $value;
         unset($this->_staticMethods[$name]);
     } else {
         if (isset($current) && isset($current['set']) && is_callable($current['set'])) {
             // bindable setter found, use it, no need to set anything in _ownProperties
             $setter = \Closure::bind($current['set'], $this, $this);
             $setter($value);
         } else {
             if (isset($current) && isset($current[':set']) && is_callable($current[':set'])) {
                 // nonbindable setter found
                 $current[':set']($this, $value);
             } else {
                 if (isset($current) && (isset($current['get']) && is_callable($current['get']) || isset($current[':get']) && is_callable($current[':get']))) {
                     // there is only a getter, no setter, so ignore setting this property, its readonly.
                     return null;
                 } else {
                     if (!array_key_exists($name, $this->_staticMethods)) {
                         // bindable value, update _ownProperties, so clearcache as well
                         $clearcache = true;
                         $this->_ownProperties[$name] = $this->_bind($value);
                     } else {
                         // non bindable value, update _ownProperties, so clearcache as well
                         $clearcache = true;
                         $this->_ownProperties[$name] = $value;
                     }
                 }
             }
         }
     }
     if ($clearcache) {
         // purge prototype cache for this property - this will clear too much but cache will be filled again
         // clearing exactly the right entries from the cache will generally cost more performance than this
         unset(self::$properties[$name]);
         $observers = \arc\prototype::getObservers($this);
         if (isset($observers[$changes['type']])) {
             foreach ($observers[$changes['type']] as $observer) {
                 $observer($changes);
             }
         }
     }
 }