Вопрос

I have a few tables configured in Propel, with generated Peer static classes.

My problem is that I need to perform the same search operation on different but similar tables. Those tables have different Peer classes as it is how Propel works. This situation leads to duplicated code regarding to the queries that are performed on these tables.

I was wondering if there is some construct (avoiding the use of the function eval) that might help me in this case; I really would like to avoid writing duplicated code that performs the same exact calls on just different static Peer classes.

example code snippet from a (very long) method of a class I am writing:

$criteria = new Criteria();
$criteria->add(FoobarPeer::CONTRACTNR,$data['contractnr']);
$result = FoobarPeer::doSelect($criteria);
if(count($result) > 1){
  throw new FoobarException("status: more than one row with the specified contractnr.");
}
if(count($result) == 0){
  // no object with given contractnr. Create new one.
  $obj = $this->factory->createORM("foobar");
  $obj->setCreatedAt(time());
} else {
  // use and update existing object.
  $obj = $result[0];
}

As you can see I managed to write a factory method for the row object, but I could not find a way to do the same for static classes. In other words, I would like to have the access to the static classes dynamic and not in a way that is an ugly workaround.

Any ideas?

thanks :)

Это было полезно?

Решение

I'm not really sure I fully understand what you are asking, but here's a solution to what I think you are asking:

function orm_for($type) {
    return strtolower($type);
}

function peer_for($type) {
    return ucfirst($type)."Peer";
}

function exception_for($type) {
    return ucfirst($type)."Exception";
}

function query($type, $data) {
    $peer = $peer_for($type);
    $exception = $exception_for($type);
    $obj = null;
    $criteria = new Criteria();
    $criteria->add($peer::CONTRACTNR, $data["contractnr"]);
    $result = $peer::doSelect($criteria);
    if(count($result) > 1) {
        throw new $exception("status: more than one row with the specified contractnr.");
    } else if(count($result) == 0) {
        $obj = $this->factory->createORM(orm_for($type));
        $obj->setCreatedAt(time());
    } else {
        $obj = $result[0];
    }
}

I think the code is self-explanatory. Let me know whether or not I interpreted your question correctly.

A live example (just a POC) can be found here

Другие советы

You should be able to use behaviors to achieve what you're trying to do. You can use behaviors to add custom code to the generated peer objects. See here.

Among other things, your behaviors can implement the following methods:

staticAttributes()   // add static attributes to the peer class
staticMethods()      // add static methods to the peer class

You should be able to use these to add the code you want to the peers. You only need to worry about writing the code once. Propel will duplicate the code during the code generation process, but this shouldn't be too much of a concern, as a lot of the generated is duplicated anyway. At least the duplication is only introduced by an automated process.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top