learning repose

4 views
Skip to first unread message

aek

unread,
Aug 10, 2010, 9:47:47 AM8/10/10
to Repose PHP ORM General Discussion
I am a optimistic Java developer that for a while has been worked with
IMHO the best frameworks that you can check out in Java world. I
created a software architecture around Spring Framework, Hibernate,
ExtJS and so many other cool frameworks that is domain object centric
and very productive. I want to do the port to PHP because the my
software architecture is simply a way to do things quickly using the
frameworks more productive to me. I just want to have a good MVC, a
good ORM and some other things that can be created or integrated for
the task. I like the conception idea of Repose ORM and I want to know
a few things about it.
In my first test of the framework I couldn't do the normal things that
I can do with Hibernate and I don't know if the problem is PDO or
Repose.
The name of my database table and their fields need to begin with a
lowercase character. In Hibernate there is a way to correctly quote
the generated SQL in the way of the SQL dialect configured to supports
this kind of problems.
The class properties need to be public, there is no way to use the
getter and setter approach.
The public properties of any parent class is no visible to
ReposeMapping and this is a very useful requirement to my project.
I want to know what is the method of the session to do an update. I
think that maybe the same as insert (add), but It's not clear.

I think that your project is very helpful to the PHP frameworks stack
to bring some order to the chaos of the Active Records ORMs.
Just my honest opinion

Beau Simensen

unread,
Aug 10, 2010, 8:11:17 PM8/10/10
to repos...@googlegroups.com
Hi! Thanks for your questions. :) Let me see if I can start addressing some of them...


The name of my database table and their fields need to begin with a lowercase character.

It should not be a problem to have a table name or property name mapped to something completely different in the database. How are you creating your mapping? Are you using the Configuration Session Factory?

The table name can be specified and the SQL will be exactly the same as what you specify in the configuration. If you specify 'tableName' it should have a lowercase t in the SQL. If you are seeing a problem with this please let me know which database you are using.

The same is true for properties. You can specify 'columnName' to ensure that a specific column name is used for your property if it is different than the name used in your class for your property. (the docs may have been wrong here earlier... they have now been updated)



In Hibernate there is a way to correctly quote the generated SQL in the way of the SQL dialect configured to supports this kind of problems.

So far I have been testing exclusively with PDO using MySQL and sqlite. I have run into problems with the latter that have given me a reason to consider beefing up the multi database / dialect configuration options. Out of curiosity, which database are you trying ot use?


The class properties need to be public, there is no way to use the getter and setter approach.

This is only a restriction for PHP versions earlier than PHP 5.3 due to limitations of PHP reflection. If you are using PHP 5.3 or later and are still seeing this problem please let me know. I have been trying to test both but there may still be some errors. :)


The public properties of any parent class is no visible to ReposeMapping and this is a very useful requirement to my project.

This is something I will have to look into. I can see how this might be useful.


I want to know what is the method of the session to do an update. I think that maybe the same as insert (add), but It's not clear.

I will have to update the manual and instructions to make this more clear. Any object that is a part of the session will be added/updated/deleted as required upon flush. So if you query a session for an existing object, make changes, and flush, your data will be updated in the database.




--

Beau D. Simensen


Dragonfly Development Inc
http://dflydev.com/

s3a - Fresh. Urban. Seattle.
http://s3attle.com/


[blog] http://not-invented-here.com/
[flickr] http://flickr.com/photos/kirkryyn
[facebook] http://facebook.com/simensen



--
You received this message because you are subscribed to the Google Groups "Repose PHP ORM General Discussion" group.
To post to this group, send email to repos...@googlegroups.com.
To unsubscribe from this group, send email to repose-php+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/repose-php?hl=en.


aek

unread,
Aug 11, 2010, 10:54:58 AM8/11/10
to Repose PHP ORM General Discussion
Hi, thanks for the quickly response.
I use PostgreSQL as my default database, and I tend to type the name
of the tables and the table fields beginning with an uppercase
character, because of that I raise errors like SQLSTATE[42703] and
SQLSTATE[42P01] that dissapear after I rename all in my table to begin
with a lowercase character, I think that is a problem with the quotes
in the SQL generated. From the Hibernate reference:

