SitePoint Sponsor

User Tag List

Page 2 of 13 FirstFirst 12345612 ... LastLast
Results 26 to 50 of 325
  1. #26
    SitePoint Addict
    Join Date
    Aug 2003
    Location
    Toronto
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    FWIW, I think that the template patterns are deceptively simple but in fact are rather complicated to generalize mainly because there are so many ways to approach them. Perhaps it might be more productive in terms of this thread to start with a smaller, more narrowly defined concept. For example, cache access, resources/libraries, parsers, etc.

    There seems also to be some issue in the thread about implementations following the interface (ie. needing to be re-written to the "standard"). This ought not be strictly so: emulation through adaptors should be sufficient.

  2. #27
    SitePoint Evangelist ghurtado's Avatar
    Join Date
    Sep 2003
    Location
    Wixom, Michigan
    Posts
    591
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I agree with you, jayboots. I think the idea of adaptors is a key one here. Maybe the best chance this has of becoming the standard it needs to be is by being more of a repository of adaptors rather than interfaces only. That way if someone wants to submit a class for "compliance" they wouldnt need to rewrite their interface (fat chance this would happen in the majority of cases), but rather simply just provide an adaptor that couples with the standard interface, and the same level of interoperability could be achieved.
    Garcia

  3. #28
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Travis S
    At which point we would also need to define what a datasource can be.
    Which start the process of getting input from everyone to work toward a standard.

    Quote Originally Posted by Travis S
    If that were to become an agreed upon standard, yes. Of course, I would write an adapter to make sure I didn't break any existing code, but I would start a migration.
    That is the most important thing. I think the people involved have to commit to moving to the standard if it is going to fly.

    Quote Originally Posted by Travis S
    My first Template code missed on key thing - that was just an idea. As we've demonstrated here, there are many different ways to do the same thing.
    And the standards can be a little fuzzy if necessary. Define what we agree upon and document the areas of disagreement. We can define standard adaptors as well.

    Quote Originally Posted by Travis S
    Maybe there are just too many ways to do things in PHP to come up with a set of standard interfaces...?
    Well, there are lots of ways to do things in PHP, luckily there are much fewer _good_ ways to do things. I think the variation will be much more manageable in this group. I would say take a look at WACT and Skeleton as resources. If you folow the spirit of those you (may) have selkirk, sweatje, kyberfabrikken, ezku, overrunner, dagfinn, et al. giving their support for the interfaces.

    If you can get that group (throw in lastcraft too) to agree on an interface I will start using it. In fact I would help work to reimplement the Skeleton using these "standard" interfaces as a test bed.

    So lead the process Travis, you said we need a DataSpace before we can define a Template. Start there and see how it goes. (sound of Champagne bottle crashing on Travis' bow .... splash!)
    Christopher

  4. #29
    SitePoint Addict
    Join Date
    Aug 2003
    Location
    Toronto
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ghurtado, I like your thinking. I wonder if it would be equally suitable to have a related secondary project that strictly dealt with adaptors. Adaptors can be rather tricky in their own right since they are so dependant on implementation. As such, I see them as having a lower "standardization" quotient (to make up new terms) than interfaces. Separating the two, the interfaces project could stay more on goal but would have some impetus to consider the needs of adaptor classes. At any-rate, I suspect that without adaptors for popular libraries, buy-in will be much harder to foster.

  5. #30
    SitePoint Evangelist ghurtado's Avatar
    Join Date
    Sep 2003
    Location
    Wixom, Michigan
    Posts
    591
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Maybe the standards project could provide two different "levels" of approval? One for compliant interfaces and another one for libraries with compliant adaptors. But at the same time, it wouldn't be a good idea to "downgrade" those that achieve compliance via adaptors instead of interfaces. I think they could be the majority anyway. So the first step is defining the interfaces anyway, and then it is the developers choice to provide interface compliance or adaptor compliance.

    If the whole adaptor idea takes off, I see a lot of potential for this project. May we want to start with some coding guidelines / best practices, perhaps?
    Garcia

  6. #31
    SitePoint Guru
    Join Date
    Nov 2002
    Posts
    841
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint
    So lead the process Travis, you said we need a DataSpace before we can define a Template.
    Now we're talkin! Standard template interfaces are such a dead end. However, there is tremendous potential benefit to a standard DataSpace/DataSource interface. Thats because DataSpace is really about property access and property definition is 90% of a component model. The other 90% is a standard event model. There would be real benefit to having a standard component model for PHP.

  7. #32
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Selkirk
    Now we're talkin! Standard template interfaces are such a dead end. However, there is tremendous potential benefit to a standard DataSpace/DataSource interface. Thats because DataSpace is really about property access and property definition is 90% of a component model. The other 90% is a standard event model. There would be real benefit to having a standard component model for PHP.
    Selkirk's interested, I'm interested, Travis?
    Christopher

  8. #33
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It's probably a good idea to accompany each interface with appropriate adapters to known (and popular) implementations. I have the feeling that this would by far exceed the interfaces themselves in size, but that's not bad. In fact it could result in a general integration/compatibility toolkit for all the disparate libraries around. That would definately be useful.

  9. #34
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Location
    Kansas City, MO
    Posts
    68
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm on board... I would say let's work with the type of data object you would see as part of a Data Mapper (i.e., a smart/settable Value Object).

    First thing, each object needs to have a means of saying what it contains. We could use the line that ItemForSale->getAmount() will always get that item's "amount" value, or it could be ItemForSale->get('amount'). The latter leads to easier swaping between objects because there's no need to tie to a specific method.

    With either, there needs to be a means of introspection so outside code knows what is available (I'm thinking particularly the Mapper part of DataMapper in this case). Something along the lines of getAvailableProperties() or getDeclaredProperties()?

    Of course, I do have to interject phpCR here again. It abstracts this out by having each node (dataobject, datasource, etc.) have a primary node type. The node type can contain any number of property and child-node definitions that define how things behave under it. I am currently working on a concrete implementation of this where the node type is the table name, and the property definitions are based on the table definition.


    As far as the recent discussion of adapters - that is something that would really be best left to the individual packages themselves. Say we come up with a Template interface and someone wanted to create a Smarty or Savant adapter to it, that would be great, but I think energy would initially be better spent working out the abstract interfaces instead of working out concrete adapters. Although maybe that could be used as a sort of "testing ground" - the interface should be abstract enough that it could be strapped onto any existing API without too much hassle until the code can be refractored to match the real interface.

    I think there should be an Adapter interface. I would leave it completely blank, just to serve as a means of identifying that you're dealing with an adapter instead of straight code.

    Quote Originally Posted by ghurtado
    May we want to start with some coding guidelines / best practices, perhaps?
    Well, since we're working with interfaces, there's no need to worry about all the control structure bracketing, indenting, and such. I would say keep everything in the code as concise as possible and remove duplication. phpDoc can figure out the name of a parameter, so there's no need to do "@param string $string Description", instead it can be - with the same end result in the generated docs - "@param string Description". Also, the @access and @static tags are obsolete in PHP 5 as phpDoc can figure it out by how you declare it.

    I would favor hard tabs to soft - even though PEAR does it the other way - simply from a storage perspective. "\t" is faster to load and smaller to storage than " ".

    What else am I leaving out?

  10. #35
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Travis S
    I'm on board... I would say let's work with the type of data object you would see as part of a Data Mapper (i.e., a smart/settable Value Object).
    Sounds like you might be a little ahead of where Selkirk and I were, and you've jumped over the basics.
    Christopher

  11. #36
    SitePoint Guru
    Join Date
    Nov 2002
    Posts
    841
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Game On!
    First thing, each object needs to have a means of saying what it contains. We could use the line that ItemForSale->getAmount() will always get that item's "amount" value, or it could be ItemForSale->get('amount'). The latter leads to easier swaping between objects because there's no need to tie to a specific method.
    I'm assuming we're talking PHP 5.0. Instead of requiring accessor methods for each property, why not start with the standard PHP property access mechanism?
    PHP Code:
    Interface DataSource {
        function 
    __get($property);
        function 
    __set($property$value);
        function 
    __isset($property);
        function 
    __unset($property);

    Let me defined a usecase that I think needs to be supported:

    PHP Code:
    class MyDatabaseConfiguration extends DataSourceSupport implements DataSource {
        public 
    $host 'localhost';
        public 
    $database 'myapp';
        public 
    $user 'jeff';
        public 
    $password 'secret';

    It should be possible to define a trivial data object such as this without having to declare accessor methods for each property. Thus, I will defer discussion accessor methods until a later post. Remember that the interface is about how others see the object, not about how its implemented internally. With the proper adapters, it should be possible to adapt almost any object to the DataSource interface.

    With either, there needs to be a means of introspection so outside code knows what is available (I'm thinking particularly the Mapper part of DataMapper in this case). Something along the lines of getAvailableProperties() or getDeclaredProperties()?
    Excellent. Lets have some meta data description classes. I think it will help make the discussion easier to follow:
    PHP Code:
    interface PropertyInfo {
        function 
    getName();
    }

    interface 
    DataSourceInfo {
        function 
    getClass();
        function 
    getPropertyInfo($property);

    Note that I'm not saying how one would get a DataSourceInfo instance. I'm not sure that adding a getAvailableProperties() or getDataSourceInfo() method to the DataSource interface is necessarily a good idea because of the extra dependency. (The JavaBeans spec avoids doings this.)

    Now, there are three kinds of properties: standard, read only and write only. So
    PHP Code:
    interface PropertyInfo {
        function 
    getName();
        function 
    isReadable();
        function 
    isWritable();

    Since a property might not be defined, an we need an exception:
    PHP Code:
    class PropertyNotFoundException extends Exception {} 
    Either __get or __set could raise this exception. Its not unusual for a __set style method in PHP to add a property that does not exist. I don't think its possible to pick only one behavior for __set (add if not found or exception if not found), so I would suggest adding the ability to find out which behavior one might expect:
    PHP Code:
    interface DataSourceInfo {
        function 
    getClass();
        function 
    getPropertyInfo($property);
        function 
    canAddProperties();

    __unset presents a problem. With some kinds of DataSources, it will not be possible to actually remove a property, instead one would probably set it to NULL. Thus, I think that __unset should do just that. Remove if it can, set to NULL if it can't. That means we need more meta-data to figure out which behavior to expect:
    PHP Code:
    interface DataSourceInfo {
        function 
    getClass();
        function 
    getPropertyInfo($property);
        function 
    canAddProperties();
        function 
    canRemoveProperties();

    or alternatively, we need an exception for __unset to raise:
    PHP Code:
    class CannotRemovePropertyException extends Exception {} 
    Since __isset should match the isset function and return FALSE if the property exists but has a value of NULL, we should probably have a hasProperty method on the DataSource interface. I would also put an addProperty() on, just to be more explicit. Lets throw on a removeAllProperties, a setMany, and an import, too:

    PHP Code:
    Interface DataSource {
        function 
    __get($property);
        function 
    __set($property$value);
        function 
    __isset($property);
        function 
    __unset($property);
        function 
    hasProperty($property);
        function 
    addProperty($property$value);
        function 
    removeAllProperties();
        function 
    setMany($propertyValueList);
        function 
    import($propertyValueList);

    setMany and import both take an array of the form array('property'=>'value'). The difference between setMany and import is that import does the equivalent of __unset on every pre-existing property that is not in the propertyValueList. In other words, import starts over from a blank slate.

    I would favor hard tabs to soft - even though PEAR does it the other way - simply from a storage perspective. "\t" is faster to load and smaller to storage than " ".
    At the risk of starting an bad tangental discusssion, Who cares about a few bytes these days? Spaces are the only technique that can preserve formatting regardless of the program displaying the text. (Think about things like cat blah.php on the command line and browsing source code via an html based CVS browser).


    (I don't use php 5 oo on an everyday basis please correct and forgive any transgressions I may make )

  12. #37
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Location
    Kansas City, MO
    Posts
    68
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint
    Sounds like you might be a little ahead of where Selkirk and I were, and you've jumped over the basics.
    Yeah, but only slightly I've just seen how the DataSpace object is used within the WACT framework and I think that's more what you were going for, right?

    When I look at that, I would make it one simplier - it's an aggregate/registry of Value Objects. Going back to the Node/Property paradigm, the DataSpace would be the node and the Value Objects would be the properties. To me, the node/property phrasing seems to work well probably because I've seen it so much.

    I've just given a quick glance at the WACT DataSpace code - it actually looks a lot like a Session in JCR - an aggregate of available items. Trying to back that out to the least common denominator, I see the Value Object/Property. It needs to be able to hold any type of native of PHP variable.

    PHP Code:
    // just some ideas...
    interface ValueObject {
        public function 
    getName();
        public function 
    getValue();
        public function 
    getType();
    }

    interface 
    MutableValueObject extends ValueObject {
        public function 
    setValue($value);
    }

    // Decorators
    interface MorphingValueObject {
        
    // Original decorated
        
    public function getName();
        public function 
    getValue();
        public function 
    getType();

        
    // base types - where conversion is possible (getType() != array || object)
        
    public function getString();
        public function 
    getInteger();
        public function 
    getFloat();
        public function 
    getBoolean();

        
    // special cases - these throw exceptions except on getType() == array || object
        
    public function getObject();
        public function 
    getArray();
    }

    interface 
    MagicValueObject {
        public function 
    getName();
        public function 
    getValue();
        public function 
    getType();

        public function 
    __get($key);
        
    // no action is taken unless decorating a MutableValueObject
        
    public function __set($key$value);

    As I previewed this, I see that Selkirk has replied, so I'm going reply to a few specifics he's brought up...

    Quick note... All Exceptions should extend from RuntimeException which is being introduced in PHP 5.1. Until then, you can do a check to see if it exists and define it as a straight extends Exception. RuntimeException doesn't add anything to Exception, just helps denote that it happened during the course of excution.


    Jumping to the final interface:
    PHP Code:
     Interface DataSource {
        function 
    __get($property);
        function 
    __set($property$value);
        function 
    __isset($property);
        function 
    __unset($property);
        function 
    hasProperty($property);
        function 
    addProperty($property$value);
        function 
    removeAllProperties();
        function 
    setMany($propertyValueList);
        function 
    import($propertyValueList);

    setMany()/import() seem too similar in name and I'm afraid would end up being mixed up. I would remove setMany() and give its role to import(). import() also needs a means of handling naming collisions:

    PHP Code:
    function import($propertyValueList[, $onCollisionAction]);

    class 
    Action
    {
        const 
    OVERWRITE;
        const 
    IGNORE;
        const 
    MERGE;
        const 
    EXCEPTION;
        
    // more?

    Also, I would abstract the property into the ValueObject I mentioned above. That makes DataSource a container of Properties/ValueObjects and simplifies DataSource's API.

    PHP Code:
    interface DataSource
    {
        public function 
    getProperty($propertyName); 
        public function 
    setProperty(Property $property);
        public function 
    hasProperty($propertyName);
        public function 
    hasProperties();  // i.e. isEmpty()
    }

    interface 
    MagicDataSource extends DataSource
    {
        
    // $key included for PHP internal use, but should almost always == $value->getName()
        
    public function __set($keyProperty $value);
        public function 
    __get($propertyName);
    }


    interface 
    DataSourceFactory {
        
    /**
         * @returns DataSource
         */
        
    public function import($values);

    The next logical step from here is storage and retrieval at which point we're becoming dangerously close to re-inventing phpCR

    For the the sake of those who haven't looked at it and don't know anything about it. Here's the quick tour. phpCR is a repository made up of items. All of the items are broken down into two sub-types, nodes (or branches) and properties (or leaves). Using this forum as an example, the node is this post, while my name as poster, the time I post, the content I post, etc., are the properties that belong to it. Beyond that, there's the relation between the nodes, mechanisms for saving, etc., but that's the basics.

    Again, for the benefit of people who haven't seen it, here's a copy of the interfaces with all the docblocks stripped.

    PHP Code:
    interface Item
    {
        public function 
    getPath();
        public function 
    getName();
        public function 
    getAncestor($degree);
        public function 
    getParent();
        public function 
    getDepth();
        
        
    // Session refers to the container
        
    public function getSession();
        public function 
    isNode();
        public function 
    isNew();
        public function 
    isModified();
        public function 
    isSame(Item $otherItem);
        public function 
    accept(ItemVisitor $visitor);
        public function 
    save();
        public function 
    refresh($keepChanges);
        public function 
    remove();
    }

    interface 
    Node extends Item
    {
        public function 
    addNode($relPath$primaryNodeTypeName null);
        
        
    // This is a method I'd happily drop - I haven't found a good use for it yet
        
    public function orderBefore($srcChildRelPath$destChildRelPath);
        
        public function 
    setProperty($name$value$type null);
        public function 
    getNode($relPath);
        public function 
    getNodes($namePattern null);
        public function 
    getProperty($relPath);
        public function 
    getProperties($namePattern null);
        public function 
    getPrimaryItem();
        public function 
    getUUID();
        public function 
    getIndex();
        public function 
    getReferences();
        public function 
    hasNode($relPath);
        public function 
    hasProperty($relPath);
        public function 
    hasNodes();
        public function 
    hasProperties();
        
        
    // mixin = additional node type definitions to add restrictions, behavior
        // PrimaryNodeTypes specify concrete behavior.  Example: the presence of
        // mix:versionable means this node can be versioned, while nt:file means
        // this node represents a file.  (both pulled from JCR spec, but neither
        // required).
        
    public function getPrimaryNodeType();
        public function 
    getMixinNodeTypes();
        public function 
    isNodeType($nodeTypeName);
        public function 
    addMixin($mixinName);
        public function 
    removeMixin($mixinName);
        public function 
    canAddMixin($mixinName);
        public function 
    getDefinition();
        
        
    // Optional Level 2 functionality
        
    public function checkin();
        public function 
    checkout();
        public function 
    doneMerge(Version $version);
        public function 
    cancelMerge(Version $version);
        public function 
    update($scrWorkspaceName);
        public function 
    merge($srcWorkspace$bestEffort);    
        public function 
    getCorrespondingNodePath($workspaceName);
        public function 
    isCheckedOut();
        public function 
    restore($versionName$removeExisting$relPath '');
        public function 
    restoreByLabel($versionLabel$removeExisting);
        public function 
    getVersionHistory();
        public function 
    getBaseVersion();
        public function 
    lock($isDeep$isSessionScoped);
        public function 
    getLock();
        public function 
    unlock();
        public function 
    holdsLock();
        public function 
    isLocked();
    }


    // Several of these are only in here because they existed in the original
    // Java source.  I would say we could drop getLong()/Double/Stream/Date
    // without much hassle.  I would like to see getDate() brought back though
    // if PHP ever has a native Date object.
    interface Property extends Item 
    {
        public function 
    setValue($value);
        public function 
    getValue();
        public function 
    getValues();
        public function 
    getString();
        public function 
    getFloat();
        public function 
    getDouble();
        public function 
    getStream();
        public function 
    getDate();
        public function 
    getBoolean();
        public function 
    getInt();
        public function 
    getLong();
        public function 
    getLength();
        public function 
    getDefinition();
        public function 
    getType();

    Feel free to slash away - what's in there that doesn't need to be (when viewed from a storage perspective)?

  13. #38
    SitePoint Guru
    Join Date
    Nov 2002
    Posts
    841
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Travis S
    I've just given a quick glance at the WACT DataSpace code
    Make sure you look at the CVS version and not the one included in the downloadable 0.2 release.

    Also, I would abstract the property into the ValueObject I mentioned above. That makes DataSource a container of Properties/ValueObjects and simplifies DataSource's API.
    I think wrapper objects for individual property values is too much. I can also tell you from experience that the performance of the get and set operations matters. Consider the amount of work that would have to be done to map the output of a function like mysql_fetch_assoc to individual value objects for every field.


    setMany()/import() seem too similar in name and I'm afraid would end up being mixed up. I would remove setMany() and give its role to import(). import() also needs a means of handling naming collisions:

    PHP Code:
    function import($propertyValueList[, $onCollisionAction]);

    class 
    Action
    {
        const 
    OVERWRITE;
        const 
    IGNORE;
        const 
    MERGE;
        const 
    EXCEPTION;
        
    // more?

    I've never been entirely happy with the import and setMany names.

    I also prefer not to use constant parameters. When I see this, I usually refactor to

    importOVERWRITE()
    importIGNORE()
    importMERGE()
    importEXCEPTION()

    and then start to try to think of better names. Which would probably put us back at import and setMany.

    I can also tell you from experience that some implementations will want to override setMany with a different implementation and some will want to override import with a different implementation. Having the constant parameter makes this more complicated because the subclasses also have to have a case statement for the constant. I usually try to avoid case statements based on constants in OO code. I have an old post describing my attitude on this issue that actually nearly uses this very example.

    Regarding collisions, i don't see them. SetMany is conceptually equivalent to a series of __set calls.
    PHP Code:
    $ds->setMany(array('A'=>1'B'=>2));
    // Same as
    $ds->__set('A'1);
    $ds->__set('B'2);
    // Same as
    $ds->1;
    $ds->2
    or do you mean what happens when you pass it something like array('A'=>1, 'A'=>2)?

    In which case I would be included to say the last value wins.

    Conceptually, import is equivalent to, um, well, thats hard to explain exactly and thats a problem.

    Personally, these are both just convenience methods. I just did a grep of my own WACT based code and I don't use either methods in any current code. There may be some WACT users with a different style of coding, however, that do rely on these methods.

    I'll withdraw the setMany and import methods as unnecessary.

  14. #39
    SitePoint Enthusiast
    Join Date
    Mar 2005
    Posts
    53
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hello everyone,

    As always, I'm following another great thread with much enthusiasm (a nod to the people from the application controller thread and the skeleton thread). As of late, I've assumed command of creative direction in the Mojavi PHP Framework. Prior to being given control of direction, I was designing, for a number of weeks, a branch of Mojavi 3.0.0-DEV, whose UML diagrams can be found on the mojavi forum. Information on this branch can also be found on the forum at this thread.

    However, my pupose for posting here is not to introduce any of you to Mojavi, but rather to introduce the diagrams. For a long while now, I've wanted to create, in some manner or another, a series of interfaces/concrete classes which would be designed well enough (through either dependency injection, or another less un-intrusive technique) to competely unplug from the framework and share with other projects. However, this sort of vision usually falls short of any sort of realization due to the many very palpable problems and mistakes taken in this direction in the past (namely PEAR ).

    What I would like to suggest is that this group take a look at my designs, give feedback, and I will do likewise. I would like to, if possible, stay away from Controller layer constructs simply because of their very MVC-ish nature (if someone has reason to present Controller-layer interface suggestions I would certainly be open to it).

    Now, off the topic of the diagrams, and for some feedback for you guys:

    The datasource implementation through a node/container pattern seems much cleaner to me. Since the datasource is already being abstracted, why not go a bit further to:

    PHP Code:
    $obj->getAttrContainer()->get('val'); 
    It also seems that an extensive use of exceptions as an error-system vastly outweights any sort of error-code scheme, as one always will run into particular problems with handling error codes in developer-level implementation code. Thoughts?


    One last thing just for references:

    Renderer => Template
    Container et al. => Dataspace

    I look forward to your responses,

    Regards,

    Tyler

  15. #40
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Location
    Kansas City, MO
    Posts
    68
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Selkirk
    Make sure you look at the CVS version and not the one included in the downloadable 0.2 release.
    Will checkout that version and base my assumptions from it...

    Completely off-topic - when will SF ever get around to implementing SVN? I'm tired of having to look up CVS commands


    Quote Originally Posted by Selkirk
    I think wrapper objects for individual property values is too much. I can also tell you from experience that the performance of the get and set operations matters. Consider the amount of work that would have to be done to map the output of a function like mysql_fetch_assoc to individual value objects for every field.
    Has anyone ever done a benchmark of this? Code-wise, it's no different to do $string = "value" than $string = new Value("value"). I'm not wedded to the idea, but I can see its usefulness.

    This is actually an area where the Node/Property relation in phpCR needs some investigation. I'm working out from an implementation standpoint whether it should be on par with a Node as an entry in an Items table and just attach some sort of storage to it for its value (i.e. Item's existance is in Items table but its actual string value is in StringProperties), or whether it should exist virtually as a column in a table, or...?



    Quote Originally Posted by Selkirk
    Regarding collisions, i don't see them. SetMany is conceptually equivalent to a series of __set calls.
    ...snip...
    or do you mean what happens when you pass it something like array('A'=>1, 'A'=>2)?
    Yes - when the same value is set again. Perhaps there needs to be a set-once mutable with the last value wins as the default?

    Quote Originally Posted by Selkirk
    Personally, these are both just convenience methods. I just did a grep of my own WACT based code and I don't use either methods in any current code. There may be some WACT users with a different style of coding, however, that do rely on these methods.

    I'll withdraw the setMany and import methods as unnecessary.
    I think they're both good - but they're both really Factory type methods. ValueObjectFactory::import() makes much more sense to setup a ValueObject and setMany can easily be achieved with a foreach().


    Alright! We've got our another framework guy pitching in... This is the direction I wanted to go in... getting everyone (well, at least a good sized portion of "everyone") on board and coming up with some standards that everybody can live with.

    First off, I like the UML - nice work. I actually should put something together like that for phpCR. I think if people saw it diagrammed they wouldn't flinch as much as looking at the code, API docs, or 200+ spec sheet from the Java version.

    Second - the exceptions. I agree. I did some testing on assert() versus using home grown methods a fews weeks back (the full article is here). The results when comparing a simple my_assert() that did an if(!$value) { trigger_error() } floored me. Definitely, whenever we can I would say use built in features...

    Now, to come back to your actual code ideas. phpCR uses the overall container of "Session" - a name I don't like because of the class with the concept of "sessions" in PHP, but used as I wanted to do a straight port to start with. From the Session, you can grab any number of nodes - or containers of properties in this context. In an ideal world, such an interface could serve as the basis for a Model which could then be interchanged between Mojavi, WACT, Solar, or any other system. If all three were implementing the same content repository/model API, you could then take your data from any system and drop it into the controller/view of another system.

    I guess this really depends on one thing though. Do we want the Datasource/Container to be able represent data in the database and serve as a crude model, or are we after a fancy array?

    Tomorrow in the morning I'll work up some basic UML diagrams of the core functionality inside phpCR and strip out all the extras. As I posted the full interfaces earlier, I realized there was actually a lot of room for decorator use there and I'm not sure why it wasn't used in the Java version. It could give you an instance clue as to whether your Node is lockable if your Session->getItem() returns LockableNode and its much more intuitive than having lock() throw an unsupported repository exception.

    Anyway... manana...
    -T

  16. #41
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Location
    Kansas City, MO
    Posts
    68
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myself...
    Anyway... manana
    Ok, so I lied...

    Here you go...



    A lot of the parameter naming would probably make sense to revisit - this is just the way it is right now. Session in particular has been cut way down, and I've pulled a lot of the superficial out of Node.

  17. #42
    SitePoint Addict
    Join Date
    May 2005
    Posts
    255
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ghurtado
    This seems like a very good idea in principle. As kyber points out though, it might be just as hard to get the developers to agree on a particular interface as it is to get them to agree on an implementation. After all, the interface already defines a lot of things, like a coding style, a design roadmap and some other specifics that the implementation would have to follow.

    Nevertheless, I would be glad to design a logo and a visual template for the website if this takes off; for now this is probably the perfect place to start to put forth ideas and consider the finer points.

    Absolutely. Almost any PHP developer of a certain caliber has been longing for this for quite a while now. PEAR was supposed to fill that gap, but it failed miserably, and quite honestly I don't hold much of a hope for it to change directions in the near future.


    IMHO, this has the potential of becoming a big hurdle as well. There are two mainstream movements in "Advanced PHP" nowadays. The one seems to be looking up to Java as its older brother, and thinking "that's what I want to be when I grow up". The other wants PHP to evolve in it's own right, taking advantage of what it does best and designing its own custom idioms that will advance the language as an independent entity. Neither group is 100% right, and both are probably neccesary to keep the language balanced, but I tend to caution against the dangers of mimicking Java too much without considering alternative approaches that may work much better in PHP. To provide an extreme example as an illustration (I am sure you have run accross this in the past), some PHP developers out there are creating classes for "String", "Array" and "Hashmap". I stand clear of that path, and I am sure you do too.

    I actually saw code a few weeks ago with this implementation (replaced the prefix with "x" so as to not identify the guilty party).

    PHP Code:
    class xString{

         function 
    __toString() 
         {
             ... 
         }

    Just think about that one for a minute. I never quite understood the logic of developing this way; if you want to program with Java...just program with Java. PHP has some very unique strengths, as it borrows from both perl's powerful string manipulation and C/C++/Java's facilities for application development (borring OO features from C++ & Java, and low-level functions from C). This is why it's such a popular, powerful language -- it truly offers you flexibility that few languages can claim to be able to truly deliver.

  18. #43
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A thread with Selkirk and illusina tentatively discussing a common set of interfaces on which to build PHP frameworks? Has the world gone mad!

    From looking a code and diagrams there appears to be a lot of common ground here. I like that Selkirk is already ditching crufty methods. Go, go, go.
    Christopher

  19. #44
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Travis S
    Has anyone ever done a benchmark of this? Code-wise, it's no different to do $string = "value" than $string = new Value("value").
    It does show up high when profiling with xdebug, but it may be simply making something visible, which was there already. Anyway - I would be willing to sacrifice a few clockcycles in return for the added flexibility in this case.

    I haven't consumed all of thoose lengthy posts just yet, but I have one though about the interface of DataSource/DataSpace/Node/ValueObject. The implementations discussed so far, imply a flat collection of properties (like properties of an object). A basic ArrayDataSpace would map theese to keys in an underlying array. What happens when this array is a jagged array - Eg. one of the properties is an array ? Should the DataSpace then return the array, or should it return a new ArrayDataSpace wrapper around it ? Also - how intelligent should such a DataSpace be ? Should it be possible to select with an xpath-like query, into a subnode ? Perhaps we should operate with two interfaces - a base IDataSpace and an extended IHierarichalDataSpace ?

  20. #45
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, interesting discussion and I'm looking forwards to reading more, so please continue

    Should the DataSpace then return the array, or should it return a new ArrayDataSpace wrapper around it ?
    I think it should return the array as is. If you let the data source/data space object wrap it's self on top of the array, what happens when that new data source/data space object created finds that it it's self, has an array? ...

    In that regards, shouldn't the client script make the choice in how to handle or manage the array. Giving the data source/data space the role of returning a new data source/data space object is not part and parcel of the responsibilities, from my perspective that is.

  21. #46
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK. I had this idea cooking in my cranium since yesterday. Sorry if it's diverting the current topic of formulating a common DataSpace interface.

    A short explanation :
    As arborint nicely demonstrated, and most of us realize, defining a common interface between two analog (at least to some degree) implementations is only part of the problem. The real challenge is how to get the implementations to actually conform to the interface. The answer is ofcourse to provide wrappers, which made me think about a framework for doing this.

    The basic structure is somewhat inspired by the interface of XPCOM - class/method naming is mostly random. For one thing, I don't know if ComponentLocator is very descriptive.

    Without further ado.
    Attached Files Attached Files

  22. #47
    SitePoint Wizard
    Join Date
    Jan 2004
    Location
    3rd rock from the sun
    Posts
    1,005
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I also think a big reason it won't work is that the vast majority of PHP programmers, didn't start as programmers, and aren't really interested in standards, just "making it work".
    OK, we start off like that - then after years of repetition we say "theres gotta be a better way... I gotta think like a programmer, not a scripter" and we start looking for solutions, read books, join forums - and search for the equivalent of phpclasses.org or script libraries - because thats how we learned in the past - re-using and looking at other peoples code. PHP is just so good for that.

    The value of standards is very, very high on the priorities of anyone who has done anything on the web over the last 5 years... tag wars et al, if(document.layers)... remember all that crap?

    Possibly because of PHP's lower barrier to entry...?
    Correct again. One of the strengths of design patterns (as I understand it) is that it creates a "shared vocabulary" - which is fine if you understand the "the OO language" .

    Who is this library aimed at, define the target audience and what they will ideally want from it. If that doesn't include "scripters learning to be programmers" then you can easily forget about lower barriers to entry.
    To build upon Travis S's point
    Determine the scope..
    Determining the audience too may help focus on the job of defining the purpose.

  23. #48
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Location
    Kansas City, MO
    Posts
    68
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    Also - how intelligent should such a DataSpace be ? Should it be possible to select with an xpath-like query, into a subnode ? Perhaps we should operate with two interfaces - a base IDataSpace and an extended IHierarichalDataSpace ?
    Well it just so happens that phpcr provides for this in interfaces I didn't document in the UML or interfaces above (remember, I'm trying to simplify right now). The bigger question is - do you want Node/Properties to be aware of their surroundings (i.e. are they stored? do they know that? do they know they're related to other data?). Assuming that at some level of implementation the answer to those questions are generally yes, then something like the following happens:
    PHP Code:
    $qm $node->getSession()->getWorkspace()->getQueryManager();
    $query $qm->createQuery('/path/to/node''xpath');
    $result $query->execute(); 
    A question explanation - the Session is your user's current view of the repository within his given Workspace. Things that happen in the Session aren't persisted immediately, things that happen in the Workspace are.


    Quote Originally Posted by Dr Livingston
    I think it should return the array as is. If you let the data source/data space object wrap it's self on top of the array, what happens when that new data source/data space object created finds that it it's self, has an array? ...

    In that regards, shouldn't the client script make the choice in how to handle or manage the array. Giving the data source/data space the role of returning a new data source/data space object is not part and parcel of the responsibilities, from my perspective that is.
    One way to handle this through property definitions. Can the property have same-named siblings? If it can, then it should be able to handle the following:
    PHP Code:
    $property $node->setProperty('array', array(123));
    $array $property->getValues(); 
    If it can't, it throws an exception - it just needs to be documented that both are possible behaviors.


    One thing I'm curious about - what is everybody else's thought on the Property interface in the context of the diagram above? Is it redundant? The one benefit I see with it is the ability to transform a value that's pulled out of storage into something more usable, but seeing as how PHP is loosely-typed, maybe that kind of cleverness is best left up to the final implementors?


    Quote Originally Posted by paulyg
    Who is this library aimed at, define the target audience and what they will ideally want from it. If that doesn't include "scripters learning to be programmers" then you can easily forget about lower barriers to entry.
    To build upon Travis S's point
    Quote:
    Determine the scope..
    Determining the audience too may help focus on the job of defining the purpose.
    You are correct. Personally, I believe it should be targetted at anyone who is tired of recreating the wheel. However, I think a lot of what ends up being done is going to be over the head of the causal PHP "hacker" (i.e., downloads WP/Mambo and changes a config file and they're a hacker).

    All that said, if we can build the simplest solution and slowly add layers to it through decoration and/or inheritence, then maybe the casual scripter can start at the simplest level and implement more and more as they become more proficient.

  24. #49
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    the Session is your user's current view of the repository within his given Workspace.
    This is an interesting approach this, but what I'm asking is that does the user in question only have the one workspace, or is it possible for them to have more than one?

    If they could have one or more, then wouldn't this allow for increased flexibility for the actual application developer (not the framework developer), where the user is doing one task, and then off they go, and do another different task altogether at the drop of the hat, and to come back later to the original task.

    I'm asking, as I don't know if you at the moment allow for more than the one workspace you see.

  25. #50
    SitePoint Enthusiast
    Join Date
    Oct 2004
    Location
    Kansas City, MO
    Posts
    68
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    This is an interesting approach this, but what I'm asking is that does the user in question only have the one workspace, or is it possible for them to have more than one?
    The implementor can include one or more workspaces. It's actually a concept more than anything to help divide the role between temporal (Session) and eternal (Workspace) - or in less celestial terms, changes that might or might not be persisted and ones that are persisted immediately.

    As far as how many a user can get - theoritically, a user could go back to Repository and ask for any number of workspaces using the same credentials (unless you implement some sort of expiration on the Credentials). That said, I'm not sure I see how multiple would be useful, unless of course you're loading all of the values into _SESSION and not closing them until the user executes a save.

    As far as conceptual view of what the Workspace is - I've always viewed it as a view of the repository. That might not be correct in terms of JCR, but that's how I've viewed it. That, and any actions it takes are always followed by save() internally


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •