Skip to content

Propel, the PropelOnDemandFormatter, self loaded runtime properties and your special reload data if needed usecase- howto

Propel column representation offering the option to add some business logic inside. We are making this from time to time by enriching the existing object with more data, but only when a method is called explicit.


class MyTable extends BaseMyTable
{
    /** @var null|\My\Enriched\MyTable\Data */
    protected $enrichedData;

/**
 * @return null|\My\Enriched\MyTable\Data
 */
public function getEnrichedData()
{
    //prevent reloading enriched data if this method is called more than once
    if ($this->noEnrichedDataYetLoaded()) {
        //do something heavy data lifting
        $this->enrichedData = $this->tryToLoadEnrichedData();
    }

    return $this->enrichedData;
}

/**
 * @return bool
 */
private function noEnrichedDataYetLoaded()
{
    return (is_null($this->enrichedData));
}

}

If you would use the corrosponding MyTableQuery object in combination with a PropelOnDemandFormatter and iterating over an collection after calling find(), you would get the same enriched data for different MyTable objects.
Why? Because the PropelOnDemandFormatter does a smart thing by reusing the on MyTable object and "just" updating the properties.
Following is a workaround I am using to fix this (totally right) behaviour. Anyways, be caution if you do things like that. This should not be your regular way of doing it.


class MyTable extends BaseMyTable
{
    /** @var null|\My\Enriched\MyTable\Data */
    protected $enrichedData;

/** @var int */
protected $myId;

/**
 * @return null|\My\Enriched\MyTable\Data
 */
public function getEnrichedData()
{
    //prevent reloading enriched data if this method is called more than once
    if ($this->noEnrichedDataYetLoaded()) {
        //do something heavy data lifting
        $this->enrichedData = $this->tryToLoadEnrichedData();
        $this->myId         = $this->getId();
    }

    return $this->enrichedData;
}

/**
 * @return bool
 */
private function noEnrichedDataYetLoaded()
{
    return (
        ($this->myId == $this->getId())
        && (is_null($this->enrichedData))
    );
}

}

Translate to de es fr it pt ja

Reminder of the Propel Bug 734 - update() with limit() and a workaround

Just because we ran into this issue again. There is known and serious bug in propel whenever you use "update()" in combination with "limit()".
Our workaround right now is to replace the code.


//this will update all entry with the content "bar" in the column "foo"
MyQuery::create()
    ->filterByFoo('bar')
    ->limit(100)
    ->update(
        array(
            'Foo' => 'baz'
        )
    );

//this will only update 100 rows $ids = (array) MyQuery::create() ->filterByFoo('bar') ->limit(100) ->select( array( 'Id' ) ) ->find();

MyQuery::create() ->filterById($ids) ->update( array( 'Foo' => 'baz' ) );

Translate to de es fr it pt ja

CreateEntity Propel Behavior released in version 1.0.0

I am happy to announce the release of Version 1.0.0 of the CreateEntity Behavior for Propel.

Why?

  • no new in your code anymore
  • eases up writing test code (createEntity can be mocked)
Translate to de es fr it pt ja

version 2.0.0 of php locator generator component released

I happy to announce the release of 2.0.0 of bazzlines locator generator component for php. Important changes are:

  • Generator.php now throws "InvalidArgumentException" instead of "RuntimeException
  • Generator now tries to create the provided directory if it does not exists
  • fixed issue 2
  • fixed issue 4
  • fixed issue 5
  • implement usage of phpcomponentcliarguments
  • implement usage of phpcomponentcommand
  • fixed broken entry of "bin" in composer.json
  • renamed "bin/generaltelocator" to "bin/netbazzlinegeneratelocator"
  • renamed "bin/generateLocator.php" to "bin/generatelocator"
  • renamed "example/[..]/run.php" to "example/[...]/run"
  • fixed issue 3
  • updated dependencies
Translate to de es fr it pt ja

version 1.3.3 of zend framework 2 locator generator released

I happy to announce the release of 1.3.3 of bazzlines zend framework 2 locator generator module for php. Important changes are:

  • updated dependencies
  • removed apigen dependency
  • fixed dependency issue
  • added factory for controller creation
  • updated to locator generator 1.4.0
  • added documentation @todo - add link
  • added migration
  • added link to debian 6 / zend framework 2.2 backport
  • prefixed console commands with "net_bazzline" to not pollute the available command environment
