[Skip to main content](#vessel-content)

☰ Documentation

#  Create your own mass action plugin

Details    Written by: Eliot    Category: [HikaShop](/support/documentation/hikashop)     Published: 01 July 2013     Hits: 19790

![mass action](/images/icon_doc/icon_massaction_180.png)The mass action system included in HikaShop lets a developer add the filters and the actions a shop needs, and even the data a mass action can work on. This page gives the basis of such a plugin: a filter, an action, and a table of your own. Each of them is written once, as a class, and HikaShop takes care of the rest: the edit form, the counter of the filters, the triggers, the scheduler, the HTTP endpoints and the MCP tool all use the same class.

Start by creating a HikaShop plugin as explained in this [tutorial](/fr/support/documentation/62-hikashop-developer-documentation.html#howto), then add the functions below to it. The mass action plugins which come with HikaShop, and the classes under *administrator/components/com\_hikashop/helpers/massaction*, are complete examples of everything described here.

### A filter

A filter is a class registered under the name a saved mass action stores. The following one keeps the products which have no image. *apply()* is called in two situations: with no elements, when the mass action runs from a query (the Process button, the scheduler, an HTTP endpoint), where it adds a condition to the query; and with elements, when a trigger such as the creation of a product hands them over, where it removes the ones which do not match.

```
<span style="color: green;">// Register the filter</span>
function onMassactionTypeLoad(&$types) {
	if(!class_exists('hikashopMassactionFilterBaseHelper'))
		include_once(rtrim(HIKASHOP_HELPER, DS).DS.'massaction'.DS.'filter'.DS.'base.php');
	include_once(__DIR__.DS.'noimage.php');
	$types['productNoImage'] = new plgHikashopMyMassactionNoImage();
}
```

```
<span style="color: green;">// noimage.php</span>
class plgHikashopMyMassactionNoImage extends hikashopMassactionFilterBaseHelper {
	<span style="color: green;">// Only offered on the tables naming it in their "types"</span>
	public function universal() { return false; }

	public function label($origin, $name) { return 'Products without an image'; }

	public function apply($origin, &$elements, &$query, $filter, $num) {
		$db = \Joomla\CMS\Factory::getDBO();
		$images = 'SELECT file_ref_id FROM '.hikashop_table('file').' WHERE file_type = '.$db->quote('product');
		if(count($elements)) {
			$db->setQuery($images);
			$withImage = $db->loadColumn();
			foreach($elements as $k => $element) {
				if(in_array($element->product_id, $withImage))
					unset($elements[$k]);
			}
			return;
		}
		$query->where[] = 'hk_product.product_id NOT IN ('.$images.')';
	}

	<span style="color: green;">// What the edit form says next to the filter</span>
	public function count($origin, &$query, $filter, $num) {
		$elements = array();
		$this->apply($origin, $elements, $query, $filter, $num);
		return $this->countElements($origin, $query);
	}
}
```

A filter which is not *universal* is offered by the tables naming it. To offer this one on the products, add it to the *types* of the product table. Do it in *onMassactionRelationLoad*, which is triggered once every table has been declared, whatever the order the plugins run in:

```
function onMassactionRelationLoad(&$links, $tables) {
	if(isset($tables['product']))
		$tables['product']->types['productNoImage'] = 'productNoImage';
}
```

A filter which needs settings in the edit form also gives *defaults()*, the settings of a new filter, and *getHtml()*, the fields displayed once it is selected, named *filter\[table\]\[key\]\[name\]\[setting\]*. What the merchant entered comes back in *$filter*.

### An action

An action is registered the same way, through *onMassactionActionLoad*, and runs in *act()* on the elements the filters kept. It can return a sentence for the report of the mass action.

```
function onMassactionActionLoad(&$actions) {
	if(!class_exists('hikashopMassactionActionBaseHelper'))
		include_once(rtrim(HIKASHOP_HELPER, DS).DS.'massaction'.DS.'action'.DS.'base.php');
	include_once(__DIR__.DS.'publish.php');
	$actions['publishProducts'] = new plgHikashopMyMassactionPublish();
}
```

```
<span style="color: green;">// publish.php</span>
class plgHikashopMyMassactionPublish extends hikashopMassactionActionBaseHelper {
	public function universal() { return false; }

	public function label($origin, $name) { return 'Publish the products'; }

	public function act($origin, &$elements, $action, $k) {
		$productClass = hikashop_get('class.product');
		foreach($elements as $element) {
			$product = new stdClass();
			$product->product_id = (int)$element->product_id;
			$product->product_published = 1;
			$productClass->save($product);
		}
		return count($elements).' products published';
	}
}
```

As for a filter, an action which is not *universal* is offered by the tables naming it, in their *actions*: *$tables\['product'\]-&gt;actions\[\] = 'publishProducts';* in the same *onMassactionRelationLoad*.

### A table of your own

To run mass actions on data of your own, for example the discounts, declare the table. *component* tells HikaShop where the table lives (*\#\_\_hikashop\_discount* here) and *id* its key. *filters* offers a filter on the columns of the table, which HikaShop runs itself when it says *apply*.

```
function onMassactionTableLoad(&$tables) {
	$obj = new stdClass();
	$obj->table = 'discount';
	$obj->value = 'discount';
	$obj->text = \Joomla\CMS\Language\Text::_('DISCOUNT');
	$obj->component = 'hikashop';
	$obj->id = 'discount_id';
	$obj->date_columns = array('discount_start', 'discount_end');
	$obj->filters = array(
		'discountColumn' => array('label' => 'DISCOUNT', 'table' => 'discount', 'apply' => 'column'),
	);
	<span style="color: green;">// Offer the import from a CSV file, finding a discount by its code</span>
	$obj->types = array('csvImport' => 'csvImport');
	$obj->import = array('key' => 'discount_code');
	$tables[] = $obj;
}
```

With *import*, the "Import from a CSV file" filter is offered too: a file whose first line names columns of the table, one of them the key, selects the rows it names, and with "Save" writes its columns to them. The actions every table has, such as updating a column, deleting the elements, sending an email or exporting them, are then offered on it. The developer documentation lists the other keys a table can carry, the links to the tables it reaches, and the events a filter or an action nobody registered is still sent to.

[](#top)
