Welcome Guest, Not a member yet? Register   Sign In
Calling Method in Child Class - Is It Possible?
#1

[eluser]Nalorin[/eluser]
I have multiple controllers on my site (one for each section of my site), and a contact form is loaded within views loaded by three of my controllers.

What I want to do is have one method for validating all of the contact forms, so I'd like to have a contact_user method in MY_Controller that will either:
A) Redirect to example.com/page/posting_detail/post_id upon successful completion, to prevent resubmission on refresh
B) Load example.com/page/posting_detail/post_id, without redirect, upon failure and echo validation_errors()

The closest solution that I can think of to accomplish this is:

in application/controllers/page.php:
Code:
function contact_user($post_id)
{
  if (parent::contact_user($post_id))
    redirect('page/posting_detail/'.$post_id);

  else
    $this->posting_detail($post_id);
}

/* or */

function posting_detail($post_id = 0)
{
  if ($post_id && $this->contact_user($post_id))
    redirect('page/posting_detail/'.$post_id);

  else
  {
    /*
     * Do stuff to get ready to load view for posting_detail
     */
    $this->load->view('detail',$posting_details);
  }
}

But this would lead to duplicate code being placed in each of my controllers that contains a page with the contact form in it.

Instead, I'd like to have in libraries/MY_Controller.php:
Code:
function contact_user($post_id)
{
  /*
   * Do form validation
   */
  if ($this->form_validation->run() === FALSE)
  {
    // load the detail page of the currently loaded controller where
    // "child" would be the controller referenced by $this->uri->segment(1)
    child::posting_detail($post_id);
    // I know when MY_Controller is instantiated, there is no such thing as a "child" b/c
    // the derived class has not been instantiated yet. However, by the time this function
    // (contact_user) is run, the derived class will have been instantiated.
    // I want to know if there's some way to call a method from the derived class at call
    // time (i.e. not at time of instantiation)
  }

  else
    redirect($this->uri->segment(1).'/posting_detail/'.$post_id);
}

Is there a way to do what I'm trying to do, without having to duplicate code in each controller (like would happen in either the first two examples?
#2

[eluser]trumpetnl[/eluser]
im using the fast reply here so dont shoot me.... :-)

if i make a mental pic of the structure of your app, it would be appearent you have a 'nesting' problem. The cleanest solution i can think of on short notice (it is afterall the 'fast reply button') is to create a class on the same level as your controllers. So yes, a 'MY_' class. This will also help with the reuseability of this component.

my 5 cents
//Rik
#3

[eluser]danmontgomery[/eluser]
There's no reason to call parent::contact_user() here. I'm not real clear on the goal but you don't really seem to have a grasp on object inheritance. I'd read up on http://www.php.net/manual/en/language.oo...itance.php.

You can't call child classes because the parent has no idea if any children exist or what they are, let alone which specific child is calling that method. Regardless, the method is inherited by the child class, so as I said, there's absolutely no reason to call the parent's.
#4

[eluser]Nalorin[/eluser]
[quote author="noctrum" date="1284600775"]There's no reason to call parent::contact_user() here. I'm not real clear on the goal but you don't really seem to have a grasp on object inheritance.[/quote]
I actually have a decently good grasp of inheritance, TYVM; I made a mistake in my code (a friend called me for an emergency, so I didn't have as much time to go over it).

I respect your input and thank you for your help, noctrum, and would appreciate if you would do the same by not jumping to conclusions about other peoples' knowledge. If you're "not real clear on the goal," that's an indication of a need for clarification, not chastisement.

[quote author="noctrum" date="1284600775"]You can't call child classes because the parent has no idea if any children exist or what they are, let alone which specific child is calling that method. Regardless, the method is inherited by the child class, so as I said, there's absolutely no reason to call the parent's.[/quote]
I've updated my code above, please review it and it then might make more sense as to what I'm trying to do.

-------

In case it's still unclear, here's a very stripped down version that gives a better "big picture" view of what I want:

Assuming my controllers are named "sell,buy" (and therefore accessible by example.com/sell or example.com/buy):

libraries/MY_Controller.php:
Code:
class MY_Controller extends Controller
{
  function contact_user($post_id)
  {
    // do form_validation on $this->input->post()
    if ($this->form_validation->run() === FALSE)
    {
      // this is the part I don't know how to do - or if it's possible:
      // somehow get the child that invoked contact_user by grabbing controller from URL
      // since that will tell us the current child that has inherited this function
      $child = get_or_load_derived_class($this->uri->segment(1));

      // rerun posting_detail method so validation errors can be displayed
      $child->posting_detail($post_id);
    }
    else
    {
      /*
       * do stuff to send out email, store the results of attempt in $success
       */
      if ($success === FALSE)
      {
        redirect($this->uri->segment(1).'/posting_detail/'.$post_id);
      }
      else
      {
        die(/*output email error*/);
      }
    }
  }
}

controllers/sell.php:
Code:
class Sell extends MY_Controller
{
  function posting_detail($post_id)
  {
    // do stuff specific to showing a Sell item
  }
}

controllers/buy.php:
Code:
class Buy extends MY_Controller
{
  function posting_detail($post_id)
  {
    // do stuff specific to showing a Buy item
    // this method is different enough from Sell::posting_detail that it does not
    // warrant creating a MY_Controller::posting_detail() function
  }
}

So the contact form for an item for sale, number 47, would be POSTed to '/sell/contact_user/47'
#5

[eluser]Nalorin[/eluser]
So I discovered that the solution lies in the fact that PHP does not require the implementation of a method called from another method, unless that other method is first called.

To illustrate:
Code:
class MY_Controller extends Controller
{
  function contact_user($id)
  {
    // do stuff
    if ($this->form_validation->run() === FALSE)
      $this->ad($id);
  }
}

class Sell extends MY_Controller
{
  function ad($id)
  {
    // display ad view, with contact form. View will call <?php echo validation_errors(); ?>
  }
}

With the above code, unless the contact_user method is specifically invoked, PHP could care less about whether or not ad($id) is defined.

I'm so used to OOP in C++, where it's picky about /every/ function call, etc.




Theme © iAndrew 2016 - Forum software by © MyBB