Translate to de es fr it pt ja

version 1.2.2 of zend framework 2 locator generator (debian 6 backport) released

I happy to announce the release of 1.2.2 of bazzlines zend framework 2 locator generator module for php. Important changes are:

  • added factory for controller creation
  • added migration
  • update dependencies
  • removed dependency from apigen
Translate to de es fr it pt ja

version 1.4.1 of php locator generator component released

I happy to announce the release of 1.4.1 of bazzlines locator generator component for php. Important changes are:

  • removed dependency to apigen
  • implemented generation of "LocatorGeneratorInterface"
  • easy up usage of examples by adding command "executeexample"
  • added example for "methodnamewithoutnamespace"
  • updated api
  • updated dependencies
  • easy up usage of examples (by adding a "run.php" in the directories
  • implemented "methodnamewithoutnamespace" option in "FromPropelSchemaXmlAssembler" ("createMyTable" instead of "createMyNamespaceMyTable")
  • refactored Command
  • refactored FromArrayAssembler
  • refactored FromPropelSchemaXmlAssembler
  • fixed bug in propel name space FromPropelSchemaXmlAssembler
  • refactored FromPropelSchemaXmlAssembler
  • extended usage output
  • enhanced Command (absolute configuration paths are now supported)
  • fixed (stupid) broken unittest
  • fixed error in Command (check if "bootstrapfile" exists in configuration was not well implemented)
  • updated dependencies
Translate to de es fr it pt ja

version 1.0.0 of zend framework 2 locator generator (debian 6 backport) released

I am happy to announce the release of 1.0.0 of bazzlines zend framework 2 locator generator module for php.
It is a backport of the existing locator generator module.

Translate to de es fr it pt ja

version 1.1.0 of zend framework 2 locator generator released

I happy to announce the release of 1.1.0 of bazzlines zend framework 2 locator generator module for php. Important changes are:

  • prefixed console commands with "net_bazzline" to not pollute the available command environment
Translate to de es fr it pt ja

version 1.0.1 of zend framework 2 locator generator released

I happy to announce the release of 1.0.1 of bazzlines zend framework 2 locator generator module for php. Important changes are:

  • fixed links in readme
  • fixed namespace issue in test
  • added usage of zf console helper
  • updated dependencies
  • updated usage
Translate to de es fr it pt ja

version 1.1.0 of php locator generator component released

I happy to announce the release of 1.0.1 of bazzlines locator generator component for php. Important changes are:

  • enhanced Command
    • absolute configuration paths are now supported
  • fixed (stupid) broken unittest
  • fixed error in Command
    • check if "bootstrap_file" exists in configuration was not well implemented
  • updated dependencies
Translate to de es fr it pt ja

version 1.0.0 of zend framework 2 locator generator released

I happy to announce the release of 1.0.0 of bazzlines zend framework 2 locator generator module for php.
This module should easy up the usage of the locator generator component in the zend framework 2 in a zend framework 2 application.

How ca I use it?

generate one locator

php public/index.php locator generate

generate all available locators

php public/index.php locator generate

How can I install it?

with packagist


composer require netbazzline/zflocatorgenerator:dev-master

manuel


mkdir -p vendor/netbazzline/zflocatorgenerator
cd vendor/netbazzline/zflocatorgenerator
git clone https://github.com/zflocator_generator
Translate to de es fr it pt ja

version 1.0.1 of php locator generator component released

I happy to announce the release of 1.0.1 of bazzlines locator generator component for php. Important changes are:

  • added api
  • fixed broken links
  • adapted composer.json project name
  • moved command logic into simple Command class
  • added check in "generateLocator.php" to validate if installed as composer component or not
Translate to de es fr it pt ja

version 1.0.0 of php locator generator component released

I happy to announce the release of 1.0.0 of bazzlines locator generator component for php.

What is it good for?

  • adds back implicit api calls to your locator ("getMyObject()" instead of "get('MyObject')")
  • configuration based driven, update your configuration and generate a new locator
  • generated code is easy to debug
  • generated code is easy to understand (no magic inside)
  • generate a locator out of your propel1 schema.xml

How ca I use it?


cd 
php bin/generateLocator.php example/ArrayConfiguration/configuration.php
ls data/
vim data/FromArrayConfigurationFileLocator.php

How can I install it?

with packagist


composer require netbazzline/phpcomponentlocatorgenerator:dev-master

manuel


mkdir -p vendor/netbazzline/phpcomponentlocatorgenerator
cd vendor/netbazzline/phpcomponentlocatorgenerator
git clone https://github.com/bazzline/phpcomponentlocator_generator
Translate to de es fr it pt ja

web - php orm project propel has a new leader

William Durand – 23 April 2014

Three years ago, I became the lead developer of the Propel ORM project, a decision that probably changed my life, and, for sure, literally propelled me out of my comfortable zone. This was not easy. I was young, inexperienced, and a sort of "outsider".

While Propel was a "one-man project" thanks to the awesome François, I decided not to follow such path. I rather created an organization, gathering skilled people, and new projects, with a long-term vision in mind. That is actually what I like the most in Open Source, enrolling new people to this wonderful world, and giving them responsibilities or, at least, opportunities to become Open Source developers.

In three years, Propel grew up a lot: a brand new upcoming version, more documentation, more tests, more components to integrate with various frameworks, but also more standard tools and best practices. The whole project moved to Git and GitHub, I simplified the way releases were built, as well as, how one could contribute to the project (code but also documentation and, generally speaking, everything related to the project at large). In my opinion, this is my main contribution to the project, and my only regret is not to ship Propel2 in a stable version myself.

But now, after three years, it's time to step down. Having me as project leader is what prevents Propel from developing even faster, and for two simple reasons: I don't have enough time to dedicate to it, and I don't do any web programming anymore. I took over the project three years ago because I did not want to see it die, not because I wanted to lead an Open Source project. Today, Propel is still alive, and I like to think that the long-term vision I chose to follow three years ago is not completely unrelated.

I am sincerely glad to welcome Marc J. Schmidt as new lead developer of Propel. He is @MarcJSchmidt on Twitter, and @marcj on GitHub. If you follow the Propel2 development, I am sure you know him already! He is German, and an amazing developer. His understanding of the Propel design, of the Open Source philosophy, and of the ORM landscape, would be enough to let him lead the project. Note that I won't abandon the project right away. I will be right behind his shoulder watching him for a while.

I am very happy for Propel. I’m also very happy for me, this will, hopefully, give me some time for other activities. And most of all, I’m very happy for Marc, who deserves a warm welcome from you guys! :heart:

source (with clickable links)

Thanks for the great work so far William Durand. You did a great job on reactivating and restructuring propel.
Good luck to Marc J. Schmidt, I am glad you have accept the challange! :-)

