SitePoint Sponsor

User Tag List

Page 3 of 5 FirstFirst 12345 LastLast
Results 51 to 75 of 116
  1. #51
    SitePoint Addict silent's Avatar
    Join Date
    Jun 2004
    Location
    Roaming North America
    Posts
    220
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Check out phpGACL on SourceForge.

  2. #52
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks. Will give it a go!

  3. #53
    If it aint Dutch it aint much Kilroy's Avatar
    Join Date
    Oct 2003
    Location
    The Netherlands
    Posts
    406
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    My first impression when reading this:

    PHP Code:
    function getProgressReportDeleteLinksFromTaskId$tId )
       { 
       } 
    was WHAT THE F UCK?

    No, really, you should seperate that!

  4. #54
    SitePoint Member
    Join Date
    Sep 2003
    Location
    WA
    Posts
    7
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry for the delayed response. Lots of family this weekend.

    Hm, tricky...how is it working out?
    Working out very nicely actually. The final test will be in 1-2 years when the game is actually released. Then we can step back from the project and reevalute with a better perspective.

    Presumeably to be used alongside IM solutions as well.
    Yeppers

    To give this thread some kind of closure I'll take a punt at your requirements (only fair) and you can point out possible difficulties.
    I think you have nailed it on the head there. Your right, it is more vuage, but also at the the same time gives Tim the freedom to approach it any way he desires. Which is cool, because ultimately the rest of the team is just interested in the final product.

    Thanks again for your help guys, Tim will have to give you a test drive when he gets it all coded. We'll have to look into some of those pre-built solutions too.

  5. #55
    SitePoint Enthusiast escape164's Avatar
    Join Date
    Dec 2002
    Location
    Colorado, USA
    Posts
    79
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Not sure this will help, but TasksPro written by Alex King is the best Task Management software I've found. It might help you nail your requirements a big.

    http://www.taskspro.com (commercial)
    http://www.alexking.org/index.php?co...ent.php&show=1 (free version)

    Mike

  6. #56
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Wijitmaker
    Thanks again for your help guys, Tim will have to give you a test drive when he gets it all coded. We'll have to look into some of those pre-built solutions too.
    Actually you should be releasing often, so a test drive should be possible quite quickly, right ?

    BTW there is another spec. guide here for projects whose users are external to an organisation...
    http://joelonsoftware.com/articles/fog0000000035.html
    ...which act as a nice counterbalance to an in-house purely iterative approach.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  7. #57
    SitePoint Enthusiast
    Join Date
    Jun 2004
    Location
    Stillwater, MN
    Posts
    96
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    Hi...



    Something like...
    PHP Code:
    $finder = &new TaskFinder();
    $task = &$finder->findByName($current_task);

    $department = &$task->getOwningDepartment();
    $people = &$department->getMembers();

    $quick_list = &new QuickJumpList();
    while (
    $person = &$people->next()) {
        
    $quick_list->addLink(
                
    $person->getName(),
                
    'task_list.php?name=' $person->getName());
    }
    print 
    $quick_list->paint(); 
    Now it looks like...
    PHP Code:
    class TaskFinder {
        function &
    findByProjectName($project_name) { }
        function &
    findByName($name) { }
    }

    class 
    TaskIterator {
        function 
    TaskIterator($database_result) { }
        function &
    next() { }
    }

    class 
    Task {
        function 
    Task($row) { }
        function 
    getName() { }
        function &
    getOwningDepartment() { }
    }

    class 
    Department {
        function 
    Department($row) { }
        function &
    getMembers() { }
    }

    class 
    PersonIterator {
        function 
    PersonIterator($database_result) { }
        function &
    next() { }
    }

    class 
    Person {
        function 
    Person($row) { }
        function 
    getName() { }
    }

    class 
    QuickJumpList {
        function 
    addLink($label$url) { }
        function 
    paint() { }

    I am starting to see commonality already. The two iterators differ only in class name and their construction is hidden from the public code. These two can be merged into...
    PHP Code:
    class DataAccessorIterator {
        function 
    DataAccessorIterator($database_result$class) { }
        function &
    next() { }

    Another?

    yours, Marcus
    When you combine the two, how would it know which class to return (a Task or a Person?)

  8. #58
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    a Task or a Person?
    Would imagine that Composition has something to do with this no ? Would like to see an example myself though

  9. #59
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Radley
    When you combine the two, how would it know which class to return (a Task or a Person?)
    It takes the class name in the constructor. Assuming all of the persistent objects have the same constructor signature, all is well.

    We have recently been rethinking persistence libraries in PHP. Most examples are Java based, which is based on the objects being available in memory between each request. This affects the approach and language at a fundamental level that permeates all of the systems I have seen so far. Even the word "persistence" belies that approach. Keeping this illusion of persistent objects is difficultin PHP when everything has to be constantly torn down and rebuilt on each page.

    The rethink has produced a radical change in perspective and a much cleaner design. It's possible that every piece of advice I have ever given on this subject up to now has been wrong .

    Anyway, I need to refactor our current system over to this new approach and test it before I publicise it futher.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  10. #60
    SitePoint Addict
    Join Date
    May 2003
    Location
    Calgary, Alberta, Canada
    Posts
    275
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    We have recently been rethinking persistence libraries in PHP. Most examples are Java based, which is based on the objects being available in memory between each request. This affects the approach and language at a fundamental level that permeates all of the systems I have seen so far. Even the word "persistence" belies that approach. Keeping this illusion of persistent objects is difficultin PHP when everything has to be constantly torn down and rebuilt on each page.
    What do you mean by persistence libraries? Do you mean that you are keeping objects available in memory between requests in php or that by using a mapper you are keeping the illusion of persistent objects? Would love to see a high level example if you are keeping objects between requests.

    Very interested in your thoughts on this when you get it all refactored.

  11. #61
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by Brenden Vickery
    Do you mean that you are keeping objects available in memory between requests in php or that by using a mapper you are keeping the illusion of persistent objects?
    Keeping an illusion.

    Quote Originally Posted by Brenden Vickery
    Would love to see a high level example if you are keeping objects between requests.
    Here is roughly what it looks like now...
    PHP Code:
    $broker = &new PersistenceBroker('Programmer');
    $broker->addCondition("type = 'Web'");
    $programmers = &$broker->find();

    $count_languages = array();
    while (
    $programmer = &$programmers->next()) {
        
    $languages = &$programmer->getLanguageSkills();
        while (
    $language = &$languages->next()) {
            @
    $count_languages[$language->getName()]++;
        }

    That would be from three mapped tables: Programmers, LanguageSkills (link table), Languages (has the name). Code generation and other sneakeness maps it to the object model above including the collection (one to many) and the join (many to one).

    If you make any edits then the appropriate objects have to be committed out. That is easy enough. If you want transactions and you have multiple things going on at once, things get conceptually messy.

    I'll post more later. I have a post card that has a big 6 on it. The six refers to the estimated six days work it should take me to refactor to the new scheme. We really are eternal optimists...

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  12. #62
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    I'll post more later. I have a post card that has a big 6 on it. The six refers to the estimated six days work it should take me to refactor to the new scheme. We really are eternal optimists...
    Lets see 6 FTU / .3 realism factor = 20 Days, right on schedule
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  13. #63
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by sweatje
    Lets see 6 FTU / .3 realism factor = 20 Days, right on schedule
    Actually yeah, although two days (estimated) are already done . We have switched to three week iterations and we can divide by .4 these days (giving ten real). Used to be a velocity of three estimated days per fortnight per pair. I am doing this one at home alone though, and so we have scheduled three weeks to go.

    Give or take...

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  14. #64
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey Marcus, one question arose now while refactoring some of this. What I now have is this:

    PHP Code:
    <?php

    require_once( dirname(__FILE__)."/conf_global.php" );
    require_once( 
    dirname(__FILE__)."/sources/includes/database.php" );

    $DB = &new Cdatabase$INFO['sqlHost'], $INFO['sqlUser'], $INFO['sqlPass'], $INFO['sqlDBName'] );

    $finder = &new taskFinder();
    $task = &$finder->findByName($current_task);

    $department = &$task->getOwningDepartment();
    $people = &$department->getMembers();

    $quick_list = &new quickJumpList();
    while (
    $person = &$people->next()) {
        
    $quick_list->addLink$person->getName(), 'task_list.php?name='.$person->getName());
    }
    print 
    $quick_list->paint(); 


    class 
    taskFinder {
        function 
    taskFinder() {}
       function &
    findByProjectName($project_name) { }
       function &
    findByName($name) { }
    }

    class 
    taskIterator {
       function 
    TaskIterator($database_result) { }
       function &
    next() { }
    }

    class 
    task {
        function 
    Task($row) { }
       function 
    getName() { }
       function &
    getOwningDepartment() { }
    }

    class 
    department {
       function 
    Department($row) { }
       function &
    getMembers() { }
    }

    class 
    personIterator {
       function 
    PersonIterator($database_result) { }
       function &
    next() { }
    }

    class 
    person {
       function 
    Person($row) { }
       function 
    getName() { }
    }

    class 
    quickJumpList {
       function 
    addLink($label$url) { }
       function 
    paint() { }

        
    ?>
    Now finding a task in taskFinder, how'd you do that? Would the db call/xml file call/whatever be there? Should all tasks from the db/xml file/whatever be stored somewhere in the constructor? Speed issues?

  15. #65
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by DarkAngelBGE
    Now finding a task in taskFinder, how'd you do that?
    PHP Code:
    class TaskFinder {
        ...
        function &
    findByName($name) {
            
    $sql "select * from tasks where name='$name'";
            
    $connection = &$this->getConnection();
            
    $iterator = &$connection->query($sql);
            if (! 
    $iterator) {
                return 
    false;
            }
            return new 
    Task($iterator->next());
        }

    Quote Originally Posted by DarkAngelBGE
    Would the db call/xml file call/whatever be there?
    It can be quite happily and this is simplest at first. I have used a connection object here and you might consider using an object to wrap the SQL query as well. See what works and try it both ways.

    Quote Originally Posted by DarkAngelBGE
    Should all tasks from the db/xml file/whatever be stored somewhere in the constructor?
    If you are getting a group of rows then pass the result ID from the query into an iterator. That way you pull the results from the database only as you need them.

    Quote Originally Posted by DarkAngelBGE
    Speed issues?
    The only real issue is that sometimes mapping from relational data to objects can drive you into sub optimal queries against the database. Wait until you have a problem and then tackle it.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  16. #66
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So you would always have the DB calls in the task finder instead of having some external queryBuild object that would complicate things (now we have that database layer discussion again).

    What if I want to list my tasks and then list Joe's tasks underneath? I'd need to call the taskFinder:findByName twice, but with the same query, only different nameId/name supplied. I could handle that in one query and break the results up. That's what I mean by performance, err, speed issues.

  17. #67
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Marcus,

    If you are getting a group of rows then pass the result ID from the query into an iterator. That way you pull the results from the database only as you need them.
    Not sure I follow ? What I do is to create an iterator with a resultset, so are you proposing that instead of using the resultset, use the actual database resource it's self ?

    If so, do you have an example as I can't recall seeing an example of this before

    Thanks.

  18. #68
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How does this look to you Marcus? Obviously I would need a ton of queries if I want to store the people of the owning departments of 20 tasks. That would crash every server...

    PHP Code:
    <?php

    require_once( dirname(__FILE__)."/conf_global.php" );
    require_once( 
    dirname(__FILE__)."/sources/includes/database.php" );

    $DB = &new Cdatabase$INFO['sqlHost'], $INFO['sqlUser'], $INFO['sqlPass'], $INFO['sqlDBName'] );

    $finder = &new taskFinder();
    $task = &$finder->findByName($current_task);

    $department = &$task->getOwningDepartment();
    $people = &$department->getMembers();

    class 
    taskFinder {
        function 
    taskFinder() {}
       function &
    findByProjectName($project_name) { }

       function &
    findByName($name) {
           
    $sql "select title, member_id, department_id from tasks where name='$name'";
          
    $connection = &$this->getConnection();
          
    $iterator = &$connection->query($sql);
          if (! 
    $iterator) {
              return 
    false;
             }
             return new 
    task($iterator->next());
        }    
    }

    class 
    taskIterator {
       function 
    taskIterator($database_result) { }
       function &
    next() { }
    }

    class 
    task {
        var 
    $title '';
        var 
    $owningMember '';
        var 
    $owningDepartment '';
        
        function 
    task($row) {
          
    $connection = &$this->getConnection();
            
    $this->title $row['title'];
            
           
    $sql "select name from members where id='$row['member_id']'";
          
    $iterator = &new personIterator( &$connection->query($sql) );
             
    $this->owningMember = &new person($iterator->next());
        
           
    $sql "select name from departments where id='$row['department_id']'";
          
    $iterator = &new departmentIterator( &$connection->query($sql) );         
            
    $this->owningDepartment = &new department($iterator->next());
        }
        
       function 
    getOwningMember() { 
            return 
    $this->owningMember;
        }
        
       function &
    getOwningDepartment() { 
            return 
    $this->owningDepartment;
        }
    }

    class 
    departmentIterator {
       function 
    departmentIterator($database_result) { }
       function &
    next() { }
    }

    class 
    department {
       function 
    department($row) { }    
       function &
    getMembers() { }
    }

    class 
    personIterator {
       function 
    personIterator($database_result) { }
       function &
    next() { }
    }

    class 
    person {
       function 
    person($row) { }
       function 
    getName() { }
    }    
    ?>

  19. #69
    SitePoint Addict silent's Avatar
    Join Date
    Jun 2004
    Location
    Roaming North America
    Posts
    220
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DarkAngelBGE
    How does this look to you Marcus? Obviously I would need a ton of queries if I want to store the people of the owning departments of 20 tasks. That would crash every server...
    Hey guys, interesting stuff picking back up in this thread...

    I'd use the db to do the job it's intended to do: have JOINS do the logic of finding the owning member and department, then loop through the resultset in your findByProjectName() method, building your Task objects and populating their member variables accordingly.

    Cheers,

    jay

  20. #70
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So you would do this instead, Jay? :

    PHP Code:
    class taskFinder {
        function 
    taskFinder() {}
       function &
    findByProjectName($project_name) { }

       function &
    findByName($name) {
           
    $sql "select t.title, m.memId, d.id as deptId".
                    
    " m.name as memName, m.email as memMail".
                    
    " d.name as deptName".
                    
    " from tasks as t".
                    
    "    left join members as m on (t.mem_id = m.id)".
                    
    "    left join departments as d on (t.dept_id = d.id)".
                    
    "    where t.name='$name'";
          
    $connection = &$this->getConnection();
          
    $iterator = &$connection->query($sql);
          if (! 
    $iterator) {
              return 
    false;
             }
             return new 
    task($iterator->next());
        }    
    }

    class 
    taskIterator {
       function 
    taskIterator($database_result) { }
       function &
    next() { }
    }

    class 
    task {
        var 
    $title '';
        var 
    $owningMember '';
        var 
    $owningDepartment '';
        
        function 
    task($row) {
          
    $connection = &$this->getConnection();
            
    $this->title $row['title'];
            
             
    $this->owningMember = &new person($row['memName'], $row['memMail'], $row['memId']);     
            
    $this->owningDepartment = &new department($row['deptName'], $row['deptId']);
        }
        
       function 
    getOwningMember() { 
            return 
    $this->owningMember;
        }
        
       function &
    getOwningDepartment() { 
            return 
    $this->owningDepartment;
        }


  21. #71
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Going back to your previous posting, I was pondering on why you created an iterator just to pass over a single resultset ?

    PHP Code:
    ...
    $this->owningMember = &new person($row['memName'], $row['memMail'], $row['memId']);      
            
    $this->owningDepartment = &new department($row['deptName'], $row['deptId']); 
    ... 
    This is much better, even though in this case you have no need to pass over an actual resultset it's self

    Maybe you can explain your reasoning behind the iterators though ?

  22. #72
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I had no reasoning.

    What do you guys think how this looks now?

  23. #73
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well okay, ahving thought of it again ... what if I want to use the classes department and person without the task finder in some other context? Their constructors will always wait for the id/name/email/etc. parameters.

    So supplying a resultset would allow them classes to be used in other contextes, too, yes?

  24. #74
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I see In that case though, wouldn't a raw resultset be better, rather than an iterator ?

    That being the case, the class constructor going to use the resultset could implement the iterator it's self, in the event that the constructor has to filter the resultset ?

    Would an iterator cause hinderance ?

  25. #75
    SitePoint Wizard
    Join Date
    May 2003
    Location
    Berlin, Germany
    Posts
    1,829
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't think so. Could you support your code by a code sample, Widow?


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
  •