TComponent is the base class for all PRADO components. TComponent implements the protocol of defining, using properties, behaviors, and events. A property is defined by a getter method, and/or a setter method. Properties can be accessed in the way like accessing normal object members. Reading or writing a property will cause the invocation of the corresponding getter or setter method, e.g., $a=$this->Text; // equivalent to $a=$this->getText(); $this->Text='abc'; // equivalent to $this->setText('abc'); The signatures of getter and setter methods are as follows, getter, defines a readable property 'Text' function getText() { ... } setter, defines a writable property 'Text', with $value being the value to be set to the property function setText($value) { ... } Property names are case-insensitive. It is recommended that they are written in the format of concatenated words, with the first letter of each word capitalized (e.g. DisplayMode, ItemStyle). Javascript Get and Set Since Prado 3.2 a new class of javascript-friendly properties have been introduced to better deal with potential security problems like cross-site scripting issues. All the data that gets sent clientside inside a javascript block is now encoded by default. Sometimes there's the need to bypass this encoding and be able to send raw javascript code. This new class of javascript-friendly properties are identified by their name starting with 'js' (case insensitive): getter, defines a readable property 'Text' function getJsText() { ... } setter, defines a writable property 'Text', with $value being the value to be set to the property function setJsText(TJavaScriptLiteral $value) { ... } Js-friendly properties can be accessed using both their Js-less name and their Js-enabled name: set some simple text as property value $component->Text = 'text'; set some javascript code as property value $component->JsText = 'raw javascript'; In the first case, the property value will automatically gets encoded when sent clientside inside a javascript block. In the second case, the property will be 'marked' as being a safe javascript statement and will not be encoded when rendered inside a javascript block. This special handling makes use of the {@link TJavaScriptLiteral} class. Events An event is defined by the presence of a method whose name starts with 'on'. The event name is the method name and is thus case-insensitive. An event can be attached with one or several methods (called event handlers). An event can be raised by calling {@link raiseEvent} method, upon which the attached event handlers will be invoked automatically in the order they are attached to the event. Event handlers must have the following signature, function eventHandlerFuncName($sender,$param) { ... } where $sender refers to the object who is responsible for the raising of the event, and $param refers to a structure that may contain event-specific information. To raise an event (assuming named as 'Click') of a component, use $component->raiseEvent('OnClick'); $component->raiseEvent('OnClick', $this, $param); To attach an event handler to an event, use one of the following ways, $component->OnClick=$callback; // or $component->OnClick->add($callback); $component->attachEventHandler('OnClick',$callback); The first two ways make use of the fact that $component->OnClick refers to the event handler list {@link TPriorityList} for the 'OnClick' event. The variable $callback contains the definition of the event handler that can be either a string referring to a global function name, or an array whose first element refers to an object and second element a method name/path that is reachable by the object, e.g. - 'buttonClicked' : buttonClicked($sender,$param); - array($object,'buttonClicked') : $object->buttonClicked($sender,$param); - array($object,'MainContent.SubmitButton.buttonClicked') : $object->MainContent->SubmitButton->buttonClicked($sender,$param); With the addition of behaviors, a more expansive event model is needed. There are two new event types (global and dynamic events) as well as a more comprehensive behavior model that includes class wide behaviors. A global event is defined by all events whose name starts with 'fx'. The event name is potentially a method name and is thus case-insensitive. All 'fx' events are valid as the whole 'fx' event/method space is global in nature. Any object may patch into any global event by defining that event as a method. Global events have priorities just like 'on' events; so as to be able to order the event execution. Due to the nature of all events which start with 'fx' being valid, in effect, every object has every 'fx' global event. It is simply an issue of tapping into the desired global event. A global event that starts with 'fx' can be called even if the object does not implement the method of the global event. A call to a non-existing 'fx' method will, at minimal, function and return null. If a method argument list has a first parameter, it will be returned instead of null. This allows filtering and chaining. 'fx' methods do not automatically install and uninstall. To install and uninstall an object's global event listeners, call the object's {@link listen} and {@link unlisten} methods, respectively. An object may auto-install its global event during {@link __construct} by overriding {@link getAutoGlobalListen} and returning true. As of PHP version 5.3, nulled objects without code references will still continue to persist in the global event queue because {@link __destruct} is not automatically called. In the common __destruct method, if an object is listening to global events, then {@link unlisten} is called. {@link unlisten} is required to be manually called before an object is left without references if it is currently listening to any global events. This includes class wide behaviors. An object that contains a method that starts with 'fx' will have those functions automatically receive those events of the same name after {@link listen} is called on the object. An object may listen to a global event without defining an 'fx' method of the same name by adding an object method to the global event list. For example $component->fxGlobalCheck=$callback; // or $component->OnClick->add($callback); $component->attachEventHandler('fxGlobalCheck',array($object, 'someMethod')); Events between Objects and their behaviors, Dynamic Events An intra-object/behavior event is defined by methods that start with 'dy'. Just as with 'fx' global events, every object has every dynamic event. Any call to a method that starts with 'dy' will be handled, regardless of whether it is implemented. These events are for communicating with attached behaviors. Dynamic events can be used in a variety of ways. They can be used to tell behaviors when a non-behavior method is called. Dynamic events could be used as data filters. They could also be used to specify when a piece of code is to be run, eg. should the loop process be performed on a particular piece of data. In this way, some control is handed to the behaviors over the process and/or data. If there are no handlers for an 'fx' or 'dy' event, it will return the first parameter of the argument list. If there are no arguments, these events will return null. If there are handlers an 'fx' method will be called directly within the object. Global 'fx' events are triggered by calling {@link raiseEvent}. For dynamic events where there are behaviors that respond to the dynamic events, a {@link TCallChain} is developed. A call chain allows the behavior dynamic event implementations to call further implementing behaviors within a chain. If an object implements {@link IDynamicMethods}, all global and object dynamic events will be sent to {@link __dycall}. In the case of global events, all global events will trigger this method. In the case of behaviors, all undefined dynamic events which are called will be passed through to this method. Behaviors There are two types of behaviors. There are individual object behaviors and there are class wide behaviors. Class behaviors depend upon object behaviors. When a new class implements {@link IBehavior} or {@link IClassBehavior} or extends {@link TBehavior} or {@link TClassBehavior}, it may be added to an object by calling the object's {@link attachBehavior}. The behaviors associated name can then be used to {@link enableBehavior} or {@link disableBehavior} the specific behavior. All behaviors may be turned on and off via {@link enableBehaviors} and {@link disableBehaviors}, respectively. To check if behaviors are on or off a call to {@link getBehaviorsEnabled} will provide the variable. Attaching and detaching whole sets of behaviors is done using {@link attachBehaviors} and {@link detachBehaviors}. {@link clearBehaviors} removes all of an object's behaviors. {@link asa} returns a behavior of a specific name. {@link isa} is the behavior inclusive function that acts as the PHP operator {@link instanceof}. A behavior could provide the functionality of a specific class thus causing the host object to act similarly to a completely different class. A behavior would then implement {@link IInstanceCheck} to provide the identity of the different class. Class behaviors are similar to object behaviors except that the class behavior is the implementation for all instances of the class. A class behavior will have the object upon which is being called be prepended to the parameter list. This way the object is known across the class behavior implementation. Class behaviors are attached using {@link attachClassBehavior} and detached using {@link detachClassBehavior}. Class behaviors are important in that they will be applied to all new instances of a particular class. In this way class behaviors become default behaviors to a new instances of a class in {@link __construct}. Detaching a class behavior will remove the behavior from the default set of behaviors created for an object when the object is instanced. Class behaviors are also added to all existing instances via the global 'fx' event mechanism. When a new class behavior is added, the event {@link fxAttachClassBehavior} is raised and all existing instances that are listening to this global event (primarily after {@link listen} is called) will have this new behavior attached. A similar process is used when detaching class behaviors. Any objects listening to the global 'fx' event {@link fxDetachClassBehavior} will have a class behavior removed. Dynamic Intra-Object Events Dynamic events start with 'dy'. This mechanism is used to allow objects to communicate with their behaviors directly. The entire 'dy' event space is valid. All attached, enabled behaviors that implement a dynamic event are called when the host object calls the dynamic event. If there is no implementation or behaviors, this returns null when no parameters are supplied and will return the first parameter when there is at least one parameter in the dynamic event. null == $this->dyBehaviorEvent(); 5 == $this->dyBehaviorEvent(5); //when no behaviors implement this dynamic event Dynamic events can be chained together within behaviors to allow for data filtering. Dynamic events are implemented within behaviors by defining the event as a method. class TObjectBehavior extends TBehavior { public function dyBehaviorEvent($param1, $callchain) { Do something, eg: $param1 += 13; return $callchain->dyBehaviorEvent($param1); } } This implementation of a behavior and dynamic event will flow through to the next behavior implementing the dynamic event. The first parameter is always return when it is supplied. Otherwise a dynamic event returns null. In the case of a class behavior, the object is also prepended to the dynamic event. class TObjectClassBehavior extends TClassBehavior { public function dyBehaviorEvent($hostobject, $param1, $callchain) { Do something, eg: $param1 += $hostobject->getNumber(); return $callchain->dyBehaviorEvent($param1); } } When calling a dynamic event, only the parameters are passed. The host object and the call chain are built into the framework. Global Event and Dynamic event catching Given that all global 'fx' events and dynamic 'dy' events are valid and operational, there is a mechanism for catching events called that are not implemented (similar to the built-in PHP method {@link __call}). When a dynamic or global event is called but a behavior does not implement it, yet desires to know when an undefined dynamic event is run, the behavior implements the interface {@link IDynamicMethods} and method {@link __dycall}. In the case of dynamic events, {@link __dycall} is supplied with the method name and its parameters. When a global event is raised, via {@link raiseEvent}, the method is the event name and the parameters are supplied. When implemented, this catch-all mechanism is called for event global event event when implemented outside of a behavior. Within a behavior, it will also be called when the object to which the behavior is attached calls any unimplemented dynamic event. This is the fall-back mechanism for informing a class and/or behavior of when an global and/or undefined dynamic event is executed.
Since: 3.0
Author: Qiang Xue (qiang.xue@gmail.com)
Author: Brad Anderson (javalizard@mac.com)
Exemple #1
0
 /**
  * Constructor.
  * @param TStyle style to copy from
  */
 public function __construct($style = null)
 {
     parent::__construct();
     if ($style !== null) {
         $this->copyFrom($style);
     }
 }
