source: trunk/zpush/lib/core/stateobject.php @ 7589

Revision 7589, 7.9 KB checked in by douglas, 11 years ago (diff)

Ticket #3209 - Integrar módulo de sincronização Z-push ao Expresso

Line 
1<?php
2/***********************************************
3* File      :   stateobject.php
4* Project   :   Z-Push
5* Descr     :   simple data object with some php magic
6*
7* Created   :   02.01.2012
8*
9* Copyright 2007 - 2012 Zarafa Deutschland GmbH
10*
11* This program is free software: you can redistribute it and/or modify
12* it under the terms of the GNU Affero General Public License, version 3,
13* as published by the Free Software Foundation with the following additional
14* term according to sec. 7:
15*
16* According to sec. 7 of the GNU Affero General Public License, version 3,
17* the terms of the AGPL are supplemented with the following terms:
18*
19* "Zarafa" is a registered trademark of Zarafa B.V.
20* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
21* The licensing of the Program under the AGPL does not imply a trademark license.
22* Therefore any rights, title and interest in our trademarks remain entirely with us.
23*
24* However, if you propagate an unmodified version of the Program you are
25* allowed to use the term "Z-Push" to indicate that you distribute the Program.
26* Furthermore you may use our trademarks where it is necessary to indicate
27* the intended purpose of a product or service provided you use it in accordance
28* with honest practices in industrial or commercial matters.
29* If you want to propagate modified versions of the Program under the name "Z-Push",
30* you may only do so if you have a written permission by Zarafa Deutschland GmbH
31* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
32*
33* This program is distributed in the hope that it will be useful,
34* but WITHOUT ANY WARRANTY; without even the implied warranty of
35* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36* GNU Affero General Public License for more details.
37*
38* You should have received a copy of the GNU Affero General Public License
39* along with this program.  If not, see <http://www.gnu.org/licenses/>.
40*
41* Consult LICENSE file for details
42************************************************/
43
44class StateObject implements Serializable {
45    private $SO_internalid;
46    protected $data = array();
47    protected $unsetdata = array();
48    protected $changed = false;
49
50    /**
51     * Returns the unique id of that data object
52     *
53     * @access public
54     * @return array
55     */
56    public function GetID() {
57        if (!isset($this->SO_internalid))
58            $this->SO_internalid = sprintf('%04x%04x%04x', mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff));
59
60        return $this->SO_internalid;
61    }
62
63    /**
64     * Returns the internal array which contains all data of this object
65     *
66     * @access public
67     * @return array
68     */
69    public function GetDataArray() {
70        return $this->data;
71    }
72
73    /**
74     * Sets the internal array which contains all data of this object
75     *
76     * @param array     $data           the data to be written
77     * @param boolean   $markAsChanged  (opt) indicates if the object should be marked as "changed", default false
78     *
79     * @access public
80     * @return array
81     */
82    public function SetDataArray($data, $markAsChanged = false) {
83        $this->data = $data;
84        $this->changed = $markAsChanged;
85    }
86
87    /**
88     * Indicates if the data contained in this object was modified
89     *
90     * @access public
91     * @return array
92     */
93    public function IsDataChanged() {
94        return $this->changed;
95    }
96
97    /**
98     * PHP magic to set an instance variable
99     *
100     * @access public
101     * @return
102     */
103    public function __set($name, $value) {
104        $lname = strtolower($name);
105        if (isset($this->data[$lname]) && is_scalar($value) && !is_array($value) && $this->data[$lname] === $value)
106            return false;
107
108        $this->data[$lname] = $value;
109        $this->changed = true;
110    }
111
112    /**
113     * PHP magic to get an instance variable
114     * if the variable was not set previousely, the value of the
115     * Unsetdata array is returned
116     *
117     * @access public
118     * @return
119     */
120    public function __get($name) {
121        $lname = strtolower($name);
122
123        if (array_key_exists($lname, $this->data))
124            return $this->data[$lname];
125
126        if (isset($this->unsetdata) && is_array($this->unsetdata) && array_key_exists($lname, $this->unsetdata))
127            return $this->unsetdata[$lname];
128
129        return null;
130    }
131
132    /**
133     * PHP magic to check if an instance variable is set
134     *
135     * @access public
136     * @return
137     */
138    public function __isset($name) {
139        return isset($this->data[strtolower($name)]);
140    }
141
142    /**
143     * PHP magic to remove an instance variable
144     *
145     * @access public
146     * @return
147     */
148    public function __unset($name) {
149        if (isset($this->$name)) {
150            unset($this->data[strtolower($name)]);
151            $this->changed = true;
152        }
153    }
154
155    /**
156     * PHP magic to implement any getter, setter, has and delete operations
157     * on an instance variable.
158     * Methods like e.g. "SetVariableName($x)" and "GetVariableName()" are supported
159     *
160     * @access public
161     * @return mixed
162     */
163    public function __call($name, $arguments) {
164        $name = strtolower($name);
165        $operator = substr($name, 0,3);
166        $var = substr($name,3);
167
168        if ($operator == "set" && count($arguments) == 1){
169            $this->$var = $arguments[0];
170            return true;
171        }
172
173        if ($operator == "set" && count($arguments) == 2 && $arguments[1] === false){
174            $this->data[$var] = $arguments[0];
175            return true;
176        }
177
178        // getter without argument = return variable, null if not set
179        if ($operator == "get" && count($arguments) == 0) {
180            return $this->$var;
181        }
182
183        // getter with one argument = return variable if set, else the argument
184        else if ($operator == "get" && count($arguments) == 1) {
185            if (isset($this->$var)) {
186                return $this->$var;
187            }
188            else
189                return $arguments[0];
190        }
191
192        if ($operator == "has" && count($arguments) == 0)
193            return isset($this->$var);
194
195        if ($operator == "del" && count($arguments) == 0) {
196            unset($this->$var);
197            return true;
198        }
199
200        throw new FatalNotImplementedException(sprintf("StateObject->__call('%s'): not implemented. op: {$operator} args:". count($arguments), $name));
201    }
202
203    /**
204     * Method to serialize a StateObject
205     *
206     * @access public
207     * @return array
208     */
209    public function serialize() {
210        // perform tasks just before serialization
211        $this->preSerialize();
212
213        return serialize(array($this->SO_internalid,$this->data));
214    }
215
216    /**
217     * Method to unserialize a StateObject
218     *
219     * @access public
220     * @return array
221     * @throws StateInvalidException
222     */
223    public function unserialize($data) {
224        // throw a StateInvalidException if unserialize fails
225        ini_set('unserialize_callback_func', 'StateObject::ThrowStateInvalidException');
226
227        list($this->SO_internalid, $this->data) = unserialize($data);
228
229        // perform tasks just after unserialization
230        $this->postUnserialize();
231        return true;
232    }
233
234    /**
235     * Called before the StateObject is serialized
236     *
237     * @access protected
238     * @return boolean
239     */
240    protected function preSerialize() {
241        // make sure the object has an id before serialization
242        $this->GetID();
243
244        return true;
245    }
246
247    /**
248     * Called after the StateObject was unserialized
249     *
250     * @access protected
251     * @return boolean
252     */
253    protected function postUnserialize() {
254        return true;
255    }
256
257    /**
258     * Callback function for failed unserialize
259     *
260     * @access public
261     * @throws StateInvalidException
262     */
263    public static function ThrowStateInvalidException() {
264        throw new StateInvalidException("Unserialization failed as class was not found or not compatible");
265    }
266}
267
268?>
Note: See TracBrowser for help on using the repository browser.