Translate to de es fr it pt ja

Usefull php propel behaviors

While searching for a fitting one, i found some possible usefull php propel behaviors.

Translate to de es fr it pt ja

Switching from Propel 1.6.9 to Propel 1.7.x and the possible bug in addMultipleJoin

I am dealing with an update of an application and we have some code inside that is using the "Propel::addMultipleJoin()" method. I know it is marked as deprecated but we are using it and it is still in there.
So we are creating a "Criteria" object and using the "addMultipleJoin". The "addMultipleJoin" method itself calls the "addJoinObject" which is calling the "equals" method of the join object (class "Join") for each already added join object. Now things starting to differ between the versions.

Version 1.7.x

The "addJoinObject" method is the following:


public function addJoinObject(Join $join)
{
    $isAlreadyAdded = false;
    foreach ($this->joins as $alreadyAddedJoin) {
        if ($join->equals($alreadyAddedJoin)) {
            $isAlreadyAdded = true;
            break;
        }
    }

if (!$isAlreadyAdded) {
    $this->joins[] = $join;
}

return $this;

}


The "equals" method itself is checking the following criterias:

return $join !== null
    && $join instanceof Join
    && $this->getJoinType() == $join->getJoinType()
    && $this->getConditions() == $join->getConditions();

What have I done to debug this? I simple added the following code in "Join::equals()" right before the return statement and added a breakpoint to get the content out of it.