5.4. SQL quoted identifiers
You may force Hibernate to quote an identifier in the generated SQL by
enclosing the table or column name in
backticks in the mapping document. Hibernate will use the correct
quotation style for the SQL Dialect (usually
double quotes, but brackets for SQL Server and backticks for MySQL).

> Are you using the Configuration Session Factory?
Yes, I am following the examples of the wiki


> Out of curiosity, which database are you trying ot use?
Like I said I use PostgreSQL, but just for store the data, I think
that the ability to switch form one database to another brings to the
ORM a big power. I use Ubuntu 10.04, with all the latest packages.

> Any object that is a part of the session will be added/updated/deleted as
> required upon flush. So if you query a session for an existing object, make
> changes, and flush, your data will be updated in the database.

I asked that because it will be helpful if the session can offer an
update or merge method that can generate an update SQL statement
without the need of previously select SQL statement.

Other question that I have is related with the autoloader strategy:
I debug the code and I see that the data is being retrieved from the
database but repose cannot create an object because it cannot load the
class from the location where they live, this is with the
repose_ClasspathAutoloader because it search for classes in .:/usr/
share/php:/usr/share/pear. I want to know if there is a more automatic
way than using repose_CallbackAutoloader for manual autoload of
classes from the location. I continue my search in this way to
complete the example in my DAO using repose.

Another thing is about transaction I don't like to manage transactions
in the DAO because it's a role of the business layer to grap a bunch
of database actions. If some of this topic are covered in Repose let
me know.

I will be glad to contribute to the development of this project even
when I am a Java developer.

Beau Simensen

unread,
Aug 11, 2010, 12:28:14 PM8/11/10
to repos...@googlegroups.com
It would be nice to have someone who actively uses Postgres to help get it working for that database. Let me look a bit more into finding a way to add better support for multiple dialects and we can see if we can get you to try some of those changes out. I think that is probably the best thing to tackle first.

Autoloading right now is pretty basic. I need to find a way to extend the capabilities of the built in autoloader through the Configuration Session Factory. If you want to have a workaround for the time being, you can see what I put together for Repose-CI... 


specifically this line, which creates an autoloader that looks for classes at a specific path:

new repose_PathAutoloader($config->item('repose_model_libs'));

I will try to build this into the Configuration Session Factory ASAP

As far as transactions, I do not have any transaction support built into the data access object as of yet. You can "fake" it by simply not flushing a session if something goes wrong. This would allow you to keep a lot of sanity checking in your application logic.

For instance, in a section of code you might want to roll back, open up a brand new session, make changes to your objects, and if any errors come up, do not flush that session. You should be good to go. Of course this will not handle any cases where you might have an exception thrown from the data source layer... so it isn't a perfect solution.



--

Beau D. Simensen


Dragonfly Development Inc
http://dflydev.com/

s3a - Fresh. Urban. Seattle.
http://s3attle.com/


[blog] http://not-invented-here.com/
[flickr] http://flickr.com/photos/kirkryyn
[facebook] http://facebook.com/simensen



--

aek

unread,
Aug 20, 2010, 2:59:34 PM8/20/10
to Repose PHP ORM General Discussion
Hi, I have been playing with all of your frameworks to build my
software architecture on PHP, and now I have some ideas to share with
you.
When I came to PHP world there are some things that I need to learn or
adapt. One of this is the classpath, the need of use require_once all
over the place. I saw that repose has his own classloader
(repose_ClasspathAutoloader), halo and substrate use the classloader
from hc (hc_core_ClassLoader), and skittle use the filelocator of hc
(hc_core_FileLocator).
because of that I start search. All of three use those class for the
same. I found an universal, simple classloader and file locator for
php in http://www.thetricky.net/php/php-class-loader. I have been test
it and it works awesome. It provide a cache solution for store the
calculated paths in the selected cache strategy and is an open source
solution. check it out and forget a little about use require_once and
classloaders.

About Repose:
I implement my CommonDao and it work fine for postgres, even my
listByExample that use pagination. I think that the pagination is one
of the thing that its database dependent but for postgres works fine.
The only think that is not working is the example part of the method
that take as an example an Object to call filterBy method of the
repose_FluidQuery because I need to do a like anywhere with the table
fields.
Any points on this?
The transactions topic has a simple solution to allow the user code to
use transactions, the only needs are 3 methods:

