News:

You may pay someone to create your store, or you visit our seminar and become a professional yourself with the silver certification

Main Menu

MVC like structure in extended plugins?

Started by taenny, January 07, 2015, 22:54:13 PM

Previous topic - Next topic

taenny

Hi,

I would like to implement a form similar to the task askquestion but with more information being sent. This form should be used as "request offer for shipping" and send an email with information about the current product and (if registered) information about the address of the user.
To achieve this I think a simple template override for the view "askquestion" is not sufficient since I would need to draw additional information from the model (address).. but please correct me, if my assumption is wrong!

Therefore I have tried to build an extended plugin according to the wiki using the hook onVmSiteController to create a custom virtuemart view called requestoffer.
If I override the display method in my requestoffer controller (derived from JController) I can actually see the output when entering the URL [mydomain.com]/index.php?option=com_virtuemart&view=requestoffer.
My question is: Can I build an MVC like structure with my own views/language/.. folders in the plugin - like a tiny component, or is this simply not meant to be used like that?
If I call the default view in my custom controller with parent::display($cachable); I get the view not found error (500) although I have created a corresponding view according to the usual MVC logic.

Any hints would be greatly appreciated!

=====
BTW: In the wiki http://dev.virtuemart.net/projects/virtuemart/wiki/Extension_Plugins I noticed
$this->_path = JPATH_PLUGINS.DS.$this->getName();.
Since extended plugins get installed in the 'vmextended' directory, I think this should be
$this->_path = JPATH_PLUGINS.DS."vmextended".DS.$this->getName();
=====

Cheers, Daniel

Extended Plugin in [path_to_plugin]/requestoffer.php

  public function onVmSiteController ($controller)
  {
   
    if ($controller = 'Requestoffer') {
      vmdebug("Controller onVmSiteController fired");
      if (!class_exists('VirtuemartControllerRequestoffer')) require($this->_path.DS.'controllers'.DS.'requestoffer.php');     
      return true;
    }
    return null;
  }


Controller requestoffer in [path_to_plugin]/controllers/requestoffer.php

class VirtuemartControllerRequestoffer extends JController
{

  public function __construct()
  {
    parent::__construct();
  }

function display($cachable = false) {
//call parent method
echo ("<h1>SUCCESS!</h1>");
}
}


View requestoffer in [path_to_plugin]/views/requestoffer/view.html.php

class VirtuemartViewRequestoffer extends JView {

function display ($tpl = NULL) {
echo("<h1>View</h1>");
parent::display ($tpl);
}
}

Vm Version: 2.6.12.2
Joomla: 2.5.27
Php: 5.5
MySQL: 5.5

reinhold

Quite a coincidence: Just yesterday I had exactly the same issues with a custom admin view that I'm writing. You can easily provide a whole MVC structure in an vmextended plugin. All you have to do is to add the proper pathes in the controller and the view. Here's the code that I'm using in my plugin, which adds a view to the admin section:


class plgVmExtendedEu_Recap extends vmExtendedPlugin {

public function __construct (&$subject, $config=array()) {
parent::__construct($subject, $config);
$this->_path = JPATH_PLUGINS.DS.'vmextended'.DS.$this->getName();
JPlugin::loadLanguage('plg_vmextended_'.$this->getName());
}

public function onVmAdminController ($controller) {
if ($controller = 'eu_recap') {
// TODO: Make sure the model exists. We probably should find a better way to load this automatically!
//       Currently, some path config seems missing, so the model is not found by default.
require_once($this->_path.DS.'models'.DS.'eu_recap.php');
require_once($this->_path.DS.'controllers'.DS.'eu_recap.php');
return true;
}
}
}



class VirtuemartControllerEu_recap extends VmController {
function __construct(){
parent::__construct();
// Add the proper view pathes...
$this->addViewPath(JPATH_PLUGINS.DS . 'vmextended' . DS . 'eu_recap' . DS . 'views');
$this->addPath('models', JPATH_PLUGINS.DS . 'vmextended' . DS . 'eu_recap' . DS . 'models');
}
...



class VirtuemartViewEu_recap extends VmViewAdmin {
function __construct(){
parent::__construct();
// Add the proper view pathes...
$this->_addPath('template', JPATH_PLUGINS.DS . 'vmextended' . DS . 'eu_recap' . DS . 'views' . DS . $this->getName() . DS  . 'tmpl');
}

...
}


With these calls, everything works just fine in the backend. I have my controller in plugins/vmextended/eu_recap/controllers/, the model in plugins/vmextended/eu_recap/models/, the view (view.html.php and tmpl/default.php) in plugins/vmextended/eu_recap/views/eu_recap/ and the plugin itself in plugins/vmextended/eu_recap/eu_recap.php.

The only thing I'm not happy about is the explicit loading of the model php file. While VM appeared to find the model if called through the normal controller / router, I had some code path (can't remember the details, though) where it would not automagically find/load the correct file for the model, so I had to explicitly load it as a workaround.

While I can say for sure that this setup works for admin controllers, I have no experience with vmextended plugins that adds views to the frontend. However, I see absolutely no reason why it should not work.

Best regards,
Reinhold

reinhold

#2
PS: I should probably mention that I don't think you need a vmextended plugin with your own customized view to access the user in the template override...

The template override is just a normal php file, where you have access to the full spectrum of VirtueMart. In particular, you can simply call the user model:

$userModel = VmModel::getModel('user');
$user = $userModel->getCurrentUser();
// Let's just print out the whole user object to see what is actually available:
echo "<pre>";
print_r($user);
echo "</pre>";

taenny

Thank your very much for the quick response, Reinhold!
I will give it another try then - probably some naming convention issue on my part...

Also thanks for the tip about drawing information from the VM models in a template override. This shortcut is surely an approach that requires much less effort...
Vm Version: 2.6.12.2
Joomla: 2.5.27
Php: 5.5
MySQL: 5.5

taenny

I just wanted to report back, that I managed to get it to work with your help. Manually adding the paths ($this->__addPath([...]); ) helped and there were some minor naming convention errors on my part too - so thanks again!

You were also right about drawing additional userinfo in a template override. Nevertheless - this is only half of what I am trying to achieve. Userdata should also be sent via email. I can append information about the address in the form but the view doesn't process and renders it. So unless I miss something obvious (again) I suppose that there is no way around copying and adapting the view via an extended plugin...

Best regards, Daniel
Vm Version: 2.6.12.2
Joomla: 2.5.27
Php: 5.5
MySQL: 5.5