We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Getter/Setter with MongoDb

Hi,

i'm using getter/setter in my Phalcon\Mvc\Collection and the following example didn't work:

class Foo extends Phalcon\Mvc\Collection {
    protected $bar;
    public getBar() {return $this->bar;}
    public setBar($bar) {$this->bar = $bar;}
}

$foo = new Foo();
$foo->set('hello bar');
$foo->save();

In MongoDb the data looks like:

 { "_id": ObjectId("5314c35c99f22684438b4567")} 

After changing to:

class Foo extends Phalcon\Mvc\Collection {
    public $bar;
}

everything works fine and $bar is stored too.

 {"bar"▼: "hello bar",
   "_id": ObjectId("5314c34399f22683438b4567")} 

It is a bug or a feature? And if i extend Collection, how should the overridden save-method looks like?

Thanks Alex



3.3k
Accepted
answer
edited Mar '14

Here is my workaround:

class Foo extends \Phalcon\Mvc\Collection {

    protected $bar;
    public function getBar() {return $this->bar;}
    public function setBar( $bar ) {$this->bar = $bar;}

    /**
     * (non-PHPdoc)
     * @see \Phalcon\Mvc\Collection::save()
     */
    public function save() {
        $collection = new \Phalcon\Mvc\Collection();
        $collection->setSource($this->getSource());
        $properties = get_object_vars($this);
        if (is_array($properties) && count($properties)) {
            foreach ($properties as $key => $value) {
                $getter = 'get' . ucfirst($key);
                if (method_exists($this, $getter)) {
                    $collection->$key = $this->$getter();
                }
            }
        }       
        if ($collection->save()) {
            $this->_id = $collection->getId();
            return TRUE;
        }
        return FALSE;
    }
}

other solutions are welcome

Hi Freshman, could you explain about your save() method?

edited Apr '14

Hi,

ok lets go:

$collection = new \Phalcon\Mvc\Collection();
$collection->setSource($this->getSource());

create a fresh instance and assign her to the related collection (you can find more infos about getSource here https://docs.phalcon.io/en/latest/reference/models.html#creating-models)

$properties = get_object_vars($this);
if (is_array($properties) && count($properties)) {
  foreach ($properties as $key => $value) {
    ...
  }
}  

get all properties of Foo and loop them through

foreach ($properties as $key => $value) {
  $getter = 'get' . ucfirst($key);
  if (method_exists($this, $getter)) {
    $collection->$key = $this->$getter();
  }
}    

check inside the loop if Foo has a getter-method that matched the getter-name-conventions. if this is true, create a new property in the fresh instance with the same name and value as in Foo.

if ($collection->save()) {
 $this->_id = $collection->getId();
 return TRUE;
}
return FALSE;

save that, assign the new _id to Foo and return TRUE (or FALSE if somewhere an error has occured). That's all.

For the sake of completeness, that's not a good solution if you work with Events (https://docs.phalcon.io/en/latest/reference/models.html#events-and-events-manager) because they will be called on orignal object but you need them on the new instance.



146
edited Sep '14

What's the official response of Phalcon dev team?

To write own 'save' function for this problem is not good way. We don''t have any information in docs about this, why I can't use private fields in collections.