In repose_Session:
public function commit() {
$this->engine()->commit();
}

public function rollBack() {
$this->engine()->rollBack();
}

public function beginTransaction(){
$this->engine()->beginTransaction();
}

And in repose_PdoEngine
public function commit() {
$this->dataSource->commit();
}

public function rollBack() {
$this->dataSource->rollBack();
}

public function beginTransaction(){
$this->dataSource->beginTransaction();
}

I hope this help.

About Halo:
I wrote in the halo discussion group about some topics. First is the
need of a MultiAction controller, I start my own solution.
Also I have been working on an basic implementation of the bind
method. Due to that I think that It would be helpful that
halo_HttpRequest take another property or something like that to unify
the post and get parameters using a new method getParameter like the
similar in HttpServletRequest and getParameterNames returning the keys
of the parameters array.
I will work in an InternalResourceViewResolver too.

About Skittle:
Im still confusing about skittle, I need something like JSP expression
language, and I think that skittle is ok, but I couldn't figure out
how to use it. Is there an example of use the values in the model in
an skittle view?
The most simple view in my architecture need to render a json string
that is contructed in the controller and passed in the model under the
variable name "json".

In JSP is simple as:
${json}

In skittle could be:
<?php echo $json;?>

or
<?php $s->p($json); ?>

In the method stringInc of skittle_Skittle the use of:
$realPath = $this->fileLocator->find($path);
could be replaced with:
$realPath = classLoader::getClassPath($path);
Changing the visibility of the method getClassPath of classLoader to
public. I do this because the resolution of my views was fail due to
this line because the filelocator don't know where are my views.

This are only my suggestions.
This are greats frameworks, Congratulations

aek

unread,
Aug 27, 2010, 4:27:40 PM8/27/10
to Repose PHP ORM General Discussion
Hello
I have another question, I notice that before save an object to do an
insert using repose_Session the object need to have setted the primary
key. I notice that there are an uuid generator for the proxy objects.
There are a way in Repose to get the primary key generated
automatically? like in Hibernate?. I love hi/low (hilo) key generator
strategy of Hibernate and I start search for a solution but I need to
know your opinion or suggestions. When I finish of the build of the
complete example a CRUD, I like to discuss some topics about all of
this. I have now an stable version of MultiActionController and the
PropertiesMethodNameResolver that is my prefered MethodNameResolver
strategy, the others that ship with Spring MVC are implemented but not
tested, yet.
How can I share those source code with you?
remember my question about repose Ids.

Beau Simensen

unread,
Aug 27, 2010, 4:38:50 PM8/27/10
to repos...@googlegroups.com
I need to look into the primary key handling. I know that I had intended to allow for other types of primary keys than the auto increment variety but I am not sure how far along that code was. I'll bump that to the 0.0.9 release.



--

Beau D. Simensen


Dragonfly Development Inc
http://dflydev.com/

s3a - Fresh. Urban. Seattle.
http://s3attle.com/


[blog] http://not-invented-here.com/
[flickr] http://flickr.com/photos/kirkryyn
[facebook] http://facebook.com/simensen


Beau Simensen

unread,
Sep 1, 2010, 11:30:54 PM9/1/10
to repos...@googlegroups.com
> When I came to PHP world there are some things that I need to learn or
> adapt. One of this is the classpath, the need of use require_once all
> over the place. I saw that repose has his own classloader
> (repose_ClasspathAutoloader), halo and substrate use the classloader
> from hc (hc_core_ClassLoader), and skittle use the filelocator of hc
> (hc_core_FileLocator).
> because of that I start search. All of three use those class for the
> same. I found an universal, simple classloader and file locator for
> php in http://www.thetricky.net/php/php-class-loader. I have been test
> it and it works awesome. It provide a cache solution for store the
> calculated paths in the selected cache strategy and is an open source
> solution. check it out and forget a little about use require_once and
> classloaders.

I took a quick look at this class loader:

http://www.thetricky.net/php/php-class-loader

