Is there any event like onafterConfirmorder in virtuemart ?
like in joomla onAfterRender,onBeforeRender events.
i want to execute code after order has been confirm .
Maybe the path is different in Joomla 2 or 3?
In Joomla 1.5 there is no path like:
ROOT_PATH\folder_name\administrator\components\com_virtuemart\models\order.php
Only the following path exists:
ROOT_PATH\folder_name\administrator\components\com_virtuemart\classes\ps_order.php
Better you have to create a plugin for this concept.
First you need to find the ORDER section in Virtumart. The following model file contains all the order functionality.
ROOT_PATH\folder_name\administrator\components\com_virtuemart\models\order.php
In this file you have to find where the order has been completed. In that section once the order was completed you have to trigger this plugin process your functionality.
You can call any event of plugin which is defined in that plugin.
$dispatcher = JDispatcher::getInstance();
$data = array($argu1, $argu2); // any number of arguments you want
return $dispatcher->trigger(onAfterRender, $data);
Then it will trigger the onAfterRender event in plugin which you created.
<?php
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
jimport( 'joomla.plugin.plugin' );
/**
* Example system plugin
*/
class plgSystemExample extends JPlugin
{
/**
* Constructor.
*
* #access protected
* #param object $subject The object to observe
* #param array $config An array that holds the plugin configuration
* #since 1.0
*/
public function __construct( &$subject, $config )
{
parent::__construct( $subject, $config );
// Do some extra initialisation in this constructor if required
}
/**
* Do something onAfterRender
*/
function onAfterRender()
{
}
}
Like this you have to create your plugin..
All the best....
Related
In Laravel documentation routing there is a namespace method.
Route::namespace
I tried to explore what does it really do but couldn't find it's definition in Laravel source codes. Where is it?
It's not related to code, just to group the routes. Like this:
The source is here: https://github.com/laravel/framework/blob/b73691ac7b309cd2c4fb29b32d3eed76fecca58b/src/Illuminate/Routing/RouteGroup.php#L40, it just adds the namespace at end of the current namespace.
You have a controller group like 'Products' for example,
App/
Http/
Controllers/
Products/
Stocks.php
Prices.php
Sizes.php
And you need to modify their namespaces like this to meet the PSR-4 requirements to enable autoloading of controllers:
namespace App\Http\Controllers\Products;
class Stocks {
function index(){
}
}
Then if you want to access the methods of these controllers, you might want to group them with Route::namespace():
Route::namespace("Products")->group(function(){
Route::get("stocks", "Stocks#index");
});
This will search for the Stocks class in the App\Http\Controllers\Products namespace instead of App\Http\Controllers namespace. and call the index method.
Note that you might run composer dumpautoload to let the framework rebuild the autoload.php with the PSR-4 namespaces to make these things effective.
Later Edit:
framework/src/Illuminate/Routing/Router.php defines the Route class, which redirects the Route::namespace method to RouterRegistrar class at this line:
/**
* Dynamically handle calls into the router instance.
*
* #param string $method
* #param array $parameters
* #return mixed
*/
public function __call($method, $parameters)
{
if (static::hasMacro($method)) {
return $this->macroCall($method, $parameters);
}
if ($method == 'middleware') {
return (new RouteRegistrar($this))->attribute($method, is_array($parameters[0]) ? $parameters[0] : $parameters);
}
return (new RouteRegistrar($this))->attribute($method, $parameters[0]);
}
in the last line. And in that method,
/**
* The attributes that can be set through this class.
*
* #var array
*/
protected $allowedAttributes = [
'as', 'domain', 'middleware', 'name', 'namespace', 'prefix',
];
/**
* Set the value for a given attribute.
*
* #param string $key
* #param mixed $value
* #return $this
*
* #throws \InvalidArgumentException
*/
public function attribute($key, $value)
{
if (! in_array($key, $this->allowedAttributes)) {
throw new InvalidArgumentException("Attribute [{$key}] does not exist.");
}
$this->attributes[Arr::get($this->aliases, $key, $key)] = $value;
return $this;
}
namespace attribute is being set, to use in ->group() method.
I want to write a observer for before and after methods using plugin in magento 2.
The plugin class has to be declared in etc/di.xml of your module. Here is the code:
app/code/YourCompany/YourModule/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Checkout\Model\Cart">
<plugin name="pluginAddProductToCart" type="YourCompany\YourModule\Plugin\CartPlugin" sortOrder="10" disabled="false"/>
</type>
</config>
Here,
type’s name = class whose methods are to be observed
plugin’s name = random plugin name
plugin’s type = name of plugin’s class (YourCompany\YourModule\Plugin\Plugin)
plugin’s sortOrder = the order of the plugin to be called
plugin’s disabled = enable/disable plugin, default value is false.
We can add before, after, and around methods to modify the core class functions. For example, if there is a “Save” function in the core class then in the plugin class we can have beforeSave, afterSave and aroundSave method.
beforeMethod = contains code to run before the observed Method
afterMethod = contains code to run after the observed Method
aroundMethod = contains code to run both before and after the observed Method
“observed method” means the function present in the Core class which we want to modify through our Plugin class
In the above di.xml file, we have defined that we are going to observe methods of class Magento\Checkout\Model\Cart in our plugin class YourCompany\YourModule\Plugin\CartPlugin.
In this example, we will be observing a function named addProduct of the core Cart class.
For this example,
If you want to run some code before the addProduct method (adding product to cart), then you will have to create a method named beforeAddProduct in your Plugin class.
Similarly, if you want to do something after adding product to cart, then you will have to create a new function named afterAddProduct in your Plugin class.
And, there is another method named ‘around’. This allows you to execute some code both before and after the observed method is called. For this, you will have to add a new function named aroundAddProduct in your Plugin class.
Here is the CartPlugin class.
app/code/YourCompany/YourModule/Plugin/CartPlugin.php
<?php
namespace YourCompany\YourModule\Plugin\CartPlugin;
use Magento\Framework\Exception\LocalizedException;
class CartPlugin
{
/**
* #var \Magento\Quote\Model\Quote
*/
protected $quote;
protected $request;
/**
* Plugin constructor.
*
* #param \Magento\Checkout\Model\Session $checkoutSession
*/
public function __construct(
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Framework\App\Request\Http $request
) {
$this->quote = $checkoutSession->getQuote();
$this->request = $request;
}
/**
* beforeAddProduct
*
* #param $subject
* #param $productInfo
* #param null $requestInfo
*
* #return array
* #throws LocalizedException
*/
public function beforeAddProduct($subject, $productInfo, $requestInfo = null)
{
$productId = (int)$this->request->getParam('product', 0);
$qty = (int)$this->request->getParam('qty', 1);
// do something
// your code goes here
if ( something wrong ) {
throw new LocalizedException(__('Your error message'));
}
return [$productInfo, $requestInfo];
}
/**
* afterAddProduct
*
* #param $subject
* #param $result Returned value from core observed method 'addProduct'
*/
public function afterAddProduct($subject, $result)
{
$quote = $result->getQuote();
// do something
// your code goes here
}
public function aroundAddProduct($subject, $proceed)
{
// do something
// before adding product to cart
// your code goes here
$productId = (int)$this->request->getParam('product', 0);
$qty = (int)$this->request->getParam('qty', 1);
// this will run the core addProduct function
$returnValue = $proceed();
// below code is executed after product is added to cart
if ($returnValue) {
// do something
// after adding product to cart
// your code goes here
}
return $returnValue;
}
}
?>
Can't seem to get validation groups working. It works for the default group, however I cant seem to figure out how to specify different validation groups in the following:
$errors = $validator->validate($entity);
I've a simple entity I'm testing with:
/**
* Class Login
* #package AppBundle\Entity
*/
class Login
{
/**
* #Assert\NotBlank(
* message="not.blank",
* groups={"Default", "login"}
* )
*
* #Assert\Email(
* message="email",
* groups={"Default", "login"}
* )
*/
public $email;
/**
* #Assert\NotBlank(
* message="not.blank",
* groups={"Default", "login"}
* )
*/
public $password;
}
If I add a parameter like this it complains:
$errors = $validator->validate($entity, 'login');
But there's got to be a way to do this, right?
Actually, the correct way of using Symfony3 validation groups is to list them as an array:
$errors = $validator->validate($entity, null, ['login']);
Btw, depending on your use case you might not need to set Default group for each property and use just group Login instead of login. Then when you validate the entity with group Default it'll automatically include assertions with group name equal to the class name which is Login in your case. For more details see: http://symfony.com/doc/current/validation/groups.html
After digging into the Symfony code I found the following:
File:
/vendor/symfony/symfony/src/Symfony/Component/Validator/Validator/ValidatorInterface.php
Line:
public function validate($value, $constraints = null, $groups = null);
So if I change this:
$errors = $validator->validate($entity, 'login');
To this:
$errors = $validator->validate($entity, null, 'login');
It works!
I'm having a problem. What I'm trying to do is create basic package for geolocation. I'm using workbench to create the package and there is only one source and one config file. Plus the API that I'm using. Here's my GeoLocation class
<?php namespace EvansEric\GeoLocate;
require('ip2locationlite.class.php');
class GeoLocate{
public function gip()
{
echo 'test';
}
public function gCountry()
{
echo 'test';
}
}
And here's my config file
<?php
return array(
/**
*
* # Set the API Key obtained from ipinfodb.com
*/
'key' => '',
/**
*
* # Set Refresh rate. Set to 0 by default
*/
'refresh' => 0,
/**
*
* # Set default location
*/
'default_location' => '216.110.94.228',
);
I have my package register in the app config on the main application. EvansEric\GeoLocate
But I can't use it in my application. Keeps saying it can't find class. But I'm looking at the class and I know it's there. Please help.
I'm new to codeigniter and building web applications using MVC. I'm trying to wrap my head around how I would implement widgets in a modular fashion in my application. My question is more theoretical at this point. I don't have actual code to show.
What I want to know is this, how would I construct a data-driven widget in such a way that I can simply drop it on to any page that I want. For example, let's say I have a widget called Widget. I've created a model file called /models/widget_model.php. I then have a controller file called /controllers/widget.php. Obviously my controller will use the model to grab necessary data from my database. What I don't understand is how to use this as a widget dropped onto multiple views. What I'm seeing and understand so far is how to use a controller to drive a specific view. So it's basically like one controller is used per page. What would be the process of using this widget in a modular fashion I guess?
What you search for is HMVC. There are two common library/packages you can use : Modular CI or HMVC. With that, you can actually put something like <?php echo Modules::run('module/controller/method', $param, $...); ?> as a widget, in your view files.
You can do it via drivers. Send the controller as an object reference to the driver to use view class. Then you just load drivers and use them as plugins.
Edit:
Here is the code I use in my application:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* CodeIgniter base widget driver
*
* #author Alex
* #version 1.0.0
*/
class Basedriver {
/**
* Current specified controller.
* #var CI_Controller
*/
public $controller;
/**
* Contents of the driver which should be outputted or returned.
* #var string
*/
protected $contents;
/**
* Loader Class
* #var CI_Loader
*/
protected $load;
/**
* Constructor function for Basedriver class
*/
public function __construct()
{
$this->controller =& get_instance();
$this->load = $this->controller->load;
}
/**
* Renders driver data into specified output. If $echo_contents is true,
* output is echoed to the client, otherwise it is returned.
* #param boolean $echo_contents Specifies whether the content should be outputted or returned as string
* #param mixed $params Array of parameters which should be sent to the driver
* #return string Returned driver data if $echo_contents is set
*/
public function render($params = NULL, $echo_contents = true)
{
$this->parse_params($params);
$this->run();
if ($echo_contents)
echo $this->contents;
else
return $this->contents;
return NULL;
}
/**
* Default run function for all drivers, should be overidden by extending classes.
*/
protected function run()
{
$this->contents = NULL;
}
/**
* Parses parameters and sets them as variables.
* Default variables need to be defined in extending class
*/
protected function parse_params($params)
{
if ($params === NULL) return;
foreach($params as $variable => $value)
{
if (isset($this->$variable))
$this->$variable = $value;
}
}
}
/* End of file Basedriver.php */
/* Location: ./application/libraries/Basedriver.php */
Load class is there to allow you to use view class and controller is there to allow you to use database functions and to give you some other access if you need it. This class needs to be loaded before all other drivers (widgets) and all drivers (widgets) need to extend this class. You can do this by adding 'basedriver' in $config['libraries'] array in application/config/autoload.php.
Example Driver Widget:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Example extends Basedriver
{
protected $parameter1 = 'defaultvalueparam1';
protected $parameter2 = 'defaultvalueparam2';
protected function run()
{
// Widget logic here...
// you can use $this->load->view and $this->controller->db here
$this->contents = 'final_processed_data_here';
}
}
/* End of file Example.php */
/* Location: ./application/libraries/Example/Example.php */
To use the driver which extends Basedriver as a widget, example:
$this->load->driver('example');
$this->example->render(array('parameter1' => '1', 'parameter2' => '2'));
I think you could simply using CI's view system. You create a view per widget, then you inject any variable you want from your model, and finally you display the resulting HTML anywhere you want. I can't think of any particular difficulty.