SitePoint Sponsor

User Tag List

Results 1 to 7 of 7

Thread: Class order

  1. #1
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,042
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)

    Class order

    /core/app/app_model.class.php
    Code:
    abstract class AppModel {
    }
    /core/models/dynamic/posts_model.class.php
    Code:
    abstract class PostsModel extends AppModel {
    }
    /app/models/articles_model.class.php
    Code:
    class ArticlesModel extends PostsModel {
    }
    The problem I am having is that I need to bring in articles_model.class.php before bringing in the class which it extends posts_model.class.php. Is there a way to do this without getting an error? I essentially would like to be able to bring in articles_model.class.php Than use get_parent_class() to check the parent. If the parent is not app_model than bring in the parent. In this case that parent would be posts_model.class.php. Any ideas?

  2. #2
    SitePoint Addict
    Join Date
    Aug 2007
    Posts
    365
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could try reflection class. Im not sure if it will allow you to do it though. Why are you trying to do it anyways.

  3. #3
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,042
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    I'm not very familiar with reflection but, I'll take a look.

    The bottom level class ArticlesModel is created via matching a a controller name. If a controller articles is passed than the the model ArticlesModel is created. This is fine if the class was a direct subclass of just AppModel becasue AppModel is brought in before initiation takes place. However, the PostsModel class belongs to a conceptual group of classes that adds additional functionality to a model. So these classes need to be brought in to be able to create the actual model object. In this case that model is ArticlesModel. However, I can't actually bring in file to figure out which class it extends without an error. My current solution involves just bringing in all the "dynamic model" classes. However, if there were a large number this would not be the optimal solution. I only want to bring in ones that are needed not all of them. A dynamic model which PostsModel relates conceptually to is a table in a database with a column called type. The type allows the ability to use the the same table for different sets of data that have a common interface. For example, all posts have common columns such as created,updated,title,content,etc. Therefore, via extending that class with another the subclass gains the interface but the type becomes the sub classes name. So essentially, if a user would like to add a news section they can extend the Posts interface. The interface is inhereited but since the type changes all columns with type = news are essentially a "different" table although the data is being stored in one posts. If that makes sense…

    Code:
    abstract class PostsModel extends AppModel {
    	
    	var $has = array(
    		'cols'=> array(
    			array('col'=>'id'),
    			array('col'=>'title'),
    			array('col'=>'subtitle'),
    			array('col'=>'message'),
    			array('col'=>'update'),
    			array('col'=>'created')
    		),
    		'where'=>array()
    	);
    	
    }
    Code:
    class ArticlesModel extends PostsModel {
    }
    Code:
    class NewsModel extends PostsModel {
    }
    Dynamically generated sql query from AppModel
    query: SELECT posts.`id`,posts.`title`,posts.`subtitle`,posts.`message`,posts.`update`,posts.`created` FROM posts WHERE posts.`type`='articles';

    query: SELECT posts.`id`,posts.`title`,posts.`subtitle`,posts.`message`,posts.`update`,posts.`created` FROM posts WHERE posts.`type`='news';

    The concept is essentially an interface. These two sets of data have the same columns(interface) so they share the same table in the database. Which makes it easy to add a new "data set" such a blogs, etc if it has the same column data as the posts table.

  4. #4
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,042
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    This is the current solution which I hate. Basically all the "dynamic models" are located in the same directory. Therefore, inside the index I just load them all in. However, like I mentioned before I this method consumes resources which I don't nesseccarily need. If a dynamic model isn't being used it will be loaded when really I rather it not be.

    Code:
    /*
     * bring in dynamic models. This must be done becasue it is impossible
     * to check a classes parent otherwise or bring in class file that extends
     * a class that doesn't exists
     */
     if(is_dir(CORE.DS.'models'.DS.'dynamic')) {
     	$dynamicModels = scandir(CORE.DS.'models'.DS.'dynamic');
     	foreach($dynamicModels as $file) {
     		if(stristr('.',$file) || stristr('..',$file) ) { continue; }
     		Loader::load(CORE.DS.'models'.DS.'dynamic'.DS.$file);
     	}
     }

  5. #5
    SitePoint Addict
    Join Date
    Aug 2007
    Posts
    365
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Im not sure if I understand your problem; you want to include dependencies right??

    If that is the case you could use __autoload() to include files for classes as needed,
    or
    you can have code inside your model types to include the dependencies which is required. That way it knows exactly what it is going to use!

  6. #6
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,042
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    autoload works great thanks

    Code:
    function __autoload($pClass) {
      	
    	$command = 'grep -lr "class '.$pClass.'" .';
    	$files = preg_split('/\n/',trim(shell_exec($command)));
    	if(count($files)==1) {
    		Loader::load(preg_replace('/^./',ROOT,$files[0]));
    	}
    }
    Still not the optimal solution but, I'll work.

  7. #7
    . shoooo... silver trophy logic_earth's Avatar
    Join Date
    Oct 2005
    Location
    CA
    Posts
    9,013
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    What exactly are you trying to do? You lost me from the very beginning...
    In any case Reflection will not work because the class or interface that is being extended or implemented must exists prior to its use (ie included.) Making use of autoload seems to be the optimal solution to your problem as far as I can see.
    Logic without the fatal effects.
    All code snippets are licensed under WTFPL.



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
  •