I feel like it is probably too restrictive and is not flexible enough
to allow for an individual developer to code with their own
conventions. One of the goals I have had for most of my projects is to
make them friendly enough that they can be used in almost any
environment.

I'll have to look at the Repose implementation and figure out where to
go from here. I really do not want it to be too complicated but I
don't want to force people to conform to any specific rules, either.

I have not looked at Substrate or Halo in awhile and as such I cannot
comment much beyond the fact that I know it relied quite a bit on the
hc_core_* packages.

Beau Simensen

unread,
Sep 2, 2010, 12:40:01 AM9/2/10
to repos...@googlegroups.com
In case you are still stuck on the autoloader from Repose, I have
finished giving repose_Configuration the ability to specify a custom
autoloader. Here is an example of how it may be used:

http://gist.github.com/561874

You could use this to implement an autoloader wrapper around whatever
autoloader you prefer.


--

Beau D. Simensen


Dragonfly Development Inc
http://dflydev.com/

s3a - Fresh. Urban. Seattle.
http://s3attle.com/

aek

unread,
Sep 2, 2010, 1:46:44 PM9/2/10
to Repose PHP ORM General Discussion
> I need to look into the primary key handling. I know that I had intended to
> allow for other types of primary keys than the auto increment variety but I
> am not sure how far along that code was. I'll bump that to the 0.0.9
> release.

here is my own version of Hilo identifier generator for php and
repose. like in Hibernate it need to use a new connection for the
querys, so it needs to be configure it to connect with database via
PDO. It makes sense to config the table name and the next_hi field but
its the first version. To work properly or more efficiently is better
to have an previusly initiated session using session_start()

interface repose_IdentifierGenerator {
public function generate($className);
}

class repose_HiLoIdentifierGenerator implements
repose_IdentifierGenerator{
private $dsn;
private $username;
private $password;

public function generate($className){

if(isset($_SESSION["HiValues"])){
$domainClassesHiValues = $_SESSION["HiValues"];
if(isset($domainClassesHiValues[$className])){
$hival = $domainClassesHiValues[$className][0];
$hi = $domainClassesHiValues[$className][1];
$lo = $domainClassesHiValues[$className][2];
} else {
//$hival = $this->getNext();
$lo = 32768;
}
} else {
$lo = 32768;
$domainClassesHiValues = array();
}

if ($lo > 32767) {
$hival = $this->getNext();
$lo = ($hival == 0) ? 1 : 0;
$hi = $hival * 32768; //$hiVal * (Short.MAX_VALUE + 1);
}

$next = $hi + $lo++;

$values = array();
$values[] = $hival;
$values[] = $hi;
$values[] = $lo;
$domainClassesHiValues[$className] = $values;

$_SESSION["HiValues"] = $domainClassesHiValues;
return $next;
}

public function getNext(){
$conn = new PDO($this->dsn, $this->username, $this->password);

$select = 'select next_hi from repose_unique_key for update';
$update = 'update repose_unique_key set next_hi = :next_hi where
next_hi = :old_hi';
$query = $conn->prepare($select);
$query->execute(array());

$rows = array();
foreach ( $query->fetchAll(PDO::FETCH_ASSOC) as $row ) {
$rows[] = $row;
}

$hi = $rows[0]['next_hi'];

$query = $conn->prepare($update);
$params = array();
$params['next_hi'] = $hi+1;
$params['old_hi'] = $hi;
$query->execute($params);

return $hi+1;
}

public function setDsn($dsn){
$this->dsn = $dsn;
}
public function setUsername($username){
$this->username = $username;
}
public function setPassword($password){
$this->password = $password;
}
public function getDsn(){
return $this->dsn;
}
public function getUsername(){
return $this->username;
}
public function getPassword(){
return $this->password;
}
}

aek

unread,
Sep 2, 2010, 1:47:51 PM9/2/10
to Repose PHP ORM General Discussion
> I feel like it is probably too restrictive and is not flexible enough
> to allow for an individual developer to code with their own
> conventions. One of the goals I have had for most of my projects is to
> make them friendly enough that they can be used in almost any
> environment.

Since I start using it I forget about the need of use require_once to
load a class because that class loader find it, include it, and cache
the class path for me. he only need to include at the top of the
script,
and tweek some changes. here are my tweeks:

