|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676 |
- <?php
-
-
- namespace yii\base;
-
- use Yii;
-
-
- class Component extends Object
- {
-
-
- private $_events = [];
-
-
- private $_behaviors;
-
-
-
-
- public function __get($name)
- {
- $getter = 'get' . $name;
- if (method_exists($this, $getter)) {
-
- return $this->$getter();
- } else {
-
- $this->ensureBehaviors();
- foreach ($this->_behaviors as $behavior) {
- if ($behavior->canGetProperty($name)) {
- return $behavior->$name;
- }
- }
- }
- if (method_exists($this, 'set' . $name)) {
- throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
- } else {
- throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
- }
- }
-
-
-
- public function __set($name, $value)
- {
- $setter = 'set' . $name;
- if (method_exists($this, $setter)) {
-
- $this->$setter($value);
-
- return;
- } elseif (strncmp($name, 'on ', 3) === 0) {
-
- $this->on(trim(substr($name, 3)), $value);
-
- return;
- } elseif (strncmp($name, 'as ', 3) === 0) {
-
- $name = trim(substr($name, 3));
- $this->attachBehavior($name, $value instanceof Behavior ? $value : Yii::createObject($value));
-
- return;
- } else {
-
- $this->ensureBehaviors();
- foreach ($this->_behaviors as $behavior) {
- if ($behavior->canSetProperty($name)) {
- $behavior->$name = $value;
-
- return;
- }
- }
- }
- if (method_exists($this, 'get' . $name)) {
- throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
- } else {
- throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
- }
- }
-
-
-
- public function __isset($name)
- {
- $getter = 'get' . $name;
- if (method_exists($this, $getter)) {
- return $this->$getter() !== null;
- } else {
-
- $this->ensureBehaviors();
- foreach ($this->_behaviors as $behavior) {
- if ($behavior->canGetProperty($name)) {
- return $behavior->$name !== null;
- }
- }
- }
- return false;
- }
-
-
-
- public function __unset($name)
- {
- $setter = 'set' . $name;
- if (method_exists($this, $setter)) {
- $this->$setter(null);
- return;
- } else {
-
- $this->ensureBehaviors();
- foreach ($this->_behaviors as $behavior) {
- if ($behavior->canSetProperty($name)) {
- $behavior->$name = null;
- return;
- }
- }
- }
- throw new InvalidCallException('Unsetting an unknown or read-only property: ' . get_class($this) . '::' . $name);
- }
-
-
-
- public function __call($name, $params)
- {
- $this->ensureBehaviors();
- foreach ($this->_behaviors as $object) {
- if ($object->hasMethod($name)) {
- return call_user_func_array([$object, $name], $params);
- }
- }
- throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
- }
-
-
-
- public function __clone()
- {
- $this->_events = [];
- $this->_behaviors = null;
- }
-
-
-
- public function hasProperty($name, $checkVars = true, $checkBehaviors = true)
- {
- return $this->canGetProperty($name, $checkVars, $checkBehaviors) || $this->canSetProperty($name, false, $checkBehaviors);
- }
-
-
-
- public function canGetProperty($name, $checkVars = true, $checkBehaviors = true)
- {
- if (method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name)) {
- return true;
- } elseif ($checkBehaviors) {
- $this->ensureBehaviors();
- foreach ($this->_behaviors as $behavior) {
- if ($behavior->canGetProperty($name, $checkVars)) {
- return true;
- }
- }
- }
- return false;
- }
-
-
-
- public function canSetProperty($name, $checkVars = true, $checkBehaviors = true)
- {
- if (method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name)) {
- return true;
- } elseif ($checkBehaviors) {
- $this->ensureBehaviors();
- foreach ($this->_behaviors as $behavior) {
- if ($behavior->canSetProperty($name, $checkVars)) {
- return true;
- }
- }
- }
- return false;
- }
-
-
-
- public function hasMethod($name, $checkBehaviors = true)
- {
- if (method_exists($this, $name)) {
- return true;
- } elseif ($checkBehaviors) {
- $this->ensureBehaviors();
- foreach ($this->_behaviors as $behavior) {
- if ($behavior->hasMethod($name)) {
- return true;
- }
- }
- }
- return false;
- }
-
-
-
- public function behaviors()
- {
- return [];
- }
-
-
-
- public function hasEventHandlers($name)
- {
- $this->ensureBehaviors();
- return !empty($this->_events[$name]) || Event::hasHandlers($this, $name);
- }
-
-
-
- public function on($name, $handler, $data = null, $append = true)
- {
- $this->ensureBehaviors();
- if ($append || empty($this->_events[$name])) {
- $this->_events[$name][] = [$handler, $data];
- } else {
- array_unshift($this->_events[$name], [$handler, $data]);
- }
- }
-
-
-
- public function off($name, $handler = null)
- {
- $this->ensureBehaviors();
- if (empty($this->_events[$name])) {
- return false;
- }
- if ($handler === null) {
- unset($this->_events[$name]);
- return true;
- } else {
- $removed = false;
- foreach ($this->_events[$name] as $i => $event) {
- if ($event[0] === $handler) {
- unset($this->_events[$name][$i]);
- $removed = true;
- }
- }
- if ($removed) {
- $this->_events[$name] = array_values($this->_events[$name]);
- }
- return $removed;
- }
- }
-
-
-
- public function trigger($name, Event $event = null)
- {
- $this->ensureBehaviors();
- if (!empty($this->_events[$name])) {
- if ($event === null) {
- $event = new Event;
- }
- if ($event->sender === null) {
- $event->sender = $this;
- }
- $event->handled = false;
- $event->name = $name;
- foreach ($this->_events[$name] as $handler) {
- $event->data = $handler[1];
- call_user_func($handler[0], $event);
-
- if ($event->handled) {
- return;
- }
- }
- }
-
- Event::trigger($this, $name, $event);
- }
-
-
-
- public function getBehavior($name)
- {
- $this->ensureBehaviors();
- return isset($this->_behaviors[$name]) ? $this->_behaviors[$name] : null;
- }
-
-
-
- public function getBehaviors()
- {
- $this->ensureBehaviors();
- return $this->_behaviors;
- }
-
-
-
- public function attachBehavior($name, $behavior)
- {
- $this->ensureBehaviors();
- return $this->attachBehaviorInternal($name, $behavior);
- }
-
-
-
- public function attachBehaviors($behaviors)
- {
- $this->ensureBehaviors();
- foreach ($behaviors as $name => $behavior) {
- $this->attachBehaviorInternal($name, $behavior);
- }
- }
-
-
-
- public function detachBehavior($name)
- {
- $this->ensureBehaviors();
- if (isset($this->_behaviors[$name])) {
- $behavior = $this->_behaviors[$name];
- unset($this->_behaviors[$name]);
- $behavior->detach();
- return $behavior;
- } else {
- return null;
- }
- }
-
-
-
- public function detachBehaviors()
- {
- $this->ensureBehaviors();
- foreach ($this->_behaviors as $name => $behavior) {
- $this->detachBehavior($name);
- }
- }
-
-
-
- public function ensureBehaviors()
- {
- if ($this->_behaviors === null) {
- $this->_behaviors = [];
- foreach ($this->behaviors() as $name => $behavior) {
- $this->attachBehaviorInternal($name, $behavior);
- }
- }
- }
-
-
-
- private function attachBehaviorInternal($name, $behavior)
- {
- if (!($behavior instanceof Behavior)) {
- $behavior = Yii::createObject($behavior);
- }
- if (is_int($name)) {
- $behavior->attach($this);
- $this->_behaviors[] = $behavior;
- } else {
- if (isset($this->_behaviors[$name])) {
- $this->_behaviors[$name]->detach();
- }
- $behavior->attach($this);
- $this->_behaviors[$name] = $behavior;
- }
- return $behavior;
- }
- }
|