Exemple #2
0
 /**
  * Returns an array with the names of all variables of this object that should NOT be serialized
  * because their value is the default one or useless to be cached for the next page loads.
  * Reimplement in derived classes to add new variables, but remember to  also to call the parent
  * implementation first.
  */
 protected function _getZappableSleepProps(&$exprops)
 {
     parent::_getZappableSleepProps($exprops);
     if ($this->_d === array()) {
         $exprops[] = "TMap_d";
     }
     if ($this->_r === false) {
         $exprops[] = "TMap_r";
     }
 }
 public function __sleep()
 {
     $exprops = array();
     $cn = __CLASS__;
     if (!$this->_parameterNames or !$this->_parameterNames->getCount()) {
         $exprops[] = "{$cn}_parameterNames";
     }
     if (!$this->_parameterValues or !$this->_parameterValues->getCount()) {
         $exprops[] = "{$cn}_parameterValues";
     }
     return array_diff(parent::__sleep(), $exprops);
 }
Exemple #4
0
 /**
  * Returns an array with the names of all variables of this object that should NOT be serialized
  * because their value is the default one or useless to be cached for the next page loads.
  * Reimplement in derived classes to add new variables, but remember to  also to call the parent
  * implementation first.
  */
 protected function _getZappableSleepProps(&$exprops)
 {
     parent::_getZappableSleepProps($exprops);
     if ($this->_flags === 0) {
         $exprops[] = "TFont_flags";
     }
     if ($this->_name === '') {
         $exprops[] = "TFont_name";
     }
     if ($this->_size === '') {
         $exprops[] = "TFont_size";
     }
 }