<?php
/*
****************************************************************
PHP Class Loader
Copyright (C) 2008 Sébastien Roch

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
****************************************************************


PHP Class Loader
Author : Sébastien Roch <seba...@thetricky.net>
Date : 21.10.2008
Version: 1.0

PHP Class Loader
========================
Include this file at the beginning of your pages, it will
automatically include classes when
you invoke un-included classes.
The following things are required for this library to work:
- your class names must have the same names as your filenames. case
is not sensitive.
- all your class files have to end with the same suffix. Default is
".class.php".
- one class per file

CACHE
========================
A basic cache stores the found paths to your classes. It stores its
data with APC, in a file or
in a session (Don't forget session_start()), depending on the
configuration.

As class files rarely change of directory, there is no cache
expiration time: you'll have
to delete manually the cache if you move your files or change your
directory structure!
Use one of these public functions, depending on the type of cache you
use in your configuration:
classLoader::clearCache_APC();
classLoader::clearCache_file();
classLoader::clearCache_session();

CONFIGURATION
========================
You can configure the library at the beginning of the class
classLoader. Each setting has
an explanation. Don't touch the rest, should run...

FEEDBACK
========================
Comments, bug report and criticisms appreciated. Send to
seba...@thetricky.net
*/

/**
* Main class
*/
abstract class classLoader{

/***************************/
/* EDIT CONFIGURATION HERE */
/***************************/

/**
* The directory where the classes are locateda
* Will be browsed recursively
*/
const CLASSFILES_DIRECTORY = '.';

/**
* Only files ending with this suffix will be taken into account
*/
const CLASSFILE_SUFFIX = '.php';

/**
* Set whether or not to use the cache. If you have a lot of classes,
* highly recommended to true!
*/
const USE_CACHE = true;

/**
* What to use for cache
* 'APC': the fastest, but must be supported by your configuration
* 'FILE': second best choice, but you need a writable directory
somewhere
* 'SESSION': last choice, if APC and FILE not possible. You have to
care about session_start()!
*/
const CACHE_TYPE = 'FILE';

/**
* The path to the cache file when using a file for cache
* Make sure PHP can write in the directory
*/
const CACHEFILE_PATH = "cache/classLoader.cache";

/**
* The cache lifetime in seconds when using APC cache
* Default to 0, never expire. Clear the cache manually with
classLoader::clearCache_APC()
*/
const APC_CACHE_LIFETIME = 0;

/*************************/
/* END OF CONFIGURATION */
/*************************/

/**
* Called by __autoload function. Get and cache the path of given
class
*
* @param string $className
* @return string the path to the file
*/
public static function getAndCache_file($className){
$path = null;
if(!self::USE_CACHE){
return self::getClassPath($className.self::CLASSFILE_SUFFIX);
}

if(file_exists(self::CACHEFILE_PATH)){
// the cache file exist, we try to extract the class path
$fp = fopen(self::CACHEFILE_PATH, 'r+b');
$cacheData = unserialize(fread($fp, filesize(self::CACHEFILE_PATH)
> 0 ? filesize(self::CACHEFILE_PATH) : 1));
// the classname was found
if(isset($cacheData[$className])){
$path = $cacheData[$className];
}
// else get the path and update the cache
else{
$path =
classLoader::getClassPath($className.self::CLASSFILE_SUFFIX);
$cacheData[$className] = $path;
rewind($fp);
if(fwrite($fp, serialize($cacheData)) === false){
trigger_error('Could not write in cache file ' .
self::CACHEFILE_PATH . '.');
}
}
fclose($fp);
}
else{
$path =
classLoader::getClassPath($className.self::CLASSFILE_SUFFIX);
$toStore = serialize(array($className => $path));
$fp = @fopen(self::CACHEFILE_PATH, 'wb');
if($fp){
if(fwrite($fp, self::CACHEFILE_PATH, $toStore) === false){
trigger_error('Could not write in cache file ' .
self::CACHEFILE_PATH . '.');
}
fclose($fp);
}
else{
trigger_error('Could not open cache file: ' .
self::CACHEFILE_PATH, E_USER_ERROR . '.');
}
}
return $path;
}

/**
* Called by __autoload function. Get and cache the path of given
class
* into session. Don't forget session_start()!
*
* @param string $className
* @return string the path to the file
*/
public static function getAndCache_session($className){
$path = null;
if(!self::USE_CACHE){
return self::getClassPath($className.self::CLASSFILE_SUFFIX);
}

if(isset($_SESSION['classLoader'])){
if(isset($_SESSION['classLoader'][$className])){
$path = $_SESSION['classLoader'][$className];
}
else{
$path =
classLoader::getClassPath($className.self::CLASSFILE_SUFFIX);
$_SESSION['classLoader'][$className] = $path;
}
}
else{
$path =
classLoader::getClassPath($className.self::CLASSFILE_SUFFIX);
$_SESSION['classLoader'] = array();
$_SESSION['classLoader'][$className] = $path;
}
return $path;
}

/**
* Called by __autoload function. Get and cache the path of given
class
* into APC cache.
*
* @param string $className
* @return string the path to the file
*/
public function getAndCache_APC($className){
$path = null;
if(!self::USE_CACHE){
return self::getClassPath($className.self::CLASSFILE_SUFFIX);
}
$path = apc_fetch($className);
if($path !== false){
return $path;
}
else{
$path =
classLoader::getClassPath($className.self::CLASSFILE_SUFFIX);
apc_store($className, $path, self::APC_CACHE_LIFETIME);
}
return $path;
}

/**
* Call this function to delete the file cache
*
* @return boolean true if file was deleted
*/
public static function clearCache_file(){
if(@file_exists(self::CACHEFILE_PATH )){
return unlink(self::CACHEFILE_PATH);
}
return false;
}

/**
* Call this function to delete the cache in session
*/
public static function clearCache_session(){
if(isset($_SESSION['classLoader'])){
unset($_SESSION['classLoader']);
return true;
}
return false;
}

/**
* Call this function to delete the APC cache
*/
public static function clearCache_APC(){
return apc_clear_cache();
}

/**
* get a class name and a directory path to search
* Tries to find the corresponding file ending with CLASSFILE_SUFFIX
and
* return its path
* Recursive function
*
* @param string $className "Site.class.php" for example
* @param string $basePath
* @return string the path to the file
*/
public static function getClassPath($className,
$basePath=self::CLASSFILES_DIRECTORY){
$handle = @opendir($basePath);
if($handle === false){
trigger_error('Could not open directory ' . $basePath . '.',
E_USER_ERROR);
return null;
}
while(false !== ($file = readdir($handle))){
if($file != '.' && $file != '..'){
if(is_dir($basePath.'/'.$file)){
$in_dir = self::getClassPath($className, $basePath.'/'.$file);
if(!is_null($in_dir)){
return $in_dir;
}
}
else{
if(strtolower($file) == strtolower($className)){
return $basePath.'/'.$file;
}
}
}
}
return null;
}
}

