Completed
Pull Request — master (#83)
by Evstati
11:52 queued 10:03
created

Kohana_Jam_Validated::validate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 1
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 2
1
<?php defined('SYSPATH') OR die('No direct script access.');
2
/**
3
 * Jam Model
4
 *
5
 * Jam_Model is the class all models must extend. It handles
6
 * various CRUD operations and relationships to other models.
7
 *
8
 * @package    Jam
9
 * @category   Models
10
 * @author     Ivan Kerin
11
 * @copyright  (c) 2011-2012 Despark Ltd.
12
 * @license    http://www.opensource.org/licenses/isc-license.txt
13
 */
14
abstract class Kohana_Jam_Validated extends Model implements Serializable {
15
16
	/**
17
	 * @var  array  The original data set on the object
18
	 */
19
	protected $_original = array();
20
21
	/**
22
	 * @var  array  Data that's changed since the object was loaded
23
	 */
24
	protected $_changed = array();
25
26
	/**
27
	 * @var  array  Data that's already been retrieved is cached
28
	 */
29
	protected $_retrieved = array();
30
31
	/**
32
	 * @var  array  Unmapped data that is still accessible
33
	 */
34
	protected $_unmapped = array();
35
36
	/**
37
	 * @var  boolean  Whether or not the model is validating
38
	 */
39
	protected $_is_validating = FALSE;
40
41
	/**
42
	 * @var  Jam_Meta  A copy of this object's meta object
43
	 */
44
	protected $_meta = NULL;
45
46
	/**
47
	 * @var  Boolean  A flag that keeps track of whether or not the model is valid
48
	 */
49
	 protected $_errors = NULL;
50
51
	/**
52
	 * Constructor.
53
	 *
54
	 * A key can be passed to automatically load a model by its
55
	 * unique key.
56
	 *
57
	 * @param  mixed|null  $key
0 ignored issues
show
Bug introduced by
There is no parameter named $key. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
58
	 */
59 384
	public function __construct($meta_name = NULL)
60
	{
61 384
		if ($meta_name === NULL)
62
		{
63 382
			$meta_name = $this;
64
		}
65
66
		// Load the object's meta data for quick access
67 384
		$this->_meta = Jam::meta($meta_name);
68
69 384
		$this->_original = $this->meta()->defaults();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->meta()->defaults() of type * is incompatible with the declared type array of property $_original.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
70 384
	}
71
72
	/**
73
	 * Gets the value of a field.
74
	 *
75
	 * Unlike Jam_Model::get(), values that are returned are cached
76
	 * until they are changed and relationships are automatically select()ed.
77
	 *
78
	 * @see     get()
79
	 * @param   string  $name The name or alias of the field you're retrieving
80
	 * @return  mixed
81
	 */
82 107
	public function &__get($name)
83
	{
84 107
		if ( ! array_key_exists($name, $this->_retrieved))
85
		{
86 105
			$this->_retrieved[$name] = $this->get($name);
87
		}
88
89 107
		return $this->_retrieved[$name];
90
	}
91
92
	/**
93
	 * Sets the value of a field.
94
	 *
95
	 * @see     set()
96
	 * @param   string  $name  The name of the field you're setting
97
	 * @param   mixed   $value The value you're setting
98
	 * @return  void
99
	 */
100 50
	public function __set($name, $value)
101
	{
102
		// Being set by mysql_fetch_object, store the values for the constructor
103 50
		if (empty($this->_original))
104
		{
105
			$this->_preload_data[$name] = $value;
0 ignored issues
show
Documentation introduced by
The property _preload_data does not exist on object<Kohana_Jam_Validated>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
106
			return;
107
		}
108
109 50
		$this->set($name, $value);
110 50
	}
111
112
	/**
113
	 * Passes unknown methods along to the behaviors.
114
	 *
115
	 * @param   string  $method
116
	 * @param   array   $args
117
	 * @return  mixed
118
	 **/
119 7
	public function __call($method, $args)
120
	{
121 7
		return $this->meta()->events()->trigger_callback('model', $this, $method, $args);
122
	}
123
124
	/**
125
	 * Returns true if $name is a field of the model or an unmapped column.
126
	 *
127
	 * This does not conform to the standard of returning FALSE if the
128
	 * property is set but the value is NULL. Rather this acts more like
129
	 * property_exists.
130
	 *
131
	 * @param  string    $name
132
	 * @return  boolean
133
	 */
134
	public function __isset($name)
135
	{
136
		return (bool) ($this->meta()->field($name) OR array_key_exists($name, $this->_unmapped));
137
	}
138
139
	/**
140
	 * This doesn't unset fields. Rather, it sets them to their original
141
	 * value. Unmapped, changed, and retrieved values are unset.
142
	 *
143
	 * In essence, unsetting a field sets it as if you never made any changes
144
	 * to it, and clears the cache if the value has been retrieved with those changes.
145
	 *
146
	 * @param   string  $name
147
	 * @return  void
148
	 */
149
	public function __unset($name)
150
	{
151
		unset($this->_changed[$name]);
152
		unset($this->_retrieved[$name]);
153
154
		// We can safely delete this no matter what
155
		unset($this->_unmapped[$name]);
156
	}
157
158
	/**
159
	 * Returns a string representation of the model in the
160
	 * form of `Model_Name (id)` or `Model_Name (NULL)` if
161
	 * the model is not loaded.
162
	 *
163
	 * This is designed to be useful for debugging.
164
	 *
165
	 * @return  string
166
	 */
167
	public function __toString()
168
	{
169
		return (string) get_class($this).'('.($this->is_valid() ? 'Valid' : 'Not Valid').')';
170
	}
171
172
	/**
173
	 * Gets the value for a field.
174
	 *
175
	 * @param   string       $name The field's name
176
	 * @return  array|mixed
177
	 */
178 169
	public function get($name)
179
	{
180 169
		if ($field = $this->_meta->field($name))
181
		{
182
			// Alias the name to its actual name
183 166
			$name = $field->name;
184
185 166
			if (array_key_exists($name, $this->_changed))
186
			{
187 28
				return $field->get($this, $this->_changed[$name], TRUE);
0 ignored issues
show
Compatibility introduced by
$this of type object<Kohana_Jam_Validated> is not a sub-type of object<Jam_Validated>. It seems like you assume a child class of the class Kohana_Jam_Validated to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
Bug introduced by
The method get does only exist in Jam_Field, but not in Kohana_Jam_Meta.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
188
			}
189
			else
190
			{
191 166
				return $this->original($name);
192
			}
193
		}
194
		// Return unmapped data from custom queries
195 17
		elseif ($this->unmapped($name))
196
		{
197 17
			return $this->_unmapped[$name];
198
		}
199 8
	}
200
201
	/**
202
	 * Returns the original value of a field, before it was changed.
203
	 *
204
	 * This method—combined with get(), which first searches for changed
205
	 * values—is useful for comparing changes that occurred on a model.
206
	 *
207
	 * @param   string  $field The field's or alias name
0 ignored issues
show
Bug introduced by
There is no parameter named $field. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
208
	 * @return  mixed
209
	 */
210 169
	public function original($field_name = NULL)
211
	{
212 169
		if ($field_name === NULL)
213
			return $this->_original;
214
215 169
		if ($field = $this->_meta->field($field_name))
216
		{
217 169
			return $field->get($this, $this->_original[$field_name], FALSE);
0 ignored issues
show
Compatibility introduced by
$this of type object<Kohana_Jam_Validated> is not a sub-type of object<Jam_Validated>. It seems like you assume a child class of the class Kohana_Jam_Validated to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
Bug introduced by
The method get does only exist in Jam_Field, but not in Kohana_Jam_Meta.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
218
		}
219
	}
220
221
	/**
222
	 * Returns an array of values in the fields.
223
	 *
224
	 * You can pass an array of field names to retrieve
225
	 * only the values for those fields:
226
	 *
227
	 *     $model->as_array(array('id', 'name', 'status'));
228
	 *
229
	 * @param   array  $fields
230
	 * @return  array
231
	 */
232 8
	public function as_array(array $fields = NULL)
233
	{
234 8
		$fields = $fields ? $fields : array_keys($this->_meta->fields());
235 8
		$result = array();
236
237 8
		foreach ($fields as $field)
238
		{
239 8
			$result[$field] = $this->__get($field);
240
		}
241
242 8
		return $result;
243
	}
244
245
	/**
246
	 * Set preloaded values, without changing the save, loaded and changed flags
247
	 * @param  array|string $values
248
	 * @param  mixed $value
249
	 * @return $this
250
	 */
251 13
	public function retrieved($values, $value = NULL)
252
	{
253
		// Accept retrieved('name', 'value');
254 13
		if ( ! is_array($values))
255
		{
256 13
			$values = array($values => $value);
257
		}
258
259 13
		$this->_retrieved = Arr::merge($this->_retrieved, $values);
260
261 13
		return $this;
262
	}
263
	/**
264
	 * Sets the value of a field.
265
	 *
266
	 * You can pass an array of key => value pairs
267
	 * to set multiple fields at the same time:
268
	 *
269
	 *    $model->set(array(
270
	 *        'field1' => 'value',
271
	 *        'field2' => 'value',
272
	 *         ....
273
	 *    ));
274
	 *
275
	 * @param   array|string  $values
276
	 * @param   mixed|null    $value
277
	 * @return  $this
278
	 */
279 63
	public function set($values, $value = NULL)
280
	{
281
		// Accept set('name', 'value');
282 63
		if ( ! is_array($values))
283
		{
284
			$values = array($values => $value);
285
		}
286
287 63
		foreach ($values as $key => & $value)
288
		{
289 61
			if ($field = $this->meta()->field($key))
290
			{
291 54
				if ($value !== $this->{$field->name})
292
				{
293 37
					$this->_changed[$field->name] = $field->set($this, $value, TRUE);
0 ignored issues
show
Compatibility introduced by
$this of type object<Kohana_Jam_Validated> is not a sub-type of object<Jam_Validated>. It seems like you assume a child class of the class Kohana_Jam_Validated to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
Unused Code introduced by
The call to Kohana_Jam_Meta::set() has too many arguments starting with TRUE.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
294
295 37
					if (array_key_exists($field->name, $this->_retrieved))
296
					{
297 54
						unset($this->_retrieved[$field->name]);
298
					}
299
				}
300
			}
301 27
			elseif (property_exists($this, $key))
302
			{
303 1
				$this->$key = $value;
304
			}
305
			else
306
			{
307 27
				unset($this->_retrieved[$key]);
308 61
				$this->_unmapped[$key] = $value;
309
			}
310
		}
311
312 63
		return $this;
313
	}
314
315 11
	public function is_valid()
316
	{
317 11
		return count($this->errors()) == 0;
318
	}
319
320
	/**
321
	 * Validates the current model's data
322
	 *
323
	 * @throws  Jam_Exception_Validation
324
	 * @param   Validation|null   $extra_validation
0 ignored issues
show
Bug introduced by
There is no parameter named $extra_validation. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
325
	 * @return  bool
326
	 */
327 11
	public function check($force = FALSE)
328
	{
329 11
		$this->_is_validating = TRUE;
330
		// Run validation only when new or changed
331 11
		if ($this->changed() OR $force)
332
		{
333
			// Reset the errors before checking
334 11
			$this->_errors = FALSE;
335
336 11
			$this->meta()->events()->trigger('model.before_check', $this, array($this->_changed));
337
338 11
			$this->meta()->execute_validators($this, $force);
0 ignored issues
show
Compatibility introduced by
$this of type object<Kohana_Jam_Validated> is not a sub-type of object<Jam_Validated>. It seems like you assume a child class of the class Kohana_Jam_Validated to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
339
340 11
			$this->meta()->events()->trigger('model.after_check', $this, array($this->_changed));
341
		}
342
343 11
		$this->_is_validating = FALSE;
344
345 11
		return $this->is_valid();
346
	}
347
348 11
	public function check_insist()
349
	{
350 11
		if ( ! $this->check())
351 1
			throw new Jam_Exception_Validation('There was an error validating the :model: :errors', $this);
352
353 10
		return $this;
354
	}
355
356
	/**
357
	 * Override this function to add custom validation after the validators.
358
	 * Having an empty validate function allow safely calling parent::validate()
359
	 * when extending models.
360
	 *
361
	 * You need to set errors with:
362
	 *     $this->errors()->add('field', 'error_name');
363
	 *
364
	 * @link http://git.io/5I47Tw docs
365
	 */
366
	public function validate() {}
367
368
	/**
369
	 * Get the errors from the previous check, if you provide a name, will return the errors only for that name
370
	 * Automatically loads the error messages file from messages/jam-validation/<model_name>
371
	 * If there are no errors yet - return NULL
372
	 *
373
	 * @param  string $name the name of the field to get errors of
374
	 * @return Jam_Errors|string[]|NULL
375
	 */
376 194
	public function errors($name = NULL)
377
	{
378 194
		if ( ! $this->_errors)
379
		{
380 194
			$this->_errors = new Jam_Errors($this, $this->meta()->errors_filename());
0 ignored issues
show
Compatibility introduced by
$this of type object<Kohana_Jam_Validated> is not a sub-type of object<Jam_Validated>. It seems like you assume a child class of the class Kohana_Jam_Validated to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
Documentation Bug introduced by
It seems like new \Jam_Errors($this, $...a()->errors_filename()) of type object<Jam_Errors> is incompatible with the declared type boolean of property $_errors.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
381
		}
382
383 194
		if ($name !== NULL)
384 3
			return $this->_errors->messages($name);
385
386 193
		return $this->_errors;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->_errors; of type Jam_Errors|boolean adds the type boolean to the return on line 386 which is incompatible with the return type documented by Kohana_Jam_Validated::errors of type Jam_Errors|string[]|null.
Loading history...
387
	}
388
389
	/**
390
	 * Removes any changes made to a model.
391
	 *
392
	 * This method only works on loaded models.
393
	 *
394
	 * @return  $this
395
	 */
396
	public function revert()
397
	{
398
		$this->_errors = NULL;
399
400
		$this->_changed   =
401
		$this->_retrieved = array();
402
403
		return $this;
404
	}
405
406
	/**
407
	 * Sets a model to its original state, as if freshly instantiated
408
	 *
409
	 * @return  $this
410
	 */
411 157
	public function clear()
412
	{
413 157
		$this->_errors = NULL;
414
415 157
		$this->_changed   =
416 157
		$this->_retrieved =
417 157
		$this->_unmapped  = array();
418
419 157
		$this->_original = $this->_meta->defaults();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->_meta->defaults() of type * is incompatible with the declared type array of property $_original.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
420
421 157
		return $this;
422
	}
423
424
	/**
425
	 * Whether or not the model is in the process of being validated
426
	 *
427
	 * @return  boolean
428
	 */
429 8
	public function is_validating()
430
	{
431 8
		return ($this->_is_validating OR $this->_is_saving);
0 ignored issues
show
Documentation introduced by
The property _is_saving does not exist on object<Kohana_Jam_Validated>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
432
	}
433
434
	/**
435
	 * Returns whether or not the particular $field has changed.
436
	 *
437
	 * If $field is NULL, the method returns whether or not any
438
	 * data whatsoever was changed on the model.
439
	 *
440
	 * @param   string   $field
0 ignored issues
show
Bug introduced by
There is no parameter named $field. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
441
	 * @return  boolean
442
	 */
443 49
	public function changed($name = NULL)
444
	{
445 49
		if ($name)
446
		{
447 30
			return array_key_exists($name, $this->_changed);
448
		}
449
		else
450
		{
451 37
			return (bool) $this->_changed;
452
		}
453
	}
454
455
	/**
456
	 * Returns the value of the model's primary key
457
	 *
458
	 * @return  mixed
459
	 */
460 127
	public function id()
461
	{
462 127
		return $this->get($this->meta()->primary_key());
0 ignored issues
show
Bug introduced by
It seems like $this->meta()->primary_key() targeting Kohana_Jam_Meta::primary_key() can also be of type object<Jam_Meta>; however, Kohana_Jam_Validated::get() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
463
	}
464
465
	/**
466
	 * Returns the value of the model's name key
467
	 *
468
	 * @return  mixed
469
	 */
470 10
	public function name()
471
	{
472 10
		return $this->get($this->meta()->name_key());
0 ignored issues
show
Bug introduced by
It seems like $this->meta()->name_key() targeting Kohana_Jam_Meta::name_key() can also be of type object<Jam_Meta>; however, Kohana_Jam_Validated::get() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
473
	}
474
475
	/**
476
	 * Returns the model's meta object
477
	 *
478
	 * @return  Jam_Meta
479
	 */
480 644
	public function meta()
481
	{
482 644
		if ( ! $this->_meta)
483
			throw new Kohana_Exception('Model for class :class does not have a meta', array(':class' => get_class($this)));
484
485 644
		return $this->_meta;
486
	}
487
488 18
	public function unmapped($name)
489
	{
490 18
		return array_key_exists($name, $this->_unmapped);
491
	}
492
493
494
	public function serialize()
495
	{
496
		return serialize(array(
497
			'original' => $this->_original,
498
			'changed' => $this->_changed,
499
			'unmapped' => $this->_unmapped,
500
		));
501
	}
502
503
	public function unserialize($data)
504
	{
505
		$data = unserialize($data);
506
		$this->_meta = Jam::meta($this);
507
		$this->_original = $data['original'];
508
		$this->_changed = $data['changed'];
509
		$this->_unmapped = $data['unmapped'];
510
	}
511
}
512