Exemple #5
0
 /**
  * Returns an array with the names of all variables of this object that should NOT be serialized
  * because their value is the default one or useless to be cached for the next page loads.
  * Reimplement in derived classes to add new variables, but remember to  also to call the parent
  * implementation first.
  */
 protected function _getZappableSleepProps(&$exprops)
 {
     parent::_getZappableSleepProps($exprops);
     if ($this->_attributes === null) {
         $exprops[] = "TListItem_attributes";
     }
     if ($this->_text === '') {
         $exprops[] = "TListItem_text";
     }
     if ($this->_value === '') {
         $exprops[] = "TListItem_value";
     }
     if ($this->_enabled === true) {
         $exprops[] = "TListItem_enabled";
     }
     if ($this->_selected === false) {
         $exprops[] = "TListItem_selected";
     }
 }
Exemple #6
0
 /**
  * Close the connection when serializing.
  */
 public function __sleep()
 {
     //		$this->close(); - DO NOT CLOSE the current connection as serializing doesn't neccessarily mean we don't this connection anymore in the current session
     return array_diff(parent::__sleep(), array("TDbConnection_pdo", "TDbConnection_active"));
 }
 public function __sleep()
 {
     $exprops = array();
     $cn = 'TParameterProperty';
     if ($this->_typeHandler === null) {
         $exprops[] = "{$cn}_typeHandler";
     }
     if ($this->_type === null) {
         $exprops[] = "{$cn}_type";
     }
     if ($this->_column === null) {
         $exprops[] = "{$cn}_column";
     }
     if ($this->_dbType === null) {
         $exprops[] = "{$cn}_dbType";
     }
     if ($this->_property === null) {
         $exprops[] = "{$cn}_property";
     }
     if ($this->_nullValue === null) {
         $exprops[] = "{$cn}_nullValue";
     }
     return array_diff(parent::__sleep(), $exprops);
 }