/**
* Executed automatically by PHP when a class could not be found
*
* @param string $className
*/
function __autoload($className){
switch(classLoader::CACHE_TYPE){
case 'APC': $path = classLoader::getAndCache_APC($className); break;
case 'FILE': $path = classLoader::getAndCache_file($className);
break;
case 'SESSION': $path =
classLoader::getAndCache_session($className); break;
default: trigger_error('Configuration: cache type not supported:
"'.classLoader::USE_SESSION_CACHE.'".', E_USER_ERROR);
}
if(is_null($path)){
trigger_error('Could not load class ' . $className . '.',
E_USER_ERROR);
}
require_once $path;
}

?>

aek

unread,
Sep 14, 2010, 4:48:28 PM9/14/10
to Repose PHP ORM General Discussion
Hi, I continue to using your greats frameworks and looking for what
can be improve using my own experience with them. I notice that there
are a little issue in repose_ProxyGenerator that you try to solve
calling serialize and unserialize in method makeProxy. The issue is in
the method assertProxyClassExists in this code

foreach ( $this->session->getProperties($clazz) as $property ) {
try {
$reflectionProperty = $reflectionClass-
>getProperty(
$property->name()
);

can be replaced with something like this to get all accesible fields
even those that are inherit from a parent

$properties = $this->allfields($reflectionClass);
foreach ( $this->session->getProperties($clazz) as $property ) {
try {
$reflectionProperty = $properties[$property-
>name()];


the method allfields

public function allfields($clazz){
$properties = array();
if($clazz instanceof ReflectionClass){
$reflectionClass = $clazz;
} else {
$reflectionClass = new ReflectionClass($clazz);
}

foreach ($reflectionClass->getProperties() as $reflectionProperty) {
if($reflectionProperty->isPrivate()){
$methodName = 'get'.ucfirst($reflectionProperty->getName());
if ($reflectionClass->hasMethod($methodName)) {
$method = $reflectionClass->getMethod($methodName);
if($method->isPublic()){
$properties[$reflectionProperty->getName()] =
$reflectionProperty;
}
}
}
}
if($reflectionClass->getParentClass() !== false){
$properties = array_merge($properties, $this-
>allfields($reflectionClass->getParentClass()));
}

return $properties;
}

Using this change the class fields can be private and the private
fields inherit from a parent with a getter method can be used too.

Another think that I notice is the need of an easy update method given
an object without the need of loading first, I tweak repose a little
to do that an is working now but its a little ugly solution because of
the lack of a general picture yet (I'm relatively new to all). I don't
know if you are addressing this for the future version.

Another thing I start to port the core and most needed functionalities
of spring security to PHP, keeping the same philosophy and design (I
love Spring Security), and I have now a working version that still
lacks some implementations but can be addressed due to the native
extensible design approach of work based on interfaces, the
authentication an authorization system is working with an InMemory
implementation. the project name should be hole. and use substrate for
configuration. Let me see when I can create a project and upload to a
repository server.

Beau Simensen

unread,
Sep 14, 2010, 4:55:55 PM9/14/10
to repos...@googlegroups.com
Let me think about the all fields thing. It is unclear to me whether or not this would actually break the class being extended? I'll write up some tests. Otherwise, if it works, I'll see if I can roll this into 0.0.10!

As for the update-before-query issue, would you mind writing up some quick client pseudo code to show me what you have in mind? I'm envisioning something like:

  $myObject = new MyClass();
  $myObject->a = $a;
  $myObject->b = $b;
  $session->update($object, $primaryKeyValue);
  $session->flush();

I'd also be curious to know when you would use this? If you can provide some simple use cases I could better understand exactly what you are looking to do here.

It *might* be working already and you simply need to add the object... I haven't tried this, but it may work? If you are already working around this, maybe you could try that and let me know if it for sure works or not?

  $myObject = new MyClass();
  $myObject->primaryKey = $primaryKey;
  $myObject->a = $a;
  $myObject->b = $b;
  $session->add($myObject);
  $session->flush();



--

Beau D. Simensen


Dragonfly Development Inc
http://dflydev.com/

s3a - Fresh. Urban. Seattle.
http://s3attle.com/


[blog] http://not-invented-here.com/
[flickr] http://flickr.com/photos/kirkryyn
[facebook] http://facebook.com/simensen


aek

unread,
Sep 17, 2010, 4:02:19 PM9/17/10
to Repose PHP ORM General Discussion
I just want to merge the Object with the session without the need to
make a load and change the values one by one. something like the
example you show:

$myObject = new MyClass();
$myObject->a = $a;
$myObject->b = $b;

//the session has the primary key mapped and the value is in the
object if not throw an Exception
$myObject = $session->update($myObject);
//$myObject is now linked to the session just like the add method or
load method

$myObject->c = $c;

$session->flush();
then repose can make an select for update the changed properties in
$myObject or just an update for all properties in $myObject

Beau Simensen

unread,
Sep 17, 2010, 4:15:32 PM9/17/10
to repos...@googlegroups.com
Alright, I'll see what I can do!



--

Beau D. Simensen


Dragonfly Development Inc
http://dflydev.com/

s3a - Fresh. Urban. Seattle.
http://s3attle.com/


[blog] http://not-invented-here.com/
[flickr] http://flickr.com/photos/kirkryyn
[facebook] http://facebook.com/simensen



--
Reply all
Reply to author
Forward
0 new messages