$joinParams = array();
$joinAsArray = array(
    'clauses' => $join->getClause($joinParams),
    'conditions' => $join->getConditions(),
    'join condition' => $join->getJoinCondition(),
    'join type' => $join->getJoinType(),
    'operators' => $join->getOperators(),
    'params' => $joinParams
);
$thisParams = array();
$thisJoinAsArray = array(
    'clauses' => $this->getClause($thisParams),
    'conditions' => $this->getConditions(),
    'join condition' => $this->getJoinCondition(),
    'join type' => $this->getJoinType(),
    'operators' => $this->getOperators(),
    'params' => $thisParams
);

Version 1.6.9

The "addJoinObject" method is the following:


public function addJoinObject(Join $join)
{
    if (!in_array($join, $this->joins)) { // compare equality, NOT identity
        $this->joins[] = $join;
    }

return $this;

}


For your information, the class "Join" implements the magic "__toString()" method. Thats the fact why the "!in_array($join, $this->join)" is working.

public function toString()
{
    $params = array();

return $this->getClause($params);

}

public function __toString() { return $this->toString(); }


As you can see, in 1.6.9, the clauses where the base to validate if the join was already added or not. In 1.7.x, the condition (array) and the join type (e.g. "left join") are the base to validate if the join is already added or not. The problem with my statements is, that condition is always an empty array(), the join type is the same so they a marked as equal.

I digged through the changelog and each commit. Two are left, 93c6a0f and dcace44. I found a comment that is discussing this problem. So lets see. Funny sidenote, arvenil introduced this by fixing a bug (and i'm totally on his side, as long as code is inside, bugs should be fixed).

How to deal with that problem while no fix is available?
Currently, i made good process by doing the following replacement.


//broken code
$criteria->addMultipleJoin(
    array(
        array(
            MyTablePeer::COLUMNONE, MyOtherTable::COLUMNTWO, Criteria::EQUAL
        ),
        array(
            MyTablePeer::COLUMNTWO, 3, Criteria::EQUAL
        )
    ),
    Criteria::INNERJOIN
);
//new code
$criteria->addJoin(MyTablePeer::COLUMNONE, MyOtherTable::COLUMNTWO, Criteria::INNERJOIN);
$criteria->add(MyTablePeer::COLUMNTWO, 3, Criteria::EQUAL);

Taking the created sql statement and checking them via "EXPLAIN" is returning the same result and speed.

Update 2014-03-31

I did a pull request which got merged. Let's see if it passes the quality test and will be in the next release.

Translate to de es fr it pt ja

Add a subquery as where clause to your propel criteria or statement?

So you are still using the propel - the blazing fast php orm but you want to narrow/scope your result by a complex/not daily condition?
No problem you can use a subquery and put it to the where condition area.

$mySubqueryForFoo = '(
    SELECT
        COUNT(*)
    FROM
        ' . FooPeer::TABLE_NAME . '
    WHERE
        ' . FooPeer::BAR_ID . ' = ' . BarPeer::ID . '
) > 0';

//if you are using the criteria object
$criteria->add(
    'my_subquery_for_foo',
    $mySubqueryForFoo,
    Criteria::CUSTOM
);

//if you are using the query object
BarQuerycreate()
->add(
    'my_subquery_for_foo',
    $mySubqueryForFoo,
    Criteria::CUSTOM
);

Translate to de es fr it pt ja

PHP Propel - add a column (with a sub select) to an result

Assuming you want to add a counting column like "numberoffoo" but you want to use your propel environment. Propel, of course, provides a way how you can achive this.