Exemple #8
0
 public function __sleep()
 {
     $exprops = array();
     $cn = __CLASS__;
     if (!count($this->_selectQueue)) {
         $exprops[] = "{$cn}_selectQueue";
     }
     if (is_null($this->_groupBy)) {
         $exprops[] = "{$cn}_groupBy";
     }
     if (!$this->_IsRowDataFound) {
         $exprops[] = "{$cn}_IsRowDataFound";
     }
     return array_diff(parent::__sleep(), $exprops);
 }
Exemple #9
0
 /**
  * Set the statement to null when serializing.
  */
 public function __sleep()
 {
     return array_diff(parent::__sleep(), array("TDbCommand_statement"));
 }
Exemple #10
0
 public function __sleep()
 {
     $exprops = array();
     $cn = 'TResultProperty';
     if ($this->_nullValue === null) {
         $exprops[] = "{$cn}_nullValue";
     }
     if ($this->_propertyName === null) {
         $exprops[] = "{$cn}_propertyNama";
     }
     if ($this->_columnName === null) {
         $exprops[] = "{$cn}_columnName";
     }
     if ($this->_columnIndex == -1) {
         $exprops[] = "{$cn}_columnIndex";
     }
     if ($this->_nestedResultMapName === null) {
         $exprops[] = "{$cn}_nestedResultMapName";
     }
     if ($this->_nestedResultMap === null) {
         $exprops[] = "{$cn}_nestedResultMap";
     }
     if ($this->_valueType === null) {
         $exprops[] = "{$cn}_valueType";
     }
     if ($this->_typeHandler === null) {
         $exprops[] = "{$cn}_typeHandler";
     }
     if ($this->_isLazyLoad === false) {
         $exprops[] = "{$cn}_isLazyLoad";
     }
     if ($this->_select === null) {
         $exprops[] = "{$cn}_select";
     }
     return array_diff(parent::__sleep(), $exprops);
 }
 public function __sleep()
 {
     $exprops = array();
     $cn = __CLASS__;
     if (!count($this->_tree)) {
         $exprops[] = "{$cn}_tree";
     }
     if (!count($this->_entries)) {
         $exprops[] = "{$cn}_entries";
     }
     if (!count($this->_list)) {
         $exprops[] = "{$cn}_list";
     }
     return array_diff(parent::__sleep(), $exprops);
 }
Exemple #12
0
 /**
  * Magic method for writing properties.
  * This method is overriden to provide write access to the foreign objects via
  * the key names declared in the RELATIONS array.
  * @param string property name
  * @param mixed property value.
  * @since 3.1.2
  */
 public function __set($name, $value)
 {
     if ($this->hasRecordRelation($name) && !$this->canSetProperty($name)) {
         $this->{$name} = $value;
     } else {
         parent::__set($name, $value);
     }
 }
Exemple #13
0
 public function __sleep()
 {
     $cn = __CLASS__;
     $exprops = array("{$cn}_resultMap");
     if (!$this->_parameterMapName) {
         $exprops[] = "{$cn}_parameterMapName";
     }
     if (!$this->_parameterMap) {
         $exprops[] = "{$cn}_parameterMap";
     }
     if (!$this->_parameterClassName) {
         $exprops[] = "{$cn}_parameterClassName";
     }
     if (!$this->_resultMapName) {
         $exprops[] = "{$cn}_resultMapName";
     }
     if (!$this->_resultMap) {
         $exprops[] = "{$cn}_resultMap";
     }
     if (!$this->_resultClassName) {
         $exprops[] = "{$cn}_resultClassName";
     }
     if (!$this->_cacheModelName) {
         $exprops[] = "{$cn}_cacheModelName";
     }
     if (!$this->_SQL) {
         $exprops[] = "{$cn}_SQL";
     }
     if (!$this->_listClass) {
         $exprops[] = "{$cn}_listClass";
     }
     if (!$this->_typeHandler) {
         $exprops[] = "{$cn}_typeHandler";
     }
     if (!$this->_extendStatement) {
         $exprops[] = "{$cn}_extendStatement";
     }
     if (!$this->_cache) {
         $exprops[] = "{$cn}_cache";
     }
     return array_diff(parent::__sleep(), $exprops);
 }