public function push($fieldName, $value)
{
$oldValue = $this->get($fieldName);
// check if old value is list or sub document
// on sub document throw exception
if (is_array($oldValue)) {
$isSubDocument = array_keys($oldValue) !== range(0, count($oldValue) - 1);
if ($isSubDocument) {
throw new InvalidOperationException(sprintf('The field "%s" must be an array but is of type Object', $fieldName));
}
}
// prepare new value
$value = Structure::prepareToStore($value);
// field not exists
if (!$oldValue) {
if ($this->getId()) {
$this->operator->push($fieldName, $value);
}
$value = array($value);
} elseif (!is_array($oldValue)) {
$value = array_merge((array) $oldValue, array($value));
if ($this->getId()) {
$this->operator->set($fieldName, $value);
}
} else {
if ($this->getId()) {
// check if array because previous $set operation on single value was executed
$setValue = $this->operator->get('$set', $fieldName);
if ($setValue) {
$setValue[] = $value;
$this->operator->set($fieldName, $setValue);
} else {
$this->operator->push($fieldName, $value);
}
}
$value = array_merge($oldValue, array($value));
}
// update local data
parent::set($fieldName, $value);
return $this;
}