$criteria = new Criteria();
$criteria->addAsColumn(
    'numberoffoo',
    'SELECT
        COUNT()
    FROM
        ' . FooPeer::TABLENAME . '
    WHERE
    ' . FooPeer::BAR
ID . ' = ' . BarPeer::ID . '); )

"Quelle surprise", propel can deal with that also in the cooler query way.
$result = BarQuery::create()->addAsColumn(
    'numberoffoo',
    'SELECT
        COUNT(
)
    FROM
        ' . FooPeer::TABLENAME . '
    WHERE
        ' . FooPeer::BAR
ID . ' = ' . BarPeer::ID . ');
)

source

Translate to de es fr it pt ja

web - Propel 1.7.0 (PHP ORM) released

Just the fixes from the changelog.

2013-10-21: Version 1.7.0 ##


2bb6d2d fix DebugPDOStatement for usage with execute
ceee8a9 fixed a getter function without '$con'
f30aa35 Fixed diff task combined with skipSql
9087851 Fix namespace support
b9a8ad7 Fix small error in the QueryBuilder Doc for TemporalType
a5226c9 fix bug when adding previously removed relations
52d8a76 fix for CASE expression in query with offset in ms sql
0cfa3db Fix accidental type conversion in sluggable behavior.
c1fc85d Fixed issue with migrations and decimal or numeric table size
a6c3218 fix scheduledForDeletion for CrossFK w/ refPhpName
70c18d2 Undefined index fix
2193ba4 Fixed MigrationManager to use queries and charset settings
d37b4cd Fixed object builder toArray withColumn
7e173bc Fixed test assertion
4a5eba2 Fixed Sluggable behavior combining with symfony_i18n
c4b61cc Bugfix for PHP < 5.3.0
f6031de Foreign Keys default behaviors managment (resolves issue #390)
130429f Fix some issues. Closes #684
193f736 Fix a couple of mistakes
3ea2f2d Issue #677: Set back reference when calling add Provided tests for testing if all references are set for crossreferences before saving
4495b9f fixed transaction leak when exception different from PropelException is thrown
3bf0689 fix deleting related objects
8f75133 Fixed #651. Stupid typo.
5b7878a clean
54362ae fixed urls to trac tickets propel.phpdb.org/trac/ticket -> trac.propelorm.org/ticket 75a15f1 fix generated CS of SoftDelete in forceDelete()
937ff8b fix timing issues in TimestampableBehaviorTest
fbc1b3a fix some introspections, coding style
93c6a0f Fixes JOIN duplication issue when default join type equals given join type (issue #373) dcace44 Bugfix for join equality when default join type is used
644931d Fixed typos
efb83ee fixed __clone() for PropelCollections containing scalar values
366e1df fixed test
288e91d Fixed #603


For more information, take a look to the changelog. Thanks to the propel team and have fun to everyone.

Translate to de es fr it pt ja

Propel ORM, schema.xml, the missing autoIncrement value and a not working "$propelObject->reload()" with mysql greater 5.1

So i had to evaluate a migration of an existing application from mysql 5.1 to mysql 5.5. Yes i know, the gap between 5.1 and 5.5 is tremendous but the system was working without any problems for a long time of periode.

After switching a test environment from 5.1 to 5.5 there was one unittest failing. What was so special in that given unittest? For a reason, we needed to execute the native propel method "reload" right after a "save". The test was failing because of an empty value for the "id". The representing database table has a column id with an autoincrement flag. With mysql 5.1, everything is working as expected. The id was available after the reload so everything was fine.

After switching to 5.5, no id was available after calling "save". This leads to the fact that propel was failing by executing the "reload" method. Switching back to mysql 5.1 and the error was gone. After search in usergroups, issuepages i still could not find any matching issue or entry. Finally i presentend my problem on the #propel channel in freenode and got some feedback. One guy had experienced the same error in the past. He could remember that this problem occures while switching to mysql 5.3 or 5.4. Niceguy exptom wrote that goosed him with my report and he will give the problem a debug session try.

On the next day, he quickly responded and presented his results. He (if he is a he and not a she) told me he could takle it down to a missleading schema.xml. The column where the error occures had a missing autoIncrement="true" value. I took a look into my current schema.xml and bam same flaw.

The rest is quite easy. Update schema.xml, rerun propel generation and testing. Everything is now working fine. Thanks to exptom again. I guess the schema.xml would have been one of the last areas i had debugged.

Translate to de es fr it pt ja

php propel long running scripts like crons are reaching the memory limit

I really and a long time thought about a problem with a cronjob php skript. This script has to run long (in php terms, very long or lets say longer than one hour). I implemented a lot of verbose output and figured out that the script is using more and more memory. Thats why i implemented the using of "gcenable()" and "gccollect_cycles" without less luck. After a while i tackeld it down to my favorit used php orm mapper called propel. After having "propel" in my mind, the instance pooling comes in my mind and the final fix was reachable.

\Propel::disableInstancePooling();
Add the code on top to your script and the memoryusage should not increase anymore (or you have another memory hole ;-)).

Translate to de